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
+13 -1
View File
@@ -28,7 +28,8 @@ module.exports = function(grunt) {
grunt.registerTask("execSpecsInNode", grunt.registerTask("execSpecsInNode",
"Run Jasmine core specs in Node.js", "Run Jasmine core specs in Node.js",
function() { function() {
var done = this.async(), verifyNoGlobals(() => require('./lib/jasmine-core.js').noGlobals());
const done = this.async(),
Jasmine = require('jasmine'), Jasmine = require('jasmine'),
jasmineCore = require('./lib/jasmine-core.js'), jasmineCore = require('./lib/jasmine-core.js'),
jasmine = new Jasmine({jasmineCore: jasmineCore}); 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(', '));
}
}
+37 -1
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'); 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'), var path = require('path'),
fs = require('fs'); fs = require('fs');
+2
View File
@@ -3482,6 +3482,8 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
} }
CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(lastRanFnIx) { CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(lastRanFnIx) {
let i;
for ( for (
i = lastRanFnIx + 1; i = lastRanFnIx + 1;
i < this.queueableFns_.length && this.shouldSkip_(i); i < this.queueableFns_.length && this.shouldSkip_(i);
+1
View File
@@ -82,6 +82,7 @@
"args": "none" "args": "none"
} }
], ],
"no-implicit-globals": "error",
"block-spacing": "error", "block-spacing": "error",
"func-call-spacing": [ "func-call-spacing": [
"error", "error",
+1 -1
View File
@@ -99,7 +99,7 @@ describe('JsApiReporter', function() {
}); });
describe('#suiteResults', function() { describe('#suiteResults', function() {
var reporter, suiteResult1, suiteResult2; var reporter, suiteStarted1, suiteResult1, suiteResult2;
beforeEach(function() { beforeEach(function() {
reporter = new jasmineUnderTest.JsApiReporter({}); reporter = new jasmineUnderTest.JsApiReporter({});
suiteStarted1 = { suiteStarted1 = {
+12 -12
View File
@@ -471,20 +471,20 @@ describe('QueueRunner', function() {
}, 100); }, 100);
return p1; return p1;
} }
}; },
(queueableFn2 = { queueableFn2 = {
fn: function() { fn: function() {
fnCallback(); fnCallback();
setTimeout(function() { setTimeout(function() {
p2.resolveHandler(); p2.resolveHandler();
}, 100); }, 100);
return p2; return p2;
} }
}), },
(queueRunner = new jasmineUnderTest.QueueRunner({ queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1, queueableFn2], queueableFns: [queueableFn1, queueableFn2],
onComplete: onComplete onComplete: onComplete
})); });
queueRunner.execute(); queueRunner.execute();
expect(fnCallback).not.toHaveBeenCalled(); expect(fnCallback).not.toHaveBeenCalled();
+2
View File
@@ -14,10 +14,12 @@ describe('Timer', function() {
describe('when date is stubbed, perhaps by other testing helpers', function() { describe('when date is stubbed, perhaps by other testing helpers', function() {
var origDate = Date; var origDate = Date;
beforeEach(function() { beforeEach(function() {
// eslint-disable-next-line no-implicit-globals
Date = jasmine.createSpy('date spy'); Date = jasmine.createSpy('date spy');
}); });
afterEach(function() { afterEach(function() {
// eslint-disable-next-line no-implicit-globals
Date = origDate; Date = origDate;
}); });
+11 -11
View File
@@ -513,20 +513,20 @@ describe('TreeProcessor', function() {
it('runs afterAlls for a node with children', function() { it('runs afterAlls for a node with children', function() {
var leaf = new Leaf(), var leaf = new Leaf(),
afterAllFns = [{ fn: 'afterAll1' }, { fn: 'afterAll2' }]; afterAllFns = [{ fn: 'afterAll1' }, { fn: 'afterAll2' }],
(node = new Node({ node = new Node({
children: [leaf], children: [leaf],
afterAllFns afterAllFns
})), }),
(root = new Node({ children: [node] })), root = new Node({ children: [node] }),
(queueRunner = jasmine.createSpy('queueRunner')), queueRunner = jasmine.createSpy('queueRunner'),
(processor = new jasmineUnderTest.TreeProcessor({ processor = new jasmineUnderTest.TreeProcessor({
tree: root, tree: root,
runnableIds: [node.id], runnableIds: [node.id],
queueRunnerFactory: queueRunner queueRunnerFactory: queueRunner
})), }),
(treeComplete = jasmine.createSpy('treeComplete')), treeComplete = jasmine.createSpy('treeComplete'),
(nodeDone = jasmine.createSpy('nodeDone')); nodeDone = jasmine.createSpy('nodeDone');
processor.execute(treeComplete); processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns; var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
+1 -1
View File
@@ -3427,7 +3427,7 @@ describe('Env integration', function() {
const spiedOnAllFuncs = { foo: function() {} }; const spiedOnAllFuncs = { foo: function() {} };
env.spyOnAllFunctions(spiedOnAllFuncs); env.spyOnAllFunctions(spiedOnAllFuncs);
for (spy of [ for (const spy of [
createSpySpy, createSpySpy,
spiedOn.foo, spiedOn.foo,
spyObj.foo, spyObj.foo,
+2 -2
View File
@@ -112,7 +112,7 @@ describe('DiffBuilder', function() {
return '[number:' + x + ']'; return '[number:' + x + ']';
} }
}; };
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]); const prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]);
var diffBuilder = new jasmineUnderTest.DiffBuilder({ var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter prettyPrinter: prettyPrinter
}); });
@@ -131,7 +131,7 @@ describe('DiffBuilder', function() {
return '[thing with a=' + x.a + ', b=' + JSON.stringify(x.b) + ']'; 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({ var diffBuilder = new jasmineUnderTest.DiffBuilder({
prettyPrinter: prettyPrinter prettyPrinter: prettyPrinter
}); });
+1 -1
View File
@@ -94,7 +94,7 @@ describe('matchersUtil', function() {
}); });
it('fails for Arrays that have different lengths', 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); expect(matchersUtil.equals([1, 2], [1, 2, 3])).toBe(false);
}); });
@@ -30,7 +30,7 @@ describe('toHaveBeenCalledBefore', function() {
secondSpy(); secondSpy();
result = matcher.compare(firstSpy, secondSpy); const result = matcher.compare(firstSpy, secondSpy);
expect(result.pass).toBe(false); expect(result.pass).toBe(false);
expect(result.message).toMatch( expect(result.message).toMatch(
/Expected spy first spy to have been called./ /Expected spy first spy to have been called./
@@ -44,7 +44,7 @@ describe('toHaveBeenCalledBefore', function() {
firstSpy(); firstSpy();
result = matcher.compare(firstSpy, secondSpy); const result = matcher.compare(firstSpy, secondSpy);
expect(result.pass).toBe(false); expect(result.pass).toBe(false);
expect(result.message).toMatch( expect(result.message).toMatch(
/Expected spy second spy to have been called./ /Expected spy second spy to have been called./
-4
View File
@@ -73,10 +73,6 @@ describe('HtmlReporter', function() {
describe('and no expectations ran', function() { describe('and no expectations ran', function() {
var container, reporter; var container, reporter;
beforeEach(function() { beforeEach(function() {
if (typeof console === 'undefined') {
console = { warn: function() {}, error: function() {} };
}
container = document.createElement('div'); container = document.createElement('div');
reporter = new jasmineUnderTest.HtmlReporter({ reporter = new jasmineUnderTest.HtmlReporter({
env: env, env: env,
+1 -1
View File
@@ -143,7 +143,7 @@ describe('npm package', function() {
j; j;
for (j = 0; j < dirents.length; j++) { for (j = 0; j < dirents.length; j++) {
dirent = dirents[j]; const dirent = dirents[j];
if (dirent.isDirectory()) { if (dirent.isDirectory()) {
getFiles(path.resolve(dir, dirent.name)); getFiles(path.resolve(dir, dirent.name));
@@ -5,6 +5,8 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
} }
CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(lastRanFnIx) { CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(lastRanFnIx) {
let i;
for ( for (
i = lastRanFnIx + 1; i = lastRanFnIx + 1;
i < this.queueableFns_.length && this.shouldSkip_(i); i < this.queueableFns_.length && this.shouldSkip_(i);