|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- 'use strict';
-
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- exports.default = _default;
-
- 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 _default(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
- });
- };
- }
- };
- }
|