diff options
Diffstat (limited to 'node_modules/jest-jasmine2/build/jasmine/Env.js')
-rw-r--r-- | node_modules/jest-jasmine2/build/jasmine/Env.js | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/node_modules/jest-jasmine2/build/jasmine/Env.js b/node_modules/jest-jasmine2/build/jasmine/Env.js new file mode 100644 index 0000000..382c9c2 --- /dev/null +++ b/node_modules/jest-jasmine2/build/jasmine/Env.js @@ -0,0 +1,716 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = jasmineEnv; + +var _assert = require('assert'); + +var _jestUtil = require('jest-util'); + +var _assertionErrorMessage = _interopRequireDefault( + require('../assertionErrorMessage') +); + +var _isError = _interopRequireDefault(require('../isError')); + +var _queueRunner = _interopRequireDefault(require('../queueRunner')); + +var _treeProcessor = _interopRequireDefault(require('../treeProcessor')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} + +function jasmineEnv(j$) { + return class Env { + constructor() { + _defineProperty(this, 'specFilter', void 0); + + _defineProperty(this, 'catchExceptions', void 0); + + _defineProperty(this, 'throwOnExpectationFailure', void 0); + + _defineProperty(this, 'catchingExceptions', void 0); + + _defineProperty(this, 'topSuite', void 0); + + _defineProperty(this, 'fail', void 0); + + _defineProperty(this, 'pending', void 0); + + _defineProperty(this, 'afterAll', void 0); + + _defineProperty(this, 'fit', void 0); + + _defineProperty(this, 'throwingExpectationFailures', void 0); + + _defineProperty(this, 'randomizeTests', void 0); + + _defineProperty(this, 'randomTests', void 0); + + _defineProperty(this, 'seed', void 0); + + _defineProperty(this, 'execute', void 0); + + _defineProperty(this, 'fdescribe', void 0); + + _defineProperty(this, 'spyOn', void 0); + + _defineProperty(this, 'beforeEach', void 0); + + _defineProperty(this, 'afterEach', void 0); + + _defineProperty(this, 'clearReporters', void 0); + + _defineProperty(this, 'addReporter', void 0); + + _defineProperty(this, 'it', void 0); + + _defineProperty(this, 'xdescribe', void 0); + + _defineProperty(this, 'xit', void 0); + + _defineProperty(this, 'beforeAll', void 0); + + _defineProperty(this, 'todo', void 0); + + _defineProperty(this, 'provideFallbackReporter', void 0); + + _defineProperty(this, 'allowRespy', void 0); + + _defineProperty(this, 'describe', void 0); + + let totalSpecsDefined = 0; + let catchExceptions = true; + const realSetTimeout = global.setTimeout; + const realClearTimeout = global.clearTimeout; + const runnableResources = {}; + const currentlyExecutingSuites = []; + let currentSpec = null; + let throwOnExpectationFailure = false; + let random = false; + let seed = null; + let nextSpecId = 0; + let nextSuiteId = 0; + + const getNextSpecId = function () { + return 'spec' + nextSpecId++; + }; + + const getNextSuiteId = function () { + return 'suite' + nextSuiteId++; + }; + + const topSuite = new j$.Suite({ + id: getNextSuiteId(), + description: '', + + getTestPath() { + return j$.testPath; + } + }); + let currentDeclarationSuite = topSuite; + + const currentSuite = function () { + return currentlyExecutingSuites[currentlyExecutingSuites.length - 1]; + }; + + const currentRunnable = function () { + return currentSpec || currentSuite(); + }; + + const reporter = new j$.ReportDispatcher([ + 'jasmineStarted', + 'jasmineDone', + 'suiteStarted', + 'suiteDone', + 'specStarted', + 'specDone' + ]); + + this.specFilter = function () { + return true; + }; + + const defaultResourcesForRunnable = function (id, _parentRunnableId) { + const resources = { + spies: [] + }; + runnableResources[id] = resources; + }; + + const clearResourcesForRunnable = function (id) { + spyRegistry.clearSpies(); + delete runnableResources[id]; + }; + + const beforeAndAfterFns = function (suite) { + return function () { + let afters = []; + let befores = []; + + while (suite) { + befores = befores.concat(suite.beforeFns); + afters = afters.concat(suite.afterFns); + suite = suite.parentSuite; + } + + return { + befores: befores.reverse(), + afters + }; + }; + }; + + const getSpecName = function (spec, suite) { + const fullName = [spec.description]; + const suiteFullName = suite.getFullName(); + + if (suiteFullName !== '') { + fullName.unshift(suiteFullName); + } + + return fullName.join(' '); + }; + + this.catchExceptions = function (value) { + catchExceptions = !!value; + return catchExceptions; + }; + + this.catchingExceptions = function () { + return catchExceptions; + }; + + this.throwOnExpectationFailure = function (value) { + throwOnExpectationFailure = !!value; + }; + + this.throwingExpectationFailures = function () { + return throwOnExpectationFailure; + }; + + this.randomizeTests = function (value) { + random = !!value; + }; + + this.randomTests = function () { + return random; + }; + + this.seed = function (value) { + if (value) { + seed = value; + } + + return seed; + }; + + const queueRunnerFactory = options => { + options.clearTimeout = realClearTimeout; + options.fail = this.fail; + options.setTimeout = realSetTimeout; + return (0, _queueRunner.default)(options); + }; + + this.topSuite = function () { + return topSuite; + }; + + const uncaught = err => { + if (currentSpec) { + currentSpec.onException(err); + currentSpec.cancel(); + } else { + console.error('Unhandled error'); + console.error(err.stack); + } + }; + + let oldListenersException; + let oldListenersRejection; + + const executionSetup = function () { + // Need to ensure we are the only ones handling these exceptions. + oldListenersException = process.listeners('uncaughtException').slice(); + oldListenersRejection = process.listeners('unhandledRejection').slice(); + j$.process.removeAllListeners('uncaughtException'); + j$.process.removeAllListeners('unhandledRejection'); + j$.process.on('uncaughtException', uncaught); + j$.process.on('unhandledRejection', uncaught); + }; + + const executionTeardown = function () { + j$.process.removeListener('uncaughtException', uncaught); + j$.process.removeListener('unhandledRejection', uncaught); // restore previous exception handlers + + oldListenersException.forEach(listener => { + j$.process.on('uncaughtException', listener); + }); + oldListenersRejection.forEach(listener => { + j$.process.on('unhandledRejection', listener); + }); + }; + + this.execute = async function (runnablesToRun, suiteTree = topSuite) { + if (!runnablesToRun) { + if (focusedRunnables.length) { + runnablesToRun = focusedRunnables; + } else { + runnablesToRun = [suiteTree.id]; + } + } + + if (currentlyExecutingSuites.length === 0) { + executionSetup(); + } + + const lastDeclarationSuite = currentDeclarationSuite; + await (0, _treeProcessor.default)({ + nodeComplete(suite) { + if (!suite.disabled) { + clearResourcesForRunnable(suite.id); + } + + currentlyExecutingSuites.pop(); + + if (suite === topSuite) { + reporter.jasmineDone({ + failedExpectations: topSuite.result.failedExpectations + }); + } else { + reporter.suiteDone(suite.getResult()); + } + }, + + nodeStart(suite) { + currentlyExecutingSuites.push(suite); + defaultResourcesForRunnable( + suite.id, + suite.parentSuite && suite.parentSuite.id + ); + + if (suite === topSuite) { + reporter.jasmineStarted({ + totalSpecsDefined + }); + } else { + reporter.suiteStarted(suite.result); + } + }, + + queueRunnerFactory, + runnableIds: runnablesToRun, + tree: suiteTree + }); + currentDeclarationSuite = lastDeclarationSuite; + + if (currentlyExecutingSuites.length === 0) { + executionTeardown(); + } + }; + + this.addReporter = function (reporterToAdd) { + reporter.addReporter(reporterToAdd); + }; + + this.provideFallbackReporter = function (reporterToAdd) { + reporter.provideFallbackReporter(reporterToAdd); + }; + + this.clearReporters = function () { + reporter.clearReporters(); + }; + + const spyRegistry = new j$.SpyRegistry({ + currentSpies() { + if (!currentRunnable()) { + throw new Error( + 'Spies must be created in a before function or a spec' + ); + } + + return runnableResources[currentRunnable().id].spies; + } + }); + + this.allowRespy = function (allow) { + spyRegistry.allowRespy(allow); + }; + + this.spyOn = function (...args) { + return spyRegistry.spyOn.apply(spyRegistry, args); + }; + + const suiteFactory = function (description) { + const suite = new j$.Suite({ + id: getNextSuiteId(), + description, + parentSuite: currentDeclarationSuite, + throwOnExpectationFailure, + + getTestPath() { + return j$.testPath; + } + }); + return suite; + }; + + this.describe = function (description, specDefinitions) { + const suite = suiteFactory(description); + + if (specDefinitions === undefined) { + throw new Error( + 'Missing second argument. It must be a callback function.' + ); + } + + if (typeof specDefinitions !== 'function') { + throw new Error( + `Invalid second argument, ${specDefinitions}. It must be a callback function.` + ); + } + + if (specDefinitions.length > 0) { + throw new Error('describe does not expect any arguments'); + } + + if (currentDeclarationSuite.markedPending) { + suite.pend(); + } + + if (currentDeclarationSuite.markedTodo) { + // @ts-expect-error TODO Possible error: Suite does not have todo method + suite.todo(); + } + + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + this.xdescribe = function (description, specDefinitions) { + const suite = suiteFactory(description); + suite.pend(); + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + const focusedRunnables = []; + + this.fdescribe = function (description, specDefinitions) { + const suite = suiteFactory(description); + suite.isFocused = true; + focusedRunnables.push(suite.id); + unfocusAncestor(); + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + const addSpecsToSuite = (suite, specDefinitions) => { + const parentSuite = currentDeclarationSuite; + parentSuite.addChild(suite); + currentDeclarationSuite = suite; + let declarationError = undefined; + let describeReturnValue; + + try { + describeReturnValue = specDefinitions.call(suite); + } catch (e) { + declarationError = e; + } + + if ((0, _jestUtil.isPromise)(describeReturnValue)) { + declarationError = new Error( + 'Returning a Promise from "describe" is not supported. Tests must be defined synchronously.' + ); + } else if (describeReturnValue !== undefined) { + declarationError = new Error( + 'A "describe" callback must not return a value.' + ); + } + + if (declarationError) { + this.it('encountered a declaration exception', () => { + throw declarationError; + }); + } + + currentDeclarationSuite = parentSuite; + }; + + function findFocusedAncestor(suite) { + while (suite) { + if (suite.isFocused) { + return suite.id; + } + + suite = suite.parentSuite; + } + + return null; + } + + function unfocusAncestor() { + const focusedAncestor = findFocusedAncestor(currentDeclarationSuite); + + if (focusedAncestor) { + for (let i = 0; i < focusedRunnables.length; i++) { + if (focusedRunnables[i] === focusedAncestor) { + focusedRunnables.splice(i, 1); + break; + } + } + } + } + + const specFactory = (description, fn, suite, timeout) => { + totalSpecsDefined++; + const spec = new j$.Spec({ + id: getNextSpecId(), + beforeAndAfterFns: beforeAndAfterFns(suite), + resultCallback: specResultCallback, + + getSpecName(spec) { + return getSpecName(spec, suite); + }, + + getTestPath() { + return j$.testPath; + }, + + onStart: specStarted, + description, + queueRunnerFactory, + + userContext() { + return suite.clonedSharedUserContext(); + }, + + queueableFn: { + fn, + + timeout() { + return timeout || j$._DEFAULT_TIMEOUT_INTERVAL; + } + }, + throwOnExpectationFailure + }); + + if (!this.specFilter(spec)) { + spec.disable(); + } + + return spec; + + function specResultCallback(result) { + clearResourcesForRunnable(spec.id); + currentSpec = null; + reporter.specDone(result); + } + + function specStarted(spec) { + currentSpec = spec; + defaultResourcesForRunnable(spec.id, suite.id); + reporter.specStarted(spec.result); + } + }; + + this.it = function (description, fn, timeout) { + if (typeof description !== 'string') { + throw new Error( + `Invalid first argument, ${description}. It must be a string.` + ); + } + + if (fn === undefined) { + throw new Error( + 'Missing second argument. It must be a callback function. Perhaps you want to use `test.todo` for a test placeholder.' + ); + } + + if (typeof fn !== 'function') { + throw new Error( + `Invalid second argument, ${fn}. It must be a callback function.` + ); + } + + const spec = specFactory( + description, + fn, + currentDeclarationSuite, + timeout + ); + + if (currentDeclarationSuite.markedPending) { + spec.pend(); + } // When a test is defined inside another, jasmine will not run it. + // This check throws an error to warn the user about the edge-case. + + if (currentSpec !== null) { + throw new Error( + `Tests cannot be nested. Test "${spec.description}" cannot run because it is nested within "${currentSpec.description}".` + ); + } + + currentDeclarationSuite.addChild(spec); + return spec; + }; + + this.xit = function (...args) { + const spec = this.it.apply(this, args); + spec.pend('Temporarily disabled with xit'); + return spec; + }; + + this.todo = function () { + const description = arguments[0]; + + if (arguments.length !== 1 || typeof description !== 'string') { + throw new _jestUtil.ErrorWithStack( + 'Todo must be called with only a description.', + this.todo + ); + } + + const spec = specFactory( + description, + () => {}, + currentDeclarationSuite + ); + + if (currentDeclarationSuite.markedPending) { + spec.pend(); + } else { + spec.todo(); + } + + currentDeclarationSuite.addChild(spec); + return spec; + }; + + this.fit = function (description, fn, timeout) { + const spec = specFactory( + description, + fn, + currentDeclarationSuite, + timeout + ); + currentDeclarationSuite.addChild(spec); + + if (currentDeclarationSuite.markedPending) { + spec.pend(); + } else { + focusedRunnables.push(spec.id); + } + + unfocusAncestor(); + return spec; + }; + + this.beforeEach = function (beforeEachFunction, timeout) { + currentDeclarationSuite.beforeEach({ + fn: beforeEachFunction, + + timeout() { + return timeout || j$._DEFAULT_TIMEOUT_INTERVAL; + } + }); + }; + + this.beforeAll = function (beforeAllFunction, timeout) { + currentDeclarationSuite.beforeAll({ + fn: beforeAllFunction, + + timeout() { + return timeout || j$._DEFAULT_TIMEOUT_INTERVAL; + } + }); + }; + + this.afterEach = function (afterEachFunction, timeout) { + currentDeclarationSuite.afterEach({ + fn: afterEachFunction, + + timeout() { + return timeout || j$._DEFAULT_TIMEOUT_INTERVAL; + } + }); + }; + + this.afterAll = function (afterAllFunction, timeout) { + currentDeclarationSuite.afterAll({ + fn: afterAllFunction, + + timeout() { + return timeout || j$._DEFAULT_TIMEOUT_INTERVAL; + } + }); + }; + + this.pending = function (message) { + let fullMessage = j$.Spec.pendingSpecExceptionMessage; + + if (message) { + fullMessage += message; + } + + throw fullMessage; + }; + + this.fail = function (error) { + let checkIsError; + let message; + + if ( + error instanceof _assert.AssertionError || + (error && error.name === _assert.AssertionError.name) + ) { + checkIsError = false; // @ts-expect-error TODO Possible error: j$.Spec does not have expand property + + message = (0, _assertionErrorMessage.default)(error, { + expand: j$.Spec.expand + }); + } else { + const check = (0, _isError.default)(error); + checkIsError = check.isError; + message = check.message; + } + + const errorAsErrorObject = checkIsError ? error : new Error(message); + const runnable = currentRunnable(); + + if (!runnable) { + errorAsErrorObject.message = + 'Caught error after test environment was torn down\n\n' + + errorAsErrorObject.message; + throw errorAsErrorObject; + } + + runnable.addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + message, + error: errorAsErrorObject + }); + }; + } + }; +} |