From 6badc04e5111324bd6b2e0aa0ce39a9a9c9f577e Mon Sep 17 00:00:00 2001 From: wtgtybhertgeghgtwtg Date: Thu, 16 Mar 2017 21:59:34 -0700 Subject: [PATCH] Reduce singleton (#3164) * [jest-jasmine2] Split `jasmine-light` over multiple files. * Don't wrap things that don't need to be wrapped. * Don't wrap things that don't need to be wrapped (again). * Lint. * [jest-jasmine2] Trim `jasmine` singleton. * Adding NHL to companies that use Jest (#3163) * Support custom platforms on jest-haste-map (#3162) * Support custom platforms on jest-haste-map * Run prettier * Rebase. --- packages/jest-jasmine2/src/jasmine/Env.js | 17 -- packages/jest-jasmine2/src/jasmine/Spec.js | 5 - .../jest-jasmine2/src/jasmine/SpyRegistry.js | 176 +++++++++--------- packages/jest-jasmine2/src/jasmine/Suite.js | 2 - .../jest-jasmine2/src/jasmine/createSpy.js | 78 ++++++++ .../src/jasmine/jasmine-light.js | 91 +-------- 6 files changed, 181 insertions(+), 188 deletions(-) create mode 100644 packages/jest-jasmine2/src/jasmine/createSpy.js diff --git a/packages/jest-jasmine2/src/jasmine/Env.js b/packages/jest-jasmine2/src/jasmine/Env.js index b522c523f7df..8f3e0fdc7e28 100644 --- a/packages/jest-jasmine2/src/jasmine/Env.js +++ b/packages/jest-jasmine2/src/jasmine/Env.js @@ -86,17 +86,6 @@ module.exports = function(j$) { return 'suite' + nextSuiteId++; }; - const expectationFactory = function(actual, spec) { - return j$.Expectation.Factory({ - actual, - addExpectationResult, - }); - - function addExpectationResult(passed, result) { - return spec.addExpectationResult(passed, result); - } - }; - const defaultResourcesForRunnable = function(id, parentRunnableId) { const resources = {spies: []}; @@ -209,10 +198,7 @@ module.exports = function(j$) { }; const topSuite = new j$.Suite({ - env: this, id: getNextSuiteId(), - description: 'test', - expectationFactory, expectationResultFactory, }); defaultResourcesForRunnable(topSuite.id); @@ -305,11 +291,9 @@ module.exports = function(j$) { const suiteFactory = function(description) { const suite = new j$.Suite({ - env: self, id: getNextSuiteId(), description, parentSuite: currentDeclarationSuite, - expectationFactory, expectationResultFactory, throwOnExpectationFailure, }); @@ -398,7 +382,6 @@ module.exports = function(j$) { const spec = new j$.Spec({ id: getNextSpecId(), beforeAndAfterFns: beforeAndAfterFns(suite), - expectationFactory, resultCallback: specResultCallback, getSpecName(spec) { return getSpecName(spec, suite); diff --git a/packages/jest-jasmine2/src/jasmine/Spec.js b/packages/jest-jasmine2/src/jasmine/Spec.js index c11e120ea8b7..c096b42449aa 100644 --- a/packages/jest-jasmine2/src/jasmine/Spec.js +++ b/packages/jest-jasmine2/src/jasmine/Spec.js @@ -36,7 +36,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. const ExpectationFailed = require('./ExpectationFailed'); function Spec(attrs) { - this.expectationFactory = attrs.expectationFactory; this.resultCallback = attrs.resultCallback || function() {}; this.id = attrs.id; this.description = attrs.description || ''; @@ -57,10 +56,6 @@ function Spec(attrs) { this.expectationResultFactory = attrs.expectationResultFactory || function() {}; this.queueRunnerFactory = attrs.queueRunnerFactory || function() {}; - this.catchingExceptions = attrs.catchingExceptions || - function() { - return true; - }; this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; if (!this.queueableFn.fn) { diff --git a/packages/jest-jasmine2/src/jasmine/SpyRegistry.js b/packages/jest-jasmine2/src/jasmine/SpyRegistry.js index 5dc4ae019011..9b0e725290bf 100644 --- a/packages/jest-jasmine2/src/jasmine/SpyRegistry.js +++ b/packages/jest-jasmine2/src/jasmine/SpyRegistry.js @@ -33,6 +33,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* eslint-disable sort-keys */ 'use strict'; +const CallTracker = require('./CallTracker'); +const createSpy = require('./createSpy'); +const SpyStrategy = require('./SpyStrategy'); + const formatErrorMsg = function() { function generateErrorMsg(domain, usage) { const usageDefinition = usage ? '\nUsage: ' + usage : ''; @@ -45,98 +49,104 @@ const formatErrorMsg = function() { return generateErrorMsg; }; -module.exports = function(j$) { - const getErrorMsg = formatErrorMsg( - '', - 'spyOn(, )', - ); - - function SpyRegistry(options) { - options = options || {}; - const currentSpies = options.currentSpies || - function() { - return []; - }; - - this.allowRespy = function(allow) { - this.respy = allow; - }; - - this.spyOn = function(obj, methodName) { - if (obj === void 0) { - throw new Error( - getErrorMsg( - 'could not find an object to spy upon for ' + methodName + '()', - ), - ); - } - - if (methodName === void 0) { - throw new Error(getErrorMsg('No method name supplied')); - } - - if (obj[methodName] === void 0) { - throw new Error(getErrorMsg(methodName + '() method does not exist')); - } +function isSpy(putativeSpy) { + if (!putativeSpy) { + return false; + } + return putativeSpy.and instanceof SpyStrategy && + putativeSpy.calls instanceof CallTracker; +}; - if (obj[methodName] && j$.isSpy(obj[methodName])) { - if (this.respy) { - return obj[methodName]; - } else { - throw new Error( - getErrorMsg(methodName + ' has already been spied upon'), - ); - } - } +const getErrorMsg = formatErrorMsg( + '', + 'spyOn(, )', +); - let descriptor; - try { - descriptor = Object.getOwnPropertyDescriptor(obj, methodName); - } catch (e) { - // IE 8 doesn't support `definePropery` on non-DOM nodes - } +function SpyRegistry(options) { + options = options || {}; + const currentSpies = options.currentSpies || + function() { + return []; + }; - if (descriptor && !(descriptor.writable || descriptor.set)) { + this.allowRespy = function(allow) { + this.respy = allow; + }; + + this.spyOn = function(obj, methodName) { + if (obj === void 0) { + throw new Error( + getErrorMsg( + 'could not find an object to spy upon for ' + methodName + '()', + ), + ); + } + + if (methodName === void 0) { + throw new Error(getErrorMsg('No method name supplied')); + } + + if (obj[methodName] === void 0) { + throw new Error(getErrorMsg(methodName + '() method does not exist')); + } + + if (obj[methodName] && isSpy(obj[methodName])) { + if (this.respy) { + return obj[methodName]; + } else { throw new Error( - getErrorMsg( - methodName + ' is not declared writable or has no setter', - ), + getErrorMsg(methodName + ' has already been spied upon'), ); } - - const originalMethod = obj[methodName]; - const spiedMethod = j$.createSpy(methodName, originalMethod); - let restoreStrategy; - - if (Object.prototype.hasOwnProperty.call(obj, methodName)) { - restoreStrategy = function() { + } + + let descriptor; + try { + descriptor = Object.getOwnPropertyDescriptor(obj, methodName); + } catch (e) { + // IE 8 doesn't support `definePropery` on non-DOM nodes + } + + if (descriptor && !(descriptor.writable || descriptor.set)) { + throw new Error( + getErrorMsg( + methodName + ' is not declared writable or has no setter', + ), + ); + } + + const originalMethod = obj[methodName]; + const spiedMethod = createSpy(methodName, originalMethod); + let restoreStrategy; + + if (Object.prototype.hasOwnProperty.call(obj, methodName)) { + restoreStrategy = function() { + obj[methodName] = originalMethod; + }; + } else { + restoreStrategy = function() { + if (!delete obj[methodName]) { obj[methodName] = originalMethod; - }; - } else { - restoreStrategy = function() { - if (!delete obj[methodName]) { - obj[methodName] = originalMethod; - } - }; - } + } + }; + } - currentSpies().push({ - restoreObjectToOriginalState: restoreStrategy, - }); + currentSpies().push({ + restoreObjectToOriginalState: restoreStrategy, + }); - obj[methodName] = spiedMethod; + obj[methodName] = spiedMethod; - return spiedMethod; - }; + return spiedMethod; + }; - this.clearSpies = function() { - const spies = currentSpies(); - for (let i = spies.length - 1; i >= 0; i--) { - const spyEntry = spies[i]; - spyEntry.restoreObjectToOriginalState(); - } - }; - } + this.clearSpies = function() { + const spies = currentSpies(); + for (let i = spies.length - 1; i >= 0; i--) { + const spyEntry = spies[i]; + spyEntry.restoreObjectToOriginalState(); + } + }; +} - return SpyRegistry; -}; +module.exports = SpyRegistry; diff --git a/packages/jest-jasmine2/src/jasmine/Suite.js b/packages/jest-jasmine2/src/jasmine/Suite.js index 1977694d1364..ead151d8baeb 100644 --- a/packages/jest-jasmine2/src/jasmine/Suite.js +++ b/packages/jest-jasmine2/src/jasmine/Suite.js @@ -36,11 +36,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. const ExpectationFailed = require('./ExpectationFailed'); function Suite(attrs) { - this.env = attrs.env; this.id = attrs.id; this.parentSuite = attrs.parentSuite; this.description = attrs.description; - this.expectationFactory = attrs.expectationFactory; this.expectationResultFactory = attrs.expectationResultFactory; this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; diff --git a/packages/jest-jasmine2/src/jasmine/createSpy.js b/packages/jest-jasmine2/src/jasmine/createSpy.js new file mode 100644 index 000000000000..4fba94d86c3f --- /dev/null +++ b/packages/jest-jasmine2/src/jasmine/createSpy.js @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow + */ +// This file is a heavily modified fork of Jasmine. The original license of the code: +/* +Copyright (c) 2008-2016 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +/* eslint-disable sort-keys */ +'use strict'; + +const CallTracker = require('./CallTracker'); +const SpyStrategy = require('./SpyStrategy'); + +function createSpy(name, originalFn) { + const spyStrategy = new SpyStrategy({ + name, + fn: originalFn, + getSpy() { + return spy; + }, + }); + const callTracker = new CallTracker(); + const spy = function() { + const callData = { + object: this, + args: Array.prototype.slice.apply(arguments), + }; + + callTracker.track(callData); + const returnValue = spyStrategy.exec.apply(this, arguments); + callData.returnValue = returnValue; + + return returnValue; + }; + + for (const prop in originalFn) { + if (prop === 'and' || prop === 'calls') { + throw new Error( + "Jasmine spies would overwrite the 'and' and 'calls' properties " + + 'on the object being spied upon', + ); + } + + spy[prop] = originalFn[prop]; + } + + spy.and = spyStrategy; + spy.calls = callTracker; + + return spy; +}; + +module.exports = createSpy; diff --git a/packages/jest-jasmine2/src/jasmine/jasmine-light.js b/packages/jest-jasmine2/src/jasmine/jasmine-light.js index c28127468287..e23fbd3a3813 100644 --- a/packages/jest-jasmine2/src/jasmine/jasmine-light.js +++ b/packages/jest-jasmine2/src/jasmine/jasmine-light.js @@ -34,7 +34,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; const buildExpectationResult = require('./buildExpectationResult'); -const CallTracker = require('./CallTracker'); +const createSpy = require('./createSpy'); const Env = require('./Env'); const ExceptionFormatter = require('./ExceptionFormatter'); const JsApiReporter = require('./JsApiReporter'); @@ -50,17 +50,22 @@ const TreeProcessor = require('./TreeProcessor'); exports.create = function() { const j$ = {}; - exports.base(j$); + j$.DEFAULT_TIMEOUT_INTERVAL = 5000; + + j$.getEnv = function(options) { + const env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options)); + //jasmine. singletons in here (setTimeout blah blah). + return env; + }; j$.buildExpectationResult = buildExpectationResult; - j$.CallTracker = CallTracker; + j$.createSpy = createSpy; j$.Env = Env(j$); j$.ExceptionFormatter = ExceptionFormatter; j$.JsApiReporter = JsApiReporter; j$.QueueRunner = QueueRunner; j$.ReportDispatcher = ReportDispatcher; j$.Spec = Spec; - j$.SpyRegistry = SpyRegistry(j$); - j$.SpyStrategy = SpyStrategy; + j$.SpyRegistry = SpyRegistry; j$.Suite = Suite; j$.Timer = Timer; j$.TreeProcessor = TreeProcessor; @@ -69,82 +74,6 @@ exports.create = function() { return j$; }; -exports.base = function(j$) { - j$.DEFAULT_TIMEOUT_INTERVAL = 5000; - - j$.getEnv = function(options) { - const env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options)); - //jasmine. singletons in here (setTimeout blah blah). - return env; - }; - - j$.createSpy = function(name, originalFn) { - const spyStrategy = new j$.SpyStrategy({ - name, - fn: originalFn, - getSpy() { - return spy; - }, - }); - const callTracker = new j$.CallTracker(); - const spy = function() { - const callData = { - object: this, - args: Array.prototype.slice.apply(arguments), - }; - - callTracker.track(callData); - const returnValue = spyStrategy.exec.apply(this, arguments); - callData.returnValue = returnValue; - - return returnValue; - }; - - for (const prop in originalFn) { - if (prop === 'and' || prop === 'calls') { - throw new Error( - "Jasmine spies would overwrite the 'and' and 'calls' properties " + - 'on the object being spied upon', - ); - } - - spy[prop] = originalFn[prop]; - } - - spy.and = spyStrategy; - spy.calls = callTracker; - - return spy; - }; - - j$.isSpy = function(putativeSpy) { - if (!putativeSpy) { - return false; - } - return putativeSpy.and instanceof j$.SpyStrategy && - putativeSpy.calls instanceof j$.CallTracker; - }; - - j$.createSpyObj = function(baseName, methodNames) { - if (Array.isArray(baseName) && methodNames === void 0) { - methodNames = baseName; - baseName = 'unknown'; - } - - if (!Array.isArray(methodNames) || methodNames.length === 0) { - throw new Error( - 'createSpyObj requires a non-empty array of method names to ' + - 'create spies for', - ); - } - const obj = {}; - for (let i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]); - } - return obj; - }; -}; - exports.interface = function(jasmine, env) { const jasmineInterface = { describe(description, specDefinitions) {