diff options
Diffstat (limited to 'node_modules/@jest/test-sequencer')
| -rw-r--r-- | node_modules/@jest/test-sequencer/LICENSE | 21 | ||||
| -rw-r--r-- | node_modules/@jest/test-sequencer/build/index.d.ts | 51 | ||||
| -rw-r--r-- | node_modules/@jest/test-sequencer/build/index.js | 237 | ||||
| -rw-r--r-- | node_modules/@jest/test-sequencer/package.json | 35 | 
4 files changed, 344 insertions, 0 deletions
diff --git a/node_modules/@jest/test-sequencer/LICENSE b/node_modules/@jest/test-sequencer/LICENSE new file mode 100644 index 0000000..b96dcb0 --- /dev/null +++ b/node_modules/@jest/test-sequencer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +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. diff --git a/node_modules/@jest/test-sequencer/build/index.d.ts b/node_modules/@jest/test-sequencer/build/index.d.ts new file mode 100644 index 0000000..7b48a2b --- /dev/null +++ b/node_modules/@jest/test-sequencer/build/index.d.ts @@ -0,0 +1,51 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import type { AggregatedResult, Test } from '@jest/test-result'; +import type { Context } from 'jest-runtime'; +declare type Cache = { +    [key: string]: [0 | 1, number]; +}; +/** + * The TestSequencer will ultimately decide which tests should run first. + * It is responsible for storing and reading from a local cache + * map that stores context information for a given test, such as how long it + * took to run during the last run and if it has failed or not. + * Such information is used on: + * TestSequencer.sort(tests: Array<Test>) + * to sort the order of the provided tests. + * + * After the results are collected, + * TestSequencer.cacheResults(tests: Array<Test>, results: AggregatedResult) + * is called to store/update this information on the cache map. + */ +export default class TestSequencer { +    private _cache; +    _getCachePath(context: Context): string; +    _getCache(test: Test): Cache; +    /** +     * Sorting tests is very important because it has a great impact on the +     * user-perceived responsiveness and speed of the test run. +     * +     * If such information is on cache, tests are sorted based on: +     * -> Has it failed during the last run ? +     * Since it's important to provide the most expected feedback as quickly +     * as possible. +     * -> How long it took to run ? +     * Because running long tests first is an effort to minimize worker idle +     * time at the end of a long test run. +     * And if that information is not available they are sorted based on file size +     * since big test files usually take longer to complete. +     * +     * Note that a possible improvement would be to analyse other information +     * from the file other than its size. +     * +     */ +    sort(tests: Array<Test>): Array<Test>; +    allFailedTests(tests: Array<Test>): Array<Test>; +    cacheResults(tests: Array<Test>, results: AggregatedResult): void; +} +export {}; diff --git a/node_modules/@jest/test-sequencer/build/index.js b/node_modules/@jest/test-sequencer/build/index.js new file mode 100644 index 0000000..29fd68c --- /dev/null +++ b/node_modules/@jest/test-sequencer/build/index.js @@ -0,0 +1,237 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { +  value: true +}); +exports.default = void 0; + +function fs() { +  const data = _interopRequireWildcard(require('graceful-fs')); + +  fs = function () { +    return data; +  }; + +  return data; +} + +function _jestHasteMap() { +  const data = _interopRequireDefault(require('jest-haste-map')); + +  _jestHasteMap = function () { +    return data; +  }; + +  return data; +} + +function _interopRequireDefault(obj) { +  return obj && obj.__esModule ? obj : {default: obj}; +} + +function _getRequireWildcardCache(nodeInterop) { +  if (typeof WeakMap !== 'function') return null; +  var cacheBabelInterop = new WeakMap(); +  var cacheNodeInterop = new WeakMap(); +  return (_getRequireWildcardCache = function (nodeInterop) { +    return nodeInterop ? cacheNodeInterop : cacheBabelInterop; +  })(nodeInterop); +} + +function _interopRequireWildcard(obj, nodeInterop) { +  if (!nodeInterop && obj && obj.__esModule) { +    return obj; +  } +  if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) { +    return {default: obj}; +  } +  var cache = _getRequireWildcardCache(nodeInterop); +  if (cache && cache.has(obj)) { +    return cache.get(obj); +  } +  var newObj = {}; +  var hasPropertyDescriptor = +    Object.defineProperty && Object.getOwnPropertyDescriptor; +  for (var key in obj) { +    if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) { +      var desc = hasPropertyDescriptor +        ? Object.getOwnPropertyDescriptor(obj, key) +        : null; +      if (desc && (desc.get || desc.set)) { +        Object.defineProperty(newObj, key, desc); +      } else { +        newObj[key] = obj[key]; +      } +    } +  } +  newObj.default = obj; +  if (cache) { +    cache.set(obj, newObj); +  } +  return newObj; +} + +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; +} + +const FAIL = 0; +const SUCCESS = 1; + +/** + * The TestSequencer will ultimately decide which tests should run first. + * It is responsible for storing and reading from a local cache + * map that stores context information for a given test, such as how long it + * took to run during the last run and if it has failed or not. + * Such information is used on: + * TestSequencer.sort(tests: Array<Test>) + * to sort the order of the provided tests. + * + * After the results are collected, + * TestSequencer.cacheResults(tests: Array<Test>, results: AggregatedResult) + * is called to store/update this information on the cache map. + */ +class TestSequencer { +  constructor() { +    _defineProperty(this, '_cache', new Map()); +  } + +  _getCachePath(context) { +    const {config} = context; + +    const HasteMapClass = _jestHasteMap().default.getStatic(config); + +    return HasteMapClass.getCacheFilePath( +      config.cacheDirectory, +      'perf-cache-' + config.name +    ); +  } + +  _getCache(test) { +    const {context} = test; + +    if (!this._cache.has(context) && context.config.cache) { +      const cachePath = this._getCachePath(context); + +      if (fs().existsSync(cachePath)) { +        try { +          this._cache.set( +            context, +            JSON.parse(fs().readFileSync(cachePath, 'utf8')) +          ); +        } catch {} +      } +    } + +    let cache = this._cache.get(context); + +    if (!cache) { +      cache = {}; + +      this._cache.set(context, cache); +    } + +    return cache; +  } +  /** +   * Sorting tests is very important because it has a great impact on the +   * user-perceived responsiveness and speed of the test run. +   * +   * If such information is on cache, tests are sorted based on: +   * -> Has it failed during the last run ? +   * Since it's important to provide the most expected feedback as quickly +   * as possible. +   * -> How long it took to run ? +   * Because running long tests first is an effort to minimize worker idle +   * time at the end of a long test run. +   * And if that information is not available they are sorted based on file size +   * since big test files usually take longer to complete. +   * +   * Note that a possible improvement would be to analyse other information +   * from the file other than its size. +   * +   */ + +  sort(tests) { +    const stats = {}; + +    const fileSize = ({path, context: {hasteFS}}) => +      stats[path] || (stats[path] = hasteFS.getSize(path) || 0); + +    const hasFailed = (cache, test) => +      cache[test.path] && cache[test.path][0] === FAIL; + +    const time = (cache, test) => cache[test.path] && cache[test.path][1]; + +    tests.forEach(test => (test.duration = time(this._getCache(test), test))); +    return tests.sort((testA, testB) => { +      const cacheA = this._getCache(testA); + +      const cacheB = this._getCache(testB); + +      const failedA = hasFailed(cacheA, testA); +      const failedB = hasFailed(cacheB, testB); +      const hasTimeA = testA.duration != null; + +      if (failedA !== failedB) { +        return failedA ? -1 : 1; +      } else if (hasTimeA != (testB.duration != null)) { +        // If only one of two tests has timing information, run it last +        return hasTimeA ? 1 : -1; +      } else if (testA.duration != null && testB.duration != null) { +        return testA.duration < testB.duration ? 1 : -1; +      } else { +        return fileSize(testA) < fileSize(testB) ? 1 : -1; +      } +    }); +  } + +  allFailedTests(tests) { +    const hasFailed = (cache, test) => { +      var _cache$test$path; + +      return ( +        ((_cache$test$path = cache[test.path]) === null || +        _cache$test$path === void 0 +          ? void 0 +          : _cache$test$path[0]) === FAIL +      ); +    }; + +    return this.sort( +      tests.filter(test => hasFailed(this._getCache(test), test)) +    ); +  } + +  cacheResults(tests, results) { +    const map = Object.create(null); +    tests.forEach(test => (map[test.path] = test)); +    results.testResults.forEach(testResult => { +      if (testResult && map[testResult.testFilePath] && !testResult.skipped) { +        const cache = this._getCache(map[testResult.testFilePath]); + +        const perf = testResult.perfStats; +        cache[testResult.testFilePath] = [ +          testResult.numFailingTests ? FAIL : SUCCESS, +          perf.runtime || 0 +        ]; +      } +    }); + +    this._cache.forEach((cache, context) => +      fs().writeFileSync(this._getCachePath(context), JSON.stringify(cache)) +    ); +  } +} + +exports.default = TestSequencer; diff --git a/node_modules/@jest/test-sequencer/package.json b/node_modules/@jest/test-sequencer/package.json new file mode 100644 index 0000000..f4eb2c3 --- /dev/null +++ b/node_modules/@jest/test-sequencer/package.json @@ -0,0 +1,35 @@ +{ +  "name": "@jest/test-sequencer", +  "version": "27.5.1", +  "repository": { +    "type": "git", +    "url": "https://github.com/facebook/jest.git", +    "directory": "packages/jest-test-sequencer" +  }, +  "license": "MIT", +  "main": "./build/index.js", +  "types": "./build/index.d.ts", +  "exports": { +    ".": { +      "types": "./build/index.d.ts", +      "default": "./build/index.js" +    }, +    "./package.json": "./package.json" +  }, +  "dependencies": { +    "@jest/test-result": "^27.5.1", +    "graceful-fs": "^4.2.9", +    "jest-haste-map": "^27.5.1", +    "jest-runtime": "^27.5.1" +  }, +  "devDependencies": { +    "@types/graceful-fs": "^4.1.3" +  }, +  "engines": { +    "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" +  }, +  "publishConfig": { +    "access": "public" +  }, +  "gitHead": "67c1aa20c5fec31366d733e901fee2b981cb1850" +}  | 
