Allow use without creating globals

* Fixes #1235
This commit is contained in:
Steve Gravrock
2021-11-29 18:49:05 -08:00
parent 5942654856
commit 42e6c45efa
15 changed files with 88 additions and 37 deletions

View File

@@ -28,7 +28,8 @@ module.exports = function(grunt) {
grunt.registerTask("execSpecsInNode",
"Run Jasmine core specs in Node.js",
function() {
var done = this.async(),
verifyNoGlobals(() => require('./lib/jasmine-core.js').noGlobals());
const done = this.async(),
Jasmine = require('jasmine'),
jasmineCore = require('./lib/jasmine-core.js'),
jasmine = new Jasmine({jasmineCore: jasmineCore});
@@ -52,3 +53,14 @@ module.exports = function(grunt) {
}
);
};
function verifyNoGlobals(fn) {
const initialGlobals = Object.keys(global);
fn();
const extras = Object.keys(global).filter(k => !initialGlobals.includes(k));
if (extras.length !== 0) {
throw new Error('Globals were unexpectedly created: ' + extras.join(', '));
}
}

View File

@@ -1,6 +1,42 @@
module.exports = require("./jasmine-core/jasmine.js");
/**
* Note: Only available on Node.
* @module jasmine-core
*/
const jasmineRequire = require('./jasmine-core/jasmine.js');
module.exports = jasmineRequire;
/**
* Boots a copy of Jasmine and returns an object as described in {@link jasmine}.
* @type {function}
* @return {jasmine}
*/
module.exports.boot = require('./jasmine-core/node_boot.js');
/**
* Boots a copy of Jasmine and returns an object containing the properties
* that would normally be added to the global object. If noGlobals is called
* multiple times, the same object is returned every time.
*
* Do not call boot() if you also call noGlobals().
*
* @example
* const {describe, beforeEach, it, expect, jasmine} = require('jasmine-core').noGlobals();
*/
module.exports.noGlobals = (function() {
let jasmineInterface;
return function bootWithoutGlobals() {
if (!jasmineInterface) {
const jasmine = jasmineRequire.core(jasmineRequire);
const env = jasmine.getEnv({ suppressLoadErrors: true });
jasmineInterface = jasmineRequire.interface(jasmine, env);
}
return jasmineInterface;
};
}());
var path = require('path'),
fs = require('fs');

View File

@@ -3482,6 +3482,8 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
}
CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(lastRanFnIx) {
let i;
for (
i = lastRanFnIx + 1;
i < this.queueableFns_.length && this.shouldSkip_(i);

View File

@@ -82,6 +82,7 @@
"args": "none"
}
],
"no-implicit-globals": "error",
"block-spacing": "error",
"func-call-spacing": [
"error",

View File

@@ -99,7 +99,7 @@ describe('JsApiReporter', function() {
});
describe('#suiteResults', function() {
var reporter, suiteResult1, suiteResult2;
var reporter, suiteStarted1, suiteResult1, suiteResult2;
beforeEach(function() {
reporter = new jasmineUnderTest.JsApiReporter({});
suiteStarted1 = {

View File

@@ -471,20 +471,20 @@ describe('QueueRunner', function() {
}, 100);
return p1;
}
};
(queueableFn2 = {
fn: function() {
fnCallback();
setTimeout(function() {
p2.resolveHandler();
}, 100);
return p2;
}
}),
(queueRunner = new jasmineUnderTest.QueueRunner({
},
queueableFn2 = {
fn: function() {
fnCallback();
setTimeout(function() {
p2.resolveHandler();
}, 100);
return p2;
}
},
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2],
onComplete: onComplete
}));
});
queueRunner.execute();
expect(fnCallback).not.toHaveBeenCalled();

View File

@@ -14,10 +14,12 @@ describe('Timer', function() {
describe('when date is stubbed, perhaps by other testing helpers', function() {
var origDate = Date;
beforeEach(function() {
// eslint-disable-next-line no-implicit-globals
Date = jasmine.createSpy('date spy');
});
afterEach(function() {
// eslint-disable-next-line no-implicit-globals
Date = origDate;
});

View File

@@ -513,20 +513,20 @@ describe('TreeProcessor', function() {
it('runs afterAlls for a node with children', function() {
var leaf = new Leaf(),
afterAllFns = [{ fn: 'afterAll1' }, { fn: 'afterAll2' }];
(node = new Node({
children: [leaf],
afterAllFns
})),
(root = new Node({ children: [node] })),
(queueRunner = jasmine.createSpy('queueRunner')),
(processor = new jasmineUnderTest.TreeProcessor({
afterAllFns = [{ fn: 'afterAll1' }, { fn: 'afterAll2' }],
node = new Node({
children: [leaf],
afterAllFns
}),
root = new Node({ children: [node] }),
queueRunner = jasmine.createSpy('queueRunner'),
processor = new jasmineUnderTest.TreeProcessor({
tree: root,
runnableIds: [node.id],
queueRunnerFactory: queueRunner
})),
(treeComplete = jasmine.createSpy('treeComplete')),
(nodeDone = jasmine.createSpy('nodeDone'));
}),
treeComplete = jasmine.createSpy('treeComplete'),
nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;

View File

@@ -3427,7 +3427,7 @@ describe('Env integration', function() {
const spiedOnAllFuncs = { foo: function() {} };
env.spyOnAllFunctions(spiedOnAllFuncs);
for (spy of [
for (const spy of [
createSpySpy,
spiedOn.foo,
spyObj.foo,

View File

@@ -112,7 +112,7 @@ describe('DiffBuilder', function() {
return '[number:' + x + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});
@@ -131,7 +131,7 @@ describe('DiffBuilder', function() {
return '[thing with a=' + x.a + ', b=' + JSON.stringify(x.b) + ']';
}
};
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter
});

View File

@@ -94,7 +94,7 @@ describe('matchersUtil', function() {
});
it('fails for Arrays that have different lengths', function() {
matchersUtil = new jasmineUnderTest.MatchersUtil();
const matchersUtil = new jasmineUnderTest.MatchersUtil();
expect(matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
});

View File

@@ -30,7 +30,7 @@ describe('toHaveBeenCalledBefore', function() {
secondSpy();
result = matcher.compare(firstSpy, secondSpy);
const result = matcher.compare(firstSpy, secondSpy);
expect(result.pass).toBe(false);
expect(result.message).toMatch(
/Expected spy first spy to have been called./
@@ -44,7 +44,7 @@ describe('toHaveBeenCalledBefore', function() {
firstSpy();
result = matcher.compare(firstSpy, secondSpy);
const result = matcher.compare(firstSpy, secondSpy);
expect(result.pass).toBe(false);
expect(result.message).toMatch(
/Expected spy second spy to have been called./

View File

@@ -73,10 +73,6 @@ describe('HtmlReporter', function() {
describe('and no expectations ran', function() {
var container, reporter;
beforeEach(function() {
if (typeof console === 'undefined') {
console = { warn: function() {}, error: function() {} };
}
container = document.createElement('div');
reporter = new jasmineUnderTest.HtmlReporter({
env: env,

View File

@@ -143,7 +143,7 @@ describe('npm package', function() {
j;
for (j = 0; j < dirents.length; j++) {
dirent = dirents[j];
const dirent = dirents[j];
if (dirent.isDirectory()) {
getFiles(path.resolve(dir, dirent.name));

View File

@@ -5,6 +5,8 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
}
CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(lastRanFnIx) {
let i;
for (
i = lastRanFnIx + 1;
i < this.queueableFns_.length && this.shouldSkip_(i);