web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

745 lines
21 KiB

  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.default = _default;
  6. var _assert = require('assert');
  7. var _chalk = _interopRequireDefault(require('chalk'));
  8. var _jestMessageUtil = require('jest-message-util');
  9. var _jestUtil = require('jest-util');
  10. var _assertionErrorMessage = _interopRequireDefault(
  11. require('../assertionErrorMessage')
  12. );
  13. var _isError = _interopRequireDefault(require('../isError'));
  14. var _queueRunner = _interopRequireDefault(require('../queueRunner'));
  15. var _treeProcessor = _interopRequireDefault(require('../treeProcessor'));
  16. function _interopRequireDefault(obj) {
  17. return obj && obj.__esModule ? obj : {default: obj};
  18. }
  19. function _defineProperty(obj, key, value) {
  20. if (key in obj) {
  21. Object.defineProperty(obj, key, {
  22. value: value,
  23. enumerable: true,
  24. configurable: true,
  25. writable: true
  26. });
  27. } else {
  28. obj[key] = value;
  29. }
  30. return obj;
  31. }
  32. function _default(j$) {
  33. var _temp;
  34. return (
  35. (_temp = class Env {
  36. constructor(_options) {
  37. _defineProperty(this, 'specFilter', void 0);
  38. _defineProperty(this, 'catchExceptions', void 0);
  39. _defineProperty(this, 'throwOnExpectationFailure', void 0);
  40. _defineProperty(this, 'catchingExceptions', void 0);
  41. _defineProperty(this, 'topSuite', void 0);
  42. _defineProperty(this, 'fail', void 0);
  43. _defineProperty(this, 'pending', void 0);
  44. _defineProperty(this, 'afterAll', void 0);
  45. _defineProperty(this, 'fit', void 0);
  46. _defineProperty(this, 'throwingExpectationFailures', void 0);
  47. _defineProperty(this, 'randomizeTests', void 0);
  48. _defineProperty(this, 'randomTests', void 0);
  49. _defineProperty(this, 'seed', void 0);
  50. _defineProperty(this, 'execute', void 0);
  51. _defineProperty(this, 'fdescribe', void 0);
  52. _defineProperty(this, 'spyOn', void 0);
  53. _defineProperty(this, 'beforeEach', void 0);
  54. _defineProperty(this, 'afterEach', void 0);
  55. _defineProperty(this, 'clearReporters', void 0);
  56. _defineProperty(this, 'addReporter', void 0);
  57. _defineProperty(this, 'it', void 0);
  58. _defineProperty(this, 'xdescribe', void 0);
  59. _defineProperty(this, 'xit', void 0);
  60. _defineProperty(this, 'beforeAll', void 0);
  61. _defineProperty(this, 'todo', void 0);
  62. _defineProperty(this, 'provideFallbackReporter', void 0);
  63. _defineProperty(this, 'allowRespy', void 0);
  64. _defineProperty(this, 'describe', void 0);
  65. let totalSpecsDefined = 0;
  66. let catchExceptions = true;
  67. const realSetTimeout = global.setTimeout;
  68. const realClearTimeout = global.clearTimeout;
  69. const runnableResources = {};
  70. const currentlyExecutingSuites = [];
  71. let currentSpec = null;
  72. let throwOnExpectationFailure = false;
  73. let random = false;
  74. let seed = null;
  75. let nextSpecId = 0;
  76. let nextSuiteId = 0;
  77. const getNextSpecId = function () {
  78. return 'spec' + nextSpecId++;
  79. };
  80. const getNextSuiteId = function () {
  81. return 'suite' + nextSuiteId++;
  82. };
  83. const topSuite = new j$.Suite({
  84. id: getNextSuiteId(),
  85. description: '',
  86. getTestPath() {
  87. return j$.testPath;
  88. }
  89. });
  90. let currentDeclarationSuite = topSuite;
  91. const currentSuite = function () {
  92. return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
  93. };
  94. const currentRunnable = function () {
  95. return currentSpec || currentSuite();
  96. };
  97. const reporter = new j$.ReportDispatcher([
  98. 'jasmineStarted',
  99. 'jasmineDone',
  100. 'suiteStarted',
  101. 'suiteDone',
  102. 'specStarted',
  103. 'specDone'
  104. ]);
  105. this.specFilter = function () {
  106. return true;
  107. };
  108. const defaultResourcesForRunnable = function (id, _parentRunnableId) {
  109. const resources = {
  110. spies: []
  111. };
  112. runnableResources[id] = resources;
  113. };
  114. const clearResourcesForRunnable = function (id) {
  115. spyRegistry.clearSpies();
  116. delete runnableResources[id];
  117. };
  118. const beforeAndAfterFns = function (suite) {
  119. return function () {
  120. let afters = [];
  121. let befores = [];
  122. while (suite) {
  123. befores = befores.concat(suite.beforeFns);
  124. afters = afters.concat(suite.afterFns);
  125. suite = suite.parentSuite;
  126. }
  127. return {
  128. befores: befores.reverse(),
  129. afters
  130. };
  131. };
  132. };
  133. const getSpecName = function (spec, suite) {
  134. const fullName = [spec.description];
  135. const suiteFullName = suite.getFullName();
  136. if (suiteFullName !== '') {
  137. fullName.unshift(suiteFullName);
  138. }
  139. return fullName.join(' ');
  140. };
  141. this.catchExceptions = function (value) {
  142. catchExceptions = !!value;
  143. return catchExceptions;
  144. };
  145. this.catchingExceptions = function () {
  146. return catchExceptions;
  147. };
  148. this.throwOnExpectationFailure = function (value) {
  149. throwOnExpectationFailure = !!value;
  150. };
  151. this.throwingExpectationFailures = function () {
  152. return throwOnExpectationFailure;
  153. };
  154. this.randomizeTests = function (value) {
  155. random = !!value;
  156. };
  157. this.randomTests = function () {
  158. return random;
  159. };
  160. this.seed = function (value) {
  161. if (value) {
  162. seed = value;
  163. }
  164. return seed;
  165. };
  166. const queueRunnerFactory = options => {
  167. options.clearTimeout = realClearTimeout;
  168. options.fail = this.fail;
  169. options.setTimeout = realSetTimeout;
  170. return (0, _queueRunner.default)(options);
  171. };
  172. this.topSuite = function () {
  173. return topSuite;
  174. };
  175. const uncaught = err => {
  176. if (currentSpec) {
  177. currentSpec.onException(err);
  178. currentSpec.cancel();
  179. } else {
  180. console.error('Unhandled error');
  181. console.error(err.stack);
  182. }
  183. };
  184. let oldListenersException;
  185. let oldListenersRejection;
  186. const executionSetup = function () {
  187. // Need to ensure we are the only ones handling these exceptions.
  188. oldListenersException = process
  189. .listeners('uncaughtException')
  190. .slice();
  191. oldListenersRejection = process
  192. .listeners('unhandledRejection')
  193. .slice();
  194. j$.process.removeAllListeners('uncaughtException');
  195. j$.process.removeAllListeners('unhandledRejection');
  196. j$.process.on('uncaughtException', uncaught);
  197. j$.process.on('unhandledRejection', uncaught);
  198. };
  199. const executionTeardown = function () {
  200. j$.process.removeListener('uncaughtException', uncaught);
  201. j$.process.removeListener('unhandledRejection', uncaught); // restore previous exception handlers
  202. oldListenersException.forEach(listener => {
  203. j$.process.on('uncaughtException', listener);
  204. });
  205. oldListenersRejection.forEach(listener => {
  206. j$.process.on('unhandledRejection', listener);
  207. });
  208. };
  209. this.execute = async function (runnablesToRun, suiteTree = topSuite) {
  210. if (!runnablesToRun) {
  211. if (focusedRunnables.length) {
  212. runnablesToRun = focusedRunnables;
  213. } else {
  214. runnablesToRun = [suiteTree.id];
  215. }
  216. }
  217. if (currentlyExecutingSuites.length === 0) {
  218. executionSetup();
  219. }
  220. const lastDeclarationSuite = currentDeclarationSuite;
  221. await (0, _treeProcessor.default)({
  222. nodeComplete(suite) {
  223. if (!suite.disabled) {
  224. clearResourcesForRunnable(suite.id);
  225. }
  226. currentlyExecutingSuites.pop();
  227. if (suite === topSuite) {
  228. reporter.jasmineDone({
  229. failedExpectations: topSuite.result.failedExpectations
  230. });
  231. } else {
  232. reporter.suiteDone(suite.getResult());
  233. }
  234. },
  235. nodeStart(suite) {
  236. currentlyExecutingSuites.push(suite);
  237. defaultResourcesForRunnable(
  238. suite.id,
  239. suite.parentSuite && suite.parentSuite.id
  240. );
  241. if (suite === topSuite) {
  242. reporter.jasmineStarted({
  243. totalSpecsDefined
  244. });
  245. } else {
  246. reporter.suiteStarted(suite.result);
  247. }
  248. },
  249. queueRunnerFactory,
  250. runnableIds: runnablesToRun,
  251. tree: suiteTree
  252. });
  253. currentDeclarationSuite = lastDeclarationSuite;
  254. if (currentlyExecutingSuites.length === 0) {
  255. executionTeardown();
  256. }
  257. };
  258. this.addReporter = function (reporterToAdd) {
  259. reporter.addReporter(reporterToAdd);
  260. };
  261. this.provideFallbackReporter = function (reporterToAdd) {
  262. reporter.provideFallbackReporter(reporterToAdd);
  263. };
  264. this.clearReporters = function () {
  265. reporter.clearReporters();
  266. };
  267. const spyRegistry = new j$.SpyRegistry({
  268. currentSpies() {
  269. if (!currentRunnable()) {
  270. throw new Error(
  271. 'Spies must be created in a before function or a spec'
  272. );
  273. }
  274. return runnableResources[currentRunnable().id].spies;
  275. }
  276. });
  277. this.allowRespy = function (allow) {
  278. spyRegistry.allowRespy(allow);
  279. };
  280. this.spyOn = function (...args) {
  281. return spyRegistry.spyOn.apply(spyRegistry, args);
  282. };
  283. const suiteFactory = function (description) {
  284. const suite = new j$.Suite({
  285. id: getNextSuiteId(),
  286. description,
  287. parentSuite: currentDeclarationSuite,
  288. throwOnExpectationFailure,
  289. getTestPath() {
  290. return j$.testPath;
  291. }
  292. });
  293. return suite;
  294. };
  295. this.describe = function (description, specDefinitions) {
  296. const suite = suiteFactory(description);
  297. if (specDefinitions === undefined) {
  298. throw new Error(
  299. `Missing second argument. It must be a callback function.`
  300. );
  301. }
  302. if (typeof specDefinitions !== 'function') {
  303. throw new Error(
  304. `Invalid second argument, ${specDefinitions}. It must be a callback function.`
  305. );
  306. }
  307. if (specDefinitions.length > 0) {
  308. throw new Error('describe does not expect any arguments');
  309. }
  310. if (currentDeclarationSuite.markedPending) {
  311. suite.pend();
  312. }
  313. if (currentDeclarationSuite.markedTodo) {
  314. // @ts-expect-error TODO Possible error: Suite does not have todo method
  315. suite.todo();
  316. }
  317. addSpecsToSuite(suite, specDefinitions);
  318. return suite;
  319. };
  320. this.xdescribe = function (description, specDefinitions) {
  321. const suite = suiteFactory(description);
  322. suite.pend();
  323. addSpecsToSuite(suite, specDefinitions);
  324. return suite;
  325. };
  326. const focusedRunnables = [];
  327. this.fdescribe = function (description, specDefinitions) {
  328. const suite = suiteFactory(description);
  329. suite.isFocused = true;
  330. focusedRunnables.push(suite.id);
  331. unfocusAncestor();
  332. addSpecsToSuite(suite, specDefinitions);
  333. return suite;
  334. };
  335. const addSpecsToSuite = (suite, specDefinitions) => {
  336. const parentSuite = currentDeclarationSuite;
  337. parentSuite.addChild(suite);
  338. currentDeclarationSuite = suite;
  339. let declarationError = undefined;
  340. let describeReturnValue;
  341. try {
  342. describeReturnValue = specDefinitions.call(suite);
  343. } catch (e) {
  344. declarationError = e;
  345. } // TODO throw in Jest 25: declarationError = new Error
  346. if ((0, _jestUtil.isPromise)(describeReturnValue)) {
  347. console.log(
  348. (0, _jestMessageUtil.formatExecError)(
  349. new Error(
  350. _chalk.default.yellow(
  351. 'Returning a Promise from "describe" is not supported. Tests must be defined synchronously.\n' +
  352. 'Returning a value from "describe" will fail the test in a future version of Jest.'
  353. )
  354. ),
  355. {
  356. rootDir: '',
  357. testMatch: []
  358. },
  359. {
  360. noStackTrace: false
  361. }
  362. )
  363. );
  364. } else if (describeReturnValue !== undefined) {
  365. console.log(
  366. (0, _jestMessageUtil.formatExecError)(
  367. new Error(
  368. _chalk.default.yellow(
  369. 'A "describe" callback must not return a value.\n' +
  370. 'Returning a value from "describe" will fail the test in a future version of Jest.'
  371. )
  372. ),
  373. {
  374. rootDir: '',
  375. testMatch: []
  376. },
  377. {
  378. noStackTrace: false
  379. }
  380. )
  381. );
  382. }
  383. if (declarationError) {
  384. this.it('encountered a declaration exception', () => {
  385. throw declarationError;
  386. });
  387. }
  388. currentDeclarationSuite = parentSuite;
  389. };
  390. function findFocusedAncestor(suite) {
  391. while (suite) {
  392. if (suite.isFocused) {
  393. return suite.id;
  394. }
  395. suite = suite.parentSuite;
  396. }
  397. return null;
  398. }
  399. function unfocusAncestor() {
  400. const focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
  401. if (focusedAncestor) {
  402. for (let i = 0; i < focusedRunnables.length; i++) {
  403. if (focusedRunnables[i] === focusedAncestor) {
  404. focusedRunnables.splice(i, 1);
  405. break;
  406. }
  407. }
  408. }
  409. }
  410. const specFactory = (description, fn, suite, timeout) => {
  411. totalSpecsDefined++;
  412. const spec = new j$.Spec({
  413. id: getNextSpecId(),
  414. beforeAndAfterFns: beforeAndAfterFns(suite),
  415. resultCallback: specResultCallback,
  416. getSpecName(spec) {
  417. return getSpecName(spec, suite);
  418. },
  419. getTestPath() {
  420. return j$.testPath;
  421. },
  422. onStart: specStarted,
  423. description,
  424. queueRunnerFactory,
  425. userContext() {
  426. return suite.clonedSharedUserContext();
  427. },
  428. queueableFn: {
  429. fn,
  430. timeout() {
  431. return timeout || j$._DEFAULT_TIMEOUT_INTERVAL;
  432. }
  433. },
  434. throwOnExpectationFailure
  435. });
  436. if (!this.specFilter(spec)) {
  437. spec.disable();
  438. }
  439. return spec;
  440. function specResultCallback(result) {
  441. clearResourcesForRunnable(spec.id);
  442. currentSpec = null;
  443. reporter.specDone(result);
  444. }
  445. function specStarted(spec) {
  446. currentSpec = spec;
  447. defaultResourcesForRunnable(spec.id, suite.id);
  448. reporter.specStarted(spec.result);
  449. }
  450. };
  451. this.it = function (description, fn, timeout) {
  452. if (typeof description !== 'string') {
  453. throw new Error(
  454. `Invalid first argument, ${description}. It must be a string.`
  455. );
  456. }
  457. if (fn === undefined) {
  458. throw new Error(
  459. 'Missing second argument. It must be a callback function. Perhaps you want to use `test.todo` for a test placeholder.'
  460. );
  461. }
  462. if (typeof fn !== 'function') {
  463. throw new Error(
  464. `Invalid second argument, ${fn}. It must be a callback function.`
  465. );
  466. }
  467. const spec = specFactory(
  468. description,
  469. fn,
  470. currentDeclarationSuite,
  471. timeout
  472. );
  473. if (currentDeclarationSuite.markedPending) {
  474. spec.pend();
  475. } // When a test is defined inside another, jasmine will not run it.
  476. // This check throws an error to warn the user about the edge-case.
  477. if (currentSpec !== null) {
  478. throw new Error(
  479. `Tests cannot be nested. Test "${spec.description}" cannot run because it is nested within "${currentSpec.description}".`
  480. );
  481. }
  482. currentDeclarationSuite.addChild(spec);
  483. return spec;
  484. };
  485. this.xit = function (...args) {
  486. const spec = this.it.apply(this, args);
  487. spec.pend('Temporarily disabled with xit');
  488. return spec;
  489. };
  490. this.todo = function () {
  491. const description = arguments[0];
  492. if (arguments.length !== 1 || typeof description !== 'string') {
  493. throw new _jestUtil.ErrorWithStack(
  494. 'Todo must be called with only a description.',
  495. this.todo
  496. );
  497. }
  498. const spec = specFactory(
  499. description,
  500. () => {},
  501. currentDeclarationSuite
  502. );
  503. spec.todo();
  504. currentDeclarationSuite.addChild(spec);
  505. return spec;
  506. };
  507. this.fit = function (description, fn, timeout) {
  508. const spec = specFactory(
  509. description,
  510. fn,
  511. currentDeclarationSuite,
  512. timeout
  513. );
  514. currentDeclarationSuite.addChild(spec);
  515. focusedRunnables.push(spec.id);
  516. unfocusAncestor();
  517. return spec;
  518. };
  519. this.beforeEach = function (beforeEachFunction, timeout) {
  520. currentDeclarationSuite.beforeEach({
  521. fn: beforeEachFunction,
  522. timeout() {
  523. return timeout || j$._DEFAULT_TIMEOUT_INTERVAL;
  524. }
  525. });
  526. };
  527. this.beforeAll = function (beforeAllFunction, timeout) {
  528. currentDeclarationSuite.beforeAll({
  529. fn: beforeAllFunction,
  530. timeout() {
  531. return timeout || j$._DEFAULT_TIMEOUT_INTERVAL;
  532. }
  533. });
  534. };
  535. this.afterEach = function (afterEachFunction, timeout) {
  536. currentDeclarationSuite.afterEach({
  537. fn: afterEachFunction,
  538. timeout() {
  539. return timeout || j$._DEFAULT_TIMEOUT_INTERVAL;
  540. }
  541. });
  542. };
  543. this.afterAll = function (afterAllFunction, timeout) {
  544. currentDeclarationSuite.afterAll({
  545. fn: afterAllFunction,
  546. timeout() {
  547. return timeout || j$._DEFAULT_TIMEOUT_INTERVAL;
  548. }
  549. });
  550. };
  551. this.pending = function (message) {
  552. let fullMessage = j$.Spec.pendingSpecExceptionMessage;
  553. if (message) {
  554. fullMessage += message;
  555. }
  556. throw fullMessage;
  557. };
  558. this.fail = function (error) {
  559. let checkIsError;
  560. let message;
  561. if (
  562. error instanceof _assert.AssertionError ||
  563. (error && error.name === _assert.AssertionError.name)
  564. ) {
  565. checkIsError = false; // @ts-expect-error TODO Possible error: j$.Spec does not have expand property
  566. message = (0, _assertionErrorMessage.default)(error, {
  567. expand: j$.Spec.expand
  568. });
  569. } else {
  570. const check = (0, _isError.default)(error);
  571. checkIsError = check.isError;
  572. message = check.message;
  573. }
  574. const errorAsErrorObject = checkIsError ? error : new Error(message);
  575. const runnable = currentRunnable();
  576. if (!runnable) {
  577. errorAsErrorObject.message =
  578. 'Caught error after test environment was torn down\n\n' +
  579. errorAsErrorObject.message;
  580. throw errorAsErrorObject;
  581. }
  582. runnable.addExpectationResult(false, {
  583. matcherName: '',
  584. passed: false,
  585. expected: '',
  586. actual: '',
  587. message,
  588. error: errorAsErrorObject
  589. });
  590. };
  591. }
  592. }),
  593. _temp
  594. );
  595. }