diff --git a/docs/configuration.md b/docs/configuration.md index 5abc56e65d..56ee7ecb5b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -98,6 +98,41 @@ Config file: Settings for the `dashboard` [reporter](#reporters-string). See the [dashboard documentation](../General/dashboard.md) for more info. +### `disableBail` [`boolean`] + +_Since v5.4_ + +Default: `false`
+Command: `--disableBail`
+Config file: `"disableBail": true` + +Configure the test runner to report all failing tests when a mutant is killed instead of bailing after the first failing test. Bailing brings better performance, but you might be interested in the full report instead. This might be useful when using the "Tests" view to hunt for tests that don't kill a single mutant. + +See the difference of bail vs no bail on StrykerJS's utils package (with `--concurrency 4`): + + + + + + + + +
+
+ With bail +
With bail, in 2min 33s.
+
+
+
+ Disable bail +
Disable bail, in 2 min 45s.
+
+
+ +As you can see, when you disable bail, a lot more tests get the "Killing" status, meaning that they killed at least 1 mutant. This does come with a performance penalty of 12s in this example. + +_Note: Disable bail needs to be supported by the test runner plugin in order to work. All official test runner plugins (`@stryker-mutator/xxx-runner`) support this feature._ + ### `disableTypeChecks` [`false | string`] Default: `"{test,src,lib}/**/*.{js,ts,jsx,tsx,html,vue}"`
diff --git a/docs/images/configuration-disable-bail.png b/docs/images/configuration-disable-bail.png new file mode 100644 index 0000000000..b6a3212ba0 Binary files /dev/null and b/docs/images/configuration-disable-bail.png differ diff --git a/docs/images/configuration-with-bail.png b/docs/images/configuration-with-bail.png new file mode 100644 index 0000000000..fb2c7e0a73 Binary files /dev/null and b/docs/images/configuration-with-bail.png differ diff --git a/e2e/helpers.ts b/e2e/helpers.ts index e7885cd645..0b02497ce9 100644 --- a/e2e/helpers.ts +++ b/e2e/helpers.ts @@ -3,7 +3,7 @@ import { promises as fsPromises } from 'fs'; import { mutationTestReportSchema } from '@stryker-mutator/api/report'; import { expect } from 'chai'; import path from 'path'; -import { calculateMetrics, MetricsResult, Metrics } from 'mutation-testing-metrics'; +import { calculateMutationTestMetrics, MetricsResult, Metrics } from 'mutation-testing-metrics'; import { execSync, ExecException } from 'child_process'; interface PipedStdioSyncExecException extends ExecException { @@ -50,14 +50,14 @@ export async function readMutationTestResult(eventResultDirectory = path.resolve expect(mutationTestReportFile).ok; const mutationTestReportContent = await fsPromises.readFile(path.resolve(eventResultDirectory, mutationTestReportFile || ''), 'utf8'); const report = JSON.parse(mutationTestReportContent) as mutationTestReportSchema.MutationTestResult; - const metricsResult = calculateMetrics(report.files); + const metricsResult = calculateMutationTestMetrics(report); return metricsResult; } export async function readMutationTestingJsonResult(jsonReportFile = path.resolve('reports', 'mutation', 'mutation.json')) { const mutationTestReportContent = await fsPromises.readFile(jsonReportFile, 'utf8'); const report = JSON.parse(mutationTestReportContent) as mutationTestReportSchema.MutationTestResult; - const metricsResult = calculateMetrics(report.files); + const metricsResult = calculateMutationTestMetrics(report); return metricsResult; } @@ -73,7 +73,7 @@ export async function expectMetricsResult(expectedMetricsResult: Partial = {}; for (const key in expectedMetricsResult) { - actualSnippet[key as keyof MetricsResult] = actualMetricsResult[key as keyof MetricsResult] as any; + actualSnippet[key as keyof MetricsResult] = actualMetricsResult.systemUnderTestMetrics[key as keyof MetricsResult] as any; } if (actualSnippet.metrics) { if (typeof actualSnippet.metrics.mutationScore === 'number') { @@ -88,7 +88,7 @@ export async function expectMetricsResult(expectedMetricsResult: Partial) { const actualMetricsResult = await readMutationTestingJsonResult(); - expectActualMetrics(expectedMetrics, actualMetricsResult); + expectActualMetrics(expectedMetrics, actualMetricsResult.systemUnderTestMetrics); } /** @@ -96,7 +96,7 @@ export async function expectMetricsJson(expectedMetrics: Partial) { */ export async function expectMetrics(expectedMetrics: Partial) { const actualMetricsResult = await readMutationTestResult(); - expectActualMetrics(expectedMetrics, actualMetricsResult); + expectActualMetrics(expectedMetrics, actualMetricsResult.systemUnderTestMetrics); } export function expectActualMetrics(expectedMetrics: Partial, actualMetricsResult: MetricsResult) { diff --git a/e2e/package-lock.json b/e2e/package-lock.json index 62d6e528d0..6398ea3bc3 100644 --- a/e2e/package-lock.json +++ b/e2e/package-lock.json @@ -499,9 +499,9 @@ }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true } } @@ -542,9 +542,9 @@ }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true } } @@ -568,9 +568,9 @@ }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true } } @@ -594,9 +594,9 @@ }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true } } @@ -647,18 +647,18 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz", - "integrity": "sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.14.5" }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true } } @@ -1398,19 +1398,41 @@ "dev": true }, "@jest/console": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.1.tgz", - "integrity": "sha512-50E6nN2F5cAXn1lDljn0gE9F0WFXHYz/u0EeR7sOt4nbRPNli34ckbl6CUDaDABJbHt62DYnyQAIB3KgdzwKDw==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.6.tgz", + "integrity": "sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.0.1", - "jest-util": "^27.0.1", + "jest-message-util": "^27.0.6", + "jest-util": "^27.0.6", "slash": "^3.0.0" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1421,15 +1443,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1451,6 +1479,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -1469,35 +1526,35 @@ } }, "@jest/core": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.1.tgz", - "integrity": "sha512-PiCbKSMf6t8PEfY3MAd0Ldn3aJAt5T+UcaFkAfMZ1VZgas35+fXk5uHIjAQHQLNIHZWX19TLv0wWNT03yvrw6w==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.6.tgz", + "integrity": "sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==", "dev": true, "requires": { - "@jest/console": "^27.0.1", - "@jest/reporters": "^27.0.1", - "@jest/test-result": "^27.0.1", - "@jest/transform": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/console": "^27.0.6", + "@jest/reporters": "^27.0.6", + "@jest/test-result": "^27.0.6", + "@jest/transform": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.0.1", - "jest-config": "^27.0.1", - "jest-haste-map": "^27.0.1", - "jest-message-util": "^27.0.1", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.1", - "jest-resolve-dependencies": "^27.0.1", - "jest-runner": "^27.0.1", - "jest-runtime": "^27.0.1", - "jest-snapshot": "^27.0.1", - "jest-util": "^27.0.1", - "jest-validate": "^27.0.1", - "jest-watcher": "^27.0.1", + "jest-changed-files": "^27.0.6", + "jest-config": "^27.0.6", + "jest-haste-map": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.0.6", + "jest-resolve-dependencies": "^27.0.6", + "jest-runner": "^27.0.6", + "jest-runtime": "^27.0.6", + "jest-snapshot": "^27.0.6", + "jest-util": "^27.0.6", + "jest-validate": "^27.0.6", + "jest-watcher": "^27.0.6", "micromatch": "^4.0.4", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -1505,6 +1562,28 @@ "strip-ansi": "^6.0.0" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1524,15 +1603,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1563,12 +1648,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -1621,74 +1729,39 @@ } }, "@jest/environment": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.1.tgz", - "integrity": "sha512-nG+r3uSs2pOTsdhgt6lUm4ZGJLRcTc6HZIkrFsVpPcdSqEpJehEny9r9y2Bmhkn8fKXWdGCYJKF3i4nKO0HSmA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.0.1", - "@jest/types": "^27.0.1", - "@types/node": "*", - "jest-mock": "^27.0.1" - } - }, - "@jest/fake-timers": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.1.tgz", - "integrity": "sha512-3CyLJQnHzKI4TCJSCo+I9TzIHjSK4RrNEk93jFM6Q9+9WlSJ3mpMq/p2YuKMe0SiHKbmZOd5G/Ll5ofF9Xkw9g==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.6.tgz", + "integrity": "sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg==", "dev": true, "requires": { - "@jest/types": "^27.0.1", - "@sinonjs/fake-timers": "^7.0.2", + "@jest/fake-timers": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", - "jest-message-util": "^27.0.1", - "jest-mock": "^27.0.1", - "jest-util": "^27.0.1" - } - }, - "@jest/globals": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.1.tgz", - "integrity": "sha512-80ZCzgopysKdpp5EOglgjApKxiNDR96PG4PwngB4fTwZ4qqqSKo0EwGwQIhl16szQ1M2xCVYmr9J6KelvnABNQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.0.1", - "@jest/types": "^27.0.1", - "expect": "^27.0.1" - } - }, - "@jest/reporters": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.1.tgz", - "integrity": "sha512-lZbJWuS1h/ytKERfu1D6tEQ4PuQ7+15S4+HrSzHR0i7AGVT1WRo49h4fZqxASOp7AQCupUVtPJNZDkaG9ZXy0g==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.0.1", - "@jest/test-result": "^27.0.1", - "@jest/transform": "^27.0.1", - "@jest/types": "^27.0.1", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.0.1", - "jest-resolve": "^27.0.1", - "jest-util": "^27.0.1", - "jest-worker": "^27.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" + "jest-mock": "^27.0.6" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1699,9 +1772,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -1729,18 +1802,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1752,73 +1813,42 @@ } } }, - "@jest/source-map": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.1.tgz", - "integrity": "sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/test-result": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.1.tgz", - "integrity": "sha512-5aa+ibX2dsGSDLKaQMZb453MqjJU/CRVumebXfaJmuzuGE4qf87yQ2QZ6PEpEtBwVUEgrJCzi3jLCRaUbksSuw==", - "dev": true, - "requires": { - "@jest/console": "^27.0.1", - "@jest/types": "^27.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.1.tgz", - "integrity": "sha512-yK2c2iruJ35WgH4KH8whS72uH+FASJUrzwxzNKTzLAEWmNpWKNEPOsSEKsHynvz78bLHafrTg4adN7RrYNbEOA==", - "dev": true, - "requires": { - "@jest/test-result": "^27.0.1", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.1", - "jest-runner": "^27.0.1", - "jest-runtime": "^27.0.1" - } - }, - "@jest/transform": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.1.tgz", - "integrity": "sha512-LC95VpT6wMnQ96dRJDlUiAnW/90zyh4+jS30szI/5AsfS0qwSlr/O4TPcGoD2WVaVMfo6KvR+brvOtGyMHaNhA==", + "@jest/fake-timers": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.6.tgz", + "integrity": "sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.0.1", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.1", - "jest-regex-util": "^27.0.1", - "jest-util": "^27.0.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "@jest/types": "^27.0.6", + "@sinonjs/fake-timers": "^7.0.2", + "@types/node": "*", + "jest-message-util": "^27.0.6", + "jest-mock": "^27.0.6", + "jest-util": "^27.0.6" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1828,25 +1858,514 @@ "color-convert": "^2.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/globals": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.6.tgz", + "integrity": "sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw==", + "dev": true, + "requires": { + "@jest/environment": "^27.0.6", + "@jest/types": "^27.0.6", + "expect": "^27.0.6" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/reporters": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.6.tgz", + "integrity": "sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.0.6", + "@jest/test-result": "^27.0.6", + "@jest/transform": "^27.0.6", + "@jest/types": "^27.0.6", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.0.6", + "jest-resolve": "^27.0.6", + "jest-util": "^27.0.6", + "jest-worker": "^27.0.6", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.6.tgz", + "integrity": "sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w==", + "dev": true, + "requires": { + "@jest/console": "^27.0.6", + "@jest/types": "^27.0.6", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/test-sequencer": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz", + "integrity": "sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA==", + "dev": true, + "requires": { + "@jest/test-result": "^27.0.6", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.0.6", + "jest-runtime": "^27.0.6" + } + }, + "@jest/transform": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.6.tgz", + "integrity": "sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.0.6", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.0.6", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.0.6", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1877,12 +2396,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -2014,9 +2556,9 @@ } }, "@sinonjs/fake-timers": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.1.tgz", - "integrity": "sha512-am34LJf0N2nON/PT9G7pauA+xjcwX9P6x31m4hBgfUeSXYRZBRv/R6EcdWs8iV4XJjPO++NTsrj7ua/cN2s6ZA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", + "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" @@ -2029,9 +2571,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.14", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", - "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "version": "7.1.15", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", + "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -2042,18 +2584,18 @@ } }, "@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -2061,9 +2603,9 @@ } }, "@types/babel__traverse": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", - "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -2133,9 +2675,9 @@ "dev": true }, "@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", "dev": true }, "@types/semver": { @@ -2419,9 +2961,9 @@ }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -2734,21 +3276,43 @@ } }, "babel-jest": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.1.tgz", - "integrity": "sha512-aWFD7OGQjk3Y8MdZKf1XePlQvHnjMVJQjIq9WKrlAjz9by703kJ45Jxhp26JwnovoW71YYz5etuqRl8wMcIv0w==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.6.tgz", + "integrity": "sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA==", "dev": true, "requires": { - "@jest/transform": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/transform": "^27.0.6", + "@jest/types": "^27.0.6", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.0.1", + "babel-preset-jest": "^27.0.6", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2759,9 +3323,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -2829,9 +3393,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz", - "integrity": "sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz", + "integrity": "sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -2861,12 +3425,12 @@ } }, "babel-preset-jest": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz", - "integrity": "sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz", + "integrity": "sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.0.1", + "babel-plugin-jest-hoist": "^27.0.6", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -3423,9 +3987,9 @@ } }, "cjs-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz", - "integrity": "sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "class-transformer": { @@ -4015,9 +4579,9 @@ "dev": true }, "diff-sequences": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", - "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true }, "diffie-hellman": { @@ -4412,9 +4976,9 @@ } }, "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -4522,24 +5086,97 @@ } }, "expect": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.1.tgz", - "integrity": "sha512-hjKwLeAvKUiq0Plha1dmzOH1FGEwJC9njbT993cq4PK9r58/+3NM+WDqFVGcPuRH7XTjmbIeHQBzp2faDrPhjQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz", + "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.1", - "jest-matcher-utils": "^27.0.1", - "jest-message-util": "^27.0.1", - "jest-regex-util": "^27.0.1" + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-regex-util": "^27.0.6" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -5560,9 +6197,9 @@ }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -5604,9 +6241,9 @@ }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -6034,9 +6671,9 @@ }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -6083,16 +6720,177 @@ "dev": true }, "jest": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.1.tgz", - "integrity": "sha512-lFEoUdXjbGAIxk/gZhcv98xOaH1hjqG5R/PQHs5GBfIK5iL3tnXCjHQf4HQLVZZ2rcXML3oeVg9+XrRZbooBdQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.6.tgz", + "integrity": "sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==", "dev": true, "requires": { - "@jest/core": "^27.0.1", + "@jest/core": "^27.0.6", "import-local": "^3.0.2", - "jest-cli": "^27.0.1" + "jest-cli": "^27.0.6" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-cli": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.6.tgz", + "integrity": "sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==", + "dev": true, + "requires": { + "@jest/core": "^27.0.6", + "@jest/test-result": "^27.0.6", + "@jest/types": "^27.0.6", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.0.6", + "jest-util": "^27.0.6", + "jest-validate": "^27.0.6", + "prompts": "^2.0.1", + "yargs": "^16.0.3" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-changed-files": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.6.tgz", + "integrity": "sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "execa": "^5.0.0", + "throat": "^6.0.1" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -6103,9 +6901,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -6133,26 +6931,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "jest-cli": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.1.tgz", - "integrity": "sha512-plDsQQwpkKK1SZ5L5xqMa7v/sTwB5LTIeSJqb+cV+4EMlThdUQfg8jwMfHX8jHuUc9TPGLcdoZeBuZcGGn3Rlg==", - "dev": true, - "requires": { - "@jest/core": "^27.0.1", - "@jest/test-result": "^27.0.1", - "@jest/types": "^27.0.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.0.1", - "jest-util": "^27.0.1", - "jest-validate": "^27.0.1", - "prompts": "^2.0.1", - "yargs": "^16.0.3" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6164,44 +6942,55 @@ } } }, - "jest-changed-files": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.1.tgz", - "integrity": "sha512-Y/4AnqYNcUX/vVgfkmvSA3t7rcg+t8m3CsSGlU+ra8kjlVW5ZqXcBZY/NUew2Mo8M+dn0ApKl+FmGGT1JV5dVA==", - "dev": true, - "requires": { - "@jest/types": "^27.0.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, "jest-circus": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.1.tgz", - "integrity": "sha512-Tz3ytmrsgxWlTwSyPYb8StF9J2IMjLlbBMKAjhL2UU9/0ZpYb2JiEGjXaAhnGauQRbbpyFbSH3yj5HIbdurmwQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.6.tgz", + "integrity": "sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q==", "dev": true, "requires": { - "@jest/environment": "^27.0.1", - "@jest/test-result": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/environment": "^27.0.6", + "@jest/test-result": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^27.0.1", + "expect": "^27.0.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.0.1", - "jest-matcher-utils": "^27.0.1", - "jest-message-util": "^27.0.1", - "jest-runner": "^27.0.1", - "jest-runtime": "^27.0.1", - "jest-snapshot": "^27.0.1", - "jest-util": "^27.0.1", - "pretty-format": "^27.0.1", + "jest-each": "^27.0.6", + "jest-matcher-utils": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-runtime": "^27.0.6", + "jest-snapshot": "^27.0.6", + "jest-util": "^27.0.6", + "pretty-format": "^27.0.6", + "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -6212,15 +7001,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6242,6 +7037,41 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6254,33 +7084,56 @@ } }, "jest-config": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.1.tgz", - "integrity": "sha512-V8O6+CZjGF0OMq4kxVR29ztV/LQqlAAcJLw7a94RndfRXkha4U84n50yZCXiPWtAHHTmb3g1y52US6rGPxA+3w==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.6.tgz", + "integrity": "sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.0.1", - "@jest/types": "^27.0.1", - "babel-jest": "^27.0.1", + "@jest/test-sequencer": "^27.0.6", + "@jest/types": "^27.0.6", + "babel-jest": "^27.0.6", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", "is-ci": "^3.0.0", - "jest-circus": "^27.0.1", - "jest-environment-jsdom": "^27.0.1", - "jest-environment-node": "^27.0.1", - "jest-get-type": "^27.0.1", - "jest-jasmine2": "^27.0.1", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.1", - "jest-util": "^27.0.1", - "jest-validate": "^27.0.1", + "jest-circus": "^27.0.6", + "jest-environment-jsdom": "^27.0.6", + "jest-environment-node": "^27.0.6", + "jest-get-type": "^27.0.6", + "jest-jasmine2": "^27.0.6", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.0.6", + "jest-runner": "^27.0.6", + "jest-util": "^27.0.6", + "jest-validate": "^27.0.6", "micromatch": "^4.0.4", - "pretty-format": "^27.0.1" + "pretty-format": "^27.0.6" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -6300,9 +7153,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -6360,6 +7213,20 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -6397,15 +7264,15 @@ } }, "jest-diff": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.1.tgz", - "integrity": "sha512-DQ3OgfJgoGWVTYo4qnYW/Jg5mpYFS2QW9BLxA8bs12ZRN1K8QPZtWeYvUPohQFs3CHX3JLTndGg3jyxdL5THFQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz", + "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.1", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.1" + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" }, "dependencies": { "ansi-styles": { @@ -6418,9 +7285,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -6460,27 +7327,49 @@ } }, "jest-docblock": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.1.tgz", - "integrity": "sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.1.tgz", - "integrity": "sha512-uJTK/aZ05HsdKkfXucAT5+/1DIURnTRv34OSxn1HWHrD+xu9eDX5Xgds09QSvg/mU01VS5upuHTDKG3W+r0rQA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.6.tgz", + "integrity": "sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "chalk": "^4.0.0", - "jest-get-type": "^27.0.1", - "jest-util": "^27.0.1", - "pretty-format": "^27.0.1" + "jest-get-type": "^27.0.6", + "jest-util": "^27.0.6", + "pretty-format": "^27.0.6" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -6491,15 +7380,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6521,6 +7416,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6533,20 +7457,42 @@ } }, "jest-environment-jsdom": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.1.tgz", - "integrity": "sha512-lesU8T9zkjgLaLpUFmFDgchu6/2OCoXm52nN6UumR063Hb+1TJdI7ihgM86+G01Ay86Lyr+K/FAR6yIIOviH3Q==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz", + "integrity": "sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw==", "dev": true, "requires": { - "@jest/environment": "^27.0.1", - "@jest/fake-timers": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/environment": "^27.0.6", + "@jest/fake-timers": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", - "jest-mock": "^27.0.1", - "jest-util": "^27.0.1", + "jest-mock": "^27.0.6", + "jest-util": "^27.0.6", "jsdom": "^16.6.0" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -6554,15 +7500,55 @@ "dev": true }, "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, "escodegen": { @@ -6595,16 +7581,45 @@ "mime-types": "^2.1.12" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, "is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, "jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { "abab": "^2.0.5", @@ -6632,7 +7647,7 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.5", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" } }, @@ -6642,12 +7657,27 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "optional": true + "optional": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } }, "tough-cookie": { "version": "4.0.0", @@ -6660,21 +7690,30 @@ "universalify": "^0.1.2" } }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, "whatwg-url": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", - "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "requires": { "lodash": "^4.7.0", - "tr46": "^2.0.2", + "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" } }, "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", "dev": true } } @@ -6889,46 +7928,185 @@ } }, "jest-environment-node": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.1.tgz", - "integrity": "sha512-/p94lo0hx+hbKUw1opnRFUPPsjncRBEUU+2Dh7BuxX8Nr4rRiTivLYgXzo79FhaeMYV0uiV5WAbHBq6xC11JJg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.6.tgz", + "integrity": "sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w==", "dev": true, "requires": { - "@jest/environment": "^27.0.1", - "@jest/fake-timers": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/environment": "^27.0.6", + "@jest/fake-timers": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", - "jest-mock": "^27.0.1", - "jest-util": "^27.0.1" + "jest-mock": "^27.0.6", + "jest-util": "^27.0.6" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-get-type": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", - "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, "jest-haste-map": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.1.tgz", - "integrity": "sha512-ioCuobr4z90H1Pz8+apz2vfz63387apzAoawm/9IIOndarDfRkjLURdLOe//AI5jUQmjVRg+WiL92339kqlCmA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.6.tgz", + "integrity": "sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.1", - "jest-serializer": "^27.0.1", - "jest-util": "^27.0.1", - "jest-worker": "^27.0.1", + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.0.6", + "jest-worker": "^27.0.6", "micromatch": "^4.0.4", "walker": "^1.0.7" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -6948,6 +8126,37 @@ "fill-range": "^7.0.1" } }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -6964,12 +8173,49 @@ "dev": true, "optional": true }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + }, + "dependencies": { + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + } + } + }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -6988,6 +8234,15 @@ } } }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7000,31 +8255,53 @@ } }, "jest-jasmine2": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.1.tgz", - "integrity": "sha512-o8Ist0o970QDDm/R2o9UDbvNxq8A0++FTFQ0z9OnieJwS1nDH6H7WBDYAGPTdmnla7kbW41oLFPvhmjJE4mekg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz", + "integrity": "sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.0.1", - "@jest/source-map": "^27.0.1", - "@jest/test-result": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/environment": "^27.0.6", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^27.0.1", + "expect": "^27.0.6", "is-generator-fn": "^2.0.0", - "jest-each": "^27.0.1", - "jest-matcher-utils": "^27.0.1", - "jest-message-util": "^27.0.1", - "jest-runtime": "^27.0.1", - "jest-snapshot": "^27.0.1", - "jest-util": "^27.0.1", - "pretty-format": "^27.0.1", + "jest-each": "^27.0.6", + "jest-matcher-utils": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-runtime": "^27.0.6", + "jest-snapshot": "^27.0.6", + "jest-util": "^27.0.6", + "pretty-format": "^27.0.6", "throat": "^6.0.1" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7035,15 +8312,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7065,6 +8348,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7077,25 +8389,25 @@ } }, "jest-leak-detector": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.1.tgz", - "integrity": "sha512-SQ/lRhfmnV3UuiaKIjwNXCaW2yh1rTMAL4n4Cl4I4gU0X2LoIc6Ogxe4UKM/J6Ld2uzc4gDGVYc5lSdpf6WjYw==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz", + "integrity": "sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ==", "dev": true, "requires": { - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.1" + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" } }, "jest-matcher-utils": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.1.tgz", - "integrity": "sha512-NauNU+olKhPzLlsRnTOYFGk/MK5QFYl9ZzkrtfsY4eCq4SB3Bcl03UL44VdnlN5S/uFn4H2jwvRY1y6nSDTX3g==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz", + "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.0.1", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.1" + "jest-diff": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" }, "dependencies": { "ansi-styles": { @@ -7107,10 +8419,10 @@ "color-convert": "^2.0.1" } }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -7150,44 +8462,44 @@ } }, "jest-message-util": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.1.tgz", - "integrity": "sha512-w8BfON2GwWORkos8BsxcwwQrLkV2s1ENxSRXK43+6yuquDE2hVxES/jrFqOArpP1ETVqqMmktU6iGkG8ncVzeA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz", + "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.0.1", + "pretty-format": "^27.0.6", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" } }, "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", "dev": true }, "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -7205,12 +8517,34 @@ } } }, + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -7221,9 +8555,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -7320,13 +8654,86 @@ } }, "jest-mock": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.1.tgz", - "integrity": "sha512-fXCSZQDT5hUcAUy8OBnB018x7JFOMQnz4XfpSKEbfpWzL6o5qaLRhgf2Qg2NPuVKmC/fgOf33Edj8wjF4I24CQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.6.tgz", + "integrity": "sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "@types/node": "*" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-pnp-resolver": { @@ -7336,27 +8743,50 @@ "dev": true }, "jest-regex-util": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz", - "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", "dev": true }, "jest-resolve": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.1.tgz", - "integrity": "sha512-Q7QQ0OZ7z6D5Dul0MrsexlKalU8ZwexBfHLSu1qYPgphvUm6WO1b/xUnipU3e+uW1riDzMcJeJVYbdQ37hBHeg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.6.tgz", + "integrity": "sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "chalk": "^4.0.0", "escalade": "^3.1.1", "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.0.1", + "jest-util": "^27.0.6", + "jest-validate": "^27.0.6", "resolve": "^1.20.0", "slash": "^3.0.0" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7367,15 +8797,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7397,6 +8833,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -7425,45 +8890,141 @@ } }, "jest-resolve-dependencies": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.1.tgz", - "integrity": "sha512-ly1x5mEf21f3IVWbUNwIz/ePLtv4QdhYuQIVSVDqxx7yzAwhhdu0DJo7UNiEYKQY7Im48wfbNdOUpo7euFUXBQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz", + "integrity": "sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA==", "dev": true, "requires": { - "@jest/types": "^27.0.1", - "jest-regex-util": "^27.0.1", - "jest-snapshot": "^27.0.1" + "@jest/types": "^27.0.6", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.0.6" + }, + "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-runner": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.1.tgz", - "integrity": "sha512-DUNizlD2D7J80G3VOrwfbtb7KYxiftMng82HNcKwTW0W3AwwNuBeq+1exoCnLO7Mxh7NP+k/1XQBlzLpjr/CnA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.6.tgz", + "integrity": "sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ==", "dev": true, "requires": { - "@jest/console": "^27.0.1", - "@jest/environment": "^27.0.1", - "@jest/test-result": "^27.0.1", - "@jest/transform": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/console": "^27.0.6", + "@jest/environment": "^27.0.6", + "@jest/test-result": "^27.0.6", + "@jest/transform": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^27.0.1", - "jest-docblock": "^27.0.1", - "jest-haste-map": "^27.0.1", - "jest-leak-detector": "^27.0.1", - "jest-message-util": "^27.0.1", - "jest-resolve": "^27.0.1", - "jest-runtime": "^27.0.1", - "jest-util": "^27.0.1", - "jest-worker": "^27.0.1", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.0.6", + "jest-environment-node": "^27.0.6", + "jest-haste-map": "^27.0.6", + "jest-leak-detector": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-resolve": "^27.0.6", + "jest-runtime": "^27.0.6", + "jest-util": "^27.0.6", + "jest-worker": "^27.0.6", "source-map-support": "^0.5.6", "throat": "^6.0.1" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7474,34 +9035,69 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "~1.1.4" + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "supports-color": { @@ -7516,19 +9112,19 @@ } }, "jest-runtime": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.1.tgz", - "integrity": "sha512-ImcrbQtpCUp8X9Rm4ky3j1GG9cqIKZJvXGZyB5cHEapGPTmg7wvvNooLmKragEe61/p/bhw1qO68Y0/9BSsBBg==", - "dev": true, - "requires": { - "@jest/console": "^27.0.1", - "@jest/environment": "^27.0.1", - "@jest/fake-timers": "^27.0.1", - "@jest/globals": "^27.0.1", - "@jest/source-map": "^27.0.1", - "@jest/test-result": "^27.0.1", - "@jest/transform": "^27.0.1", - "@jest/types": "^27.0.1", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.6.tgz", + "integrity": "sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q==", + "dev": true, + "requires": { + "@jest/console": "^27.0.6", + "@jest/environment": "^27.0.6", + "@jest/fake-timers": "^27.0.6", + "@jest/globals": "^27.0.6", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.0.6", + "@jest/transform": "^27.0.6", + "@jest/types": "^27.0.6", "@types/yargs": "^16.0.0", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", @@ -7536,23 +9132,36 @@ "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.0.1", - "jest-message-util": "^27.0.1", - "jest-mock": "^27.0.1", - "jest-regex-util": "^27.0.1", - "jest-resolve": "^27.0.1", - "jest-snapshot": "^27.0.1", - "jest-util": "^27.0.1", - "jest-validate": "^27.0.1", + "jest-haste-map": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-mock": "^27.0.6", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.0.6", + "jest-snapshot": "^27.0.6", + "jest-util": "^27.0.6", + "jest-validate": "^27.0.6", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^16.0.3" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, "@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -7568,15 +9177,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7598,6 +9213,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7622,9 +9266,9 @@ } }, "jest-serializer": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.1.tgz", - "integrity": "sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", "dev": true, "requires": { "@types/node": "*", @@ -7632,9 +9276,9 @@ } }, "jest-snapshot": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.1.tgz", - "integrity": "sha512-HgKmSebDB3rswugREeh+nKrxJEVZE12K7lZ2MuwfFZT6YmiH0TlofsL2YmiLsCsG5KH5ZcLYYpF5bDrvtVx/Xg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.6.tgz", + "integrity": "sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A==", "dev": true, "requires": { "@babel/core": "^7.7.2", @@ -7643,26 +9287,48 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/transform": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/transform": "^27.0.6", + "@jest/types": "^27.0.6", "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.0.1", + "expect": "^27.0.6", "graceful-fs": "^4.2.4", - "jest-diff": "^27.0.1", - "jest-get-type": "^27.0.1", - "jest-haste-map": "^27.0.1", - "jest-matcher-utils": "^27.0.1", - "jest-message-util": "^27.0.1", - "jest-resolve": "^27.0.1", - "jest-util": "^27.0.1", + "jest-diff": "^27.0.6", + "jest-get-type": "^27.0.6", + "jest-haste-map": "^27.0.6", + "jest-matcher-utils": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-resolve": "^27.0.6", + "jest-util": "^27.0.6", "natural-compare": "^1.4.0", - "pretty-format": "^27.0.1", + "pretty-format": "^27.0.6", "semver": "^7.3.2" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7673,15 +9339,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7703,6 +9375,29 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7712,6 +9407,12 @@ "yallist": "^4.0.0" } }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -7825,19 +9526,41 @@ } }, "jest-validate": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.1.tgz", - "integrity": "sha512-zvmPRcfTkqTZuHveIKAI2nbkUc3SDXjWVJULknPLGF5bdxOGSeGZg7f/Uw0MUVOkCOaspcHnsPCgZG0pqmg71g==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.6.tgz", + "integrity": "sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.0.1", + "jest-get-type": "^27.0.6", "leven": "^3.1.0", - "pretty-format": "^27.0.1" + "pretty-format": "^27.0.6" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7854,9 +9577,9 @@ "dev": true }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -7896,20 +9619,42 @@ } }, "jest-watcher": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.1.tgz", - "integrity": "sha512-Chp9c02BN0IgEbtGreyAhGqIsOrn9a0XnzbuXOxdW1+cW0Tjh12hMzHDIdLFHpYP/TqaMTmPHaJ5KWvpCCrNFw==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.6.tgz", + "integrity": "sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ==", "dev": true, "requires": { - "@jest/test-result": "^27.0.1", - "@jest/types": "^27.0.1", + "@jest/test-result": "^27.0.6", + "@jest/types": "^27.0.6", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.0.1", + "jest-util": "^27.0.6", "string-length": "^4.0.1" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7920,15 +9665,21 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7950,6 +9701,35 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "jest-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz", + "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==", + "dev": true, + "requires": { + "@jest/types": "^27.0.6", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7962,9 +9742,9 @@ } }, "jest-worker": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.1.tgz", - "integrity": "sha512-NhHqClI3owOjmS8dBhQMKHZ2rrT0sBTpqGitp9nMX5AAjVXd+15o4v96uBEMhoywaLKN+5opcKBlXwAoADZolA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz", + "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==", "dev": true, "requires": { "@types/node": "*", @@ -9987,22 +11767,95 @@ "dev": true }, "pretty-format": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.1.tgz", - "integrity": "sha512-qE+0J6c/gd+R6XTcQgPJMc5hMJNsxzSF5p8iZSbMZ7GQzYGlSLNkh2P80Wa2dbF4gEVUsJEgcrBY+1L2/j265w==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz", + "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==", "dev": true, "requires": { - "@jest/types": "^27.0.1", + "@jest/types": "^27.0.6", "ansi-regex": "^5.0.0", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { + "@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -11979,9 +13832,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", + "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", diff --git a/e2e/package.json b/e2e/package.json index 0a52948eb3..a3715f4ff3 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -20,7 +20,7 @@ "grunt": "~1.3.0", "jasmine": "~3.6.2", "jasmine-core": "~3.6.0", - "jest": "~27.0.1", + "jest": "^27.0.6", "jest-environment-jsdom-sixteen": "^1.0.3", "karma": "~6.0.1", "karma-chai": "~0.1.0", diff --git a/e2e/test/disable-bail/.mocharc.json b/e2e/test/disable-bail/.mocharc.json new file mode 100644 index 0000000000..a17ebe5b50 --- /dev/null +++ b/e2e/test/disable-bail/.mocharc.json @@ -0,0 +1,3 @@ +{ + "require": ["test/chai-setup.js"] +} diff --git a/e2e/test/disable-bail/cucumber.js b/e2e/test/disable-bail/cucumber.js new file mode 100644 index 0000000000..dbb7402cca --- /dev/null +++ b/e2e/test/disable-bail/cucumber.js @@ -0,0 +1 @@ +module.exports = { default: '--publish-quiet' }; diff --git a/e2e/test/disable-bail/features/add.feature b/e2e/test/disable-bail/features/add.feature new file mode 100644 index 0000000000..2e47c6381a --- /dev/null +++ b/e2e/test/disable-bail/features/add.feature @@ -0,0 +1,9 @@ +Feature: Add + +Scenario: Add 40 and 2 +When I add 40 and 2 +Then I get 42 + +Scenario: Add 41 and 1 +When I add 41 and 1 +Then I get 42 \ No newline at end of file diff --git a/e2e/test/disable-bail/features/add.steps.js b/e2e/test/disable-bail/features/add.steps.js new file mode 100644 index 0000000000..f0bd3c6531 --- /dev/null +++ b/e2e/test/disable-bail/features/add.steps.js @@ -0,0 +1,11 @@ +const { When, Then } = require('@cucumber/cucumber'); +const { add } = require('../src/math'); +const { expect } = require('chai'); + +When('I add {int} and {int}', function (n, n2) { + this.result = add(n, n2); +}); + +Then('I get {int}', function (expected) { + expect(this.result).eq(expected); +}); diff --git a/e2e/test/disable-bail/karma.conf.js b/e2e/test/disable-bail/karma.conf.js new file mode 100644 index 0000000000..bc248c86b4 --- /dev/null +++ b/e2e/test/disable-bail/karma.conf.js @@ -0,0 +1,15 @@ +module.exports = function(config) { + config.set({ + frameworks: ['jasmine'], + files: [ + 'src/*.js', + 'test/math.spec.js' + ], + reporters: ['progress'], + colors: true, + autoWatch: false, + browsers: ['ChromeHeadless'], + singleRun: true, + concurrency: Infinity + }); +} diff --git a/e2e/test/disable-bail/package.json b/e2e/test/disable-bail/package.json new file mode 100644 index 0000000000..484f41bcea --- /dev/null +++ b/e2e/test/disable-bail/package.json @@ -0,0 +1,17 @@ +{ + "name": "disable-bail", + "version": "1.0.0", + "description": "A e2e test for --disableBail", + "main": "index.js", + "scripts": { + "test:cucumber": "cucumber-js", + "test:mocha": "mocha", + "test:jasmine": "jasmine", + "test:karma": "karma start", + "test:jest": "jest", + "test": "mocha --no-config --no-timeout --require ../../tasks/ts-node-register.js verify/*.ts" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/e2e/test/disable-bail/spec/support/jasmine.json b/e2e/test/disable-bail/spec/support/jasmine.json new file mode 100644 index 0000000000..67fbf562e7 --- /dev/null +++ b/e2e/test/disable-bail/spec/support/jasmine.json @@ -0,0 +1,8 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "../test/*.spec.js" + ], + "stopSpecOnExpectationFailure": false, + "random": true +} diff --git a/e2e/test/disable-bail/src/math.js b/e2e/test/disable-bail/src/math.js new file mode 100644 index 0000000000..7cba9ec27f --- /dev/null +++ b/e2e/test/disable-bail/src/math.js @@ -0,0 +1,8 @@ +{ + const add = (a, b) => a + b; + + globalThis.add = add; + if (typeof exports === 'object') { + exports.add = add; + } +} diff --git a/e2e/test/disable-bail/stryker.conf.json b/e2e/test/disable-bail/stryker.conf.json new file mode 100644 index 0000000000..0b487b1af3 --- /dev/null +++ b/e2e/test/disable-bail/stryker.conf.json @@ -0,0 +1,9 @@ +{ + "$schema": "../../node_modules/@stryker-mutator/core/schema/stryker-schema.json", + "concurrency": 1, + "reporters": ["json"], + "disableBail": true, + "karma": { + "configFile": "karma.conf.js" + } +} diff --git a/e2e/test/disable-bail/test/chai-setup.js b/e2e/test/disable-bail/test/chai-setup.js new file mode 100644 index 0000000000..38e9e0f335 --- /dev/null +++ b/e2e/test/disable-bail/test/chai-setup.js @@ -0,0 +1,6 @@ +const chai = require('chai'); + +chai.util.addMethod(chai.Assertion.prototype, 'toEqual', function (expected) { + var obj = chai.util.flag(this, 'object'); + new chai.Assertion(obj).to.deep.equal(expected); +}); diff --git a/e2e/test/disable-bail/test/math.spec.js b/e2e/test/disable-bail/test/math.spec.js new file mode 100644 index 0000000000..7bfcff0d29 --- /dev/null +++ b/e2e/test/disable-bail/test/math.spec.js @@ -0,0 +1,17 @@ +let add = globalThis.add; +if (typeof require === 'function') { + add = require('../src/math').add; +} +if(typeof expect === 'undefined'){ + globalThis.expect = require('chai').expect; +} + +describe(add.name, () => { + // Both tests kill the same mutant, necessary to test disableBail + it('should result in 42 for 40 and 2', () => { + expect(add(40, 2)).toEqual(42); + }); + it('should result in 42 for 41 and 1', () => { + expect(add(41, 1)).toEqual(42); + }); +}); diff --git a/e2e/test/disable-bail/verify/verify.ts b/e2e/test/disable-bail/verify/verify.ts new file mode 100644 index 0000000000..4c5dc38104 --- /dev/null +++ b/e2e/test/disable-bail/verify/verify.ts @@ -0,0 +1,45 @@ +import fs from 'fs'; + +import { readMutationTestingJsonResult, execStryker} from '../../../helpers'; +import { expect } from 'chai'; + +describe('disableBail', () => { + + beforeEach(async () => { + await fs.promises.rm('reports', { recursive: true, force: true }) + }) + + it('should be supported in the jest runner', async () => { + execStryker('stryker run --testRunner jest'); + await assertBailWasDisabled(); + }); + + it('should be supported in the karma runner', async () => { + execStryker('stryker run --testRunner karma'); + await assertBailWasDisabled(); + }); + + it('should be supported in the jasmine runner', async () => { + execStryker('stryker run --testRunner jasmine'); + await assertBailWasDisabled(); + }); + + it('should be supported in the mocha runner', async () => { + execStryker('stryker run --testRunner mocha'); + await assertBailWasDisabled(); + }); + + it('should be supported in the cucumber runner', async () => { + execStryker('stryker run --testRunner cucumber'); + await assertBailWasDisabled(['Feature: Add -- Scenario: Add 40 and 2', 'Feature: Add -- Scenario: Add 41 and 1']); + }); +}); + +async function assertBailWasDisabled([killedByName1, killedByName2] = ['add should result in 42 for 40 and 2', 'add should result in 42 for 41 and 1']) { + const result = await readMutationTestingJsonResult(); + const theMutant = result.systemUnderTestMetrics.childResults[0].file.mutants.find(mutant => mutant.replacement === 'a - b'); + expect(theMutant.killedByTests).lengthOf(2); + expect(theMutant.killedByTests[0].name).eq(killedByName1); + expect(theMutant.killedByTests[1].name).eq(killedByName2); +} + diff --git a/e2e/test/ignore-project/verify/verify.ts b/e2e/test/ignore-project/verify/verify.ts index 8c9374f904..484b599581 100644 --- a/e2e/test/ignore-project/verify/verify.ts +++ b/e2e/test/ignore-project/verify/verify.ts @@ -20,7 +20,7 @@ describe('After running stryker on jest-react project', () => { it('should report mutants that are disabled by a comment with correct ignore reason', async () => { const actualMetricsResult = await readMutationTestingJsonResult(); - const addResult = actualMetricsResult.childResults.find(file => file.name.endsWith('Add.js')).file!; + const addResult = actualMetricsResult.systemUnderTestMetrics.childResults.find(file => file.name.endsWith('Add.js')).file!; const mutantsAtLine31 = addResult.mutants.filter(({ location }) => location.start.line === 31) const booleanLiteralMutants = mutantsAtLine31.filter(({mutatorName}) => mutatorName === 'BooleanLiteral'); const conditionalExpressionMutants = mutantsAtLine31.filter(({mutatorName}) => mutatorName === 'ConditionalExpression'); @@ -41,7 +41,7 @@ describe('After running stryker on jest-react project', () => { it('should report mutants that result from excluded mutators with the correct ignore reason', async () => { const actualMetricsResult = await readMutationTestingJsonResult(); - const circleResult = actualMetricsResult.childResults.find(file => file.name.endsWith('Circle.js')).file!; + const circleResult = actualMetricsResult.systemUnderTestMetrics.childResults.find(file => file.name.endsWith('Circle.js')).file!; const mutantsAtLine3 = circleResult.mutants.filter(({ location }) => location.start.line === 3) mutantsAtLine3.forEach((mutant) => { diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index d9e97e0356..51f041ef25 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -456,6 +456,11 @@ } ], "description": "Enable or disable certain warnings" + }, + "disableBail": { + "description": "Disables the default of bailing after first failing test. When true runs all tests covering a mutant. Useful when the subject under test is not completely isolated by mocks and you want to know which tests are killing the mutants. This will impact performance.", + "type": "boolean", + "default": false } } } diff --git a/packages/api/src/test-runner/mutant-run-result.ts b/packages/api/src/test-runner/mutant-run-result.ts index 444f426933..e22aaab9cc 100644 --- a/packages/api/src/test-runner/mutant-run-result.ts +++ b/packages/api/src/test-runner/mutant-run-result.ts @@ -18,11 +18,11 @@ export interface TimeoutMutantRunResult { export interface KilledMutantRunResult { status: MutantRunStatus.Killed; /** - * The id of the test that killed this mutant + * An array with the ids of the tests that killed this mutant */ - killedBy: string; + killedBy: string[] | string; /** - * The failure message that was reported by the test + * The failure message that was reported by first the test */ failureMessage: string; /** diff --git a/packages/api/src/test-runner/run-options.ts b/packages/api/src/test-runner/run-options.ts index 35371cfca4..94604fa027 100644 --- a/packages/api/src/test-runner/run-options.ts +++ b/packages/api/src/test-runner/run-options.ts @@ -5,6 +5,10 @@ export interface RunOptions { * The amount of time (in milliseconds) the TestRunner has to complete the test run before a timeout occurs. */ timeout: number; + /** + * Filled from disableBail in config + */ + disableBail: boolean; } export interface DryRunOptions extends RunOptions { diff --git a/packages/api/src/test-runner/run-result-helpers.ts b/packages/api/src/test-runner/run-result-helpers.ts index 792c5daf85..cbd043501c 100644 --- a/packages/api/src/test-runner/run-result-helpers.ts +++ b/packages/api/src/test-runner/run-result-helpers.ts @@ -11,16 +11,17 @@ export function determineHitLimitReached(hitCount: number | undefined, hitLimit: return; } -export function toMutantRunResult(dryRunResult: DryRunResult): MutantRunResult { +export function toMutantRunResult(dryRunResult: DryRunResult, reportAllKillers = false): MutantRunResult { switch (dryRunResult.status) { case DryRunStatus.Complete: { - const killedBy = dryRunResult.tests.find((test): test is FailedTestResult => test.status === TestStatus.Failed); + const failedTests = dryRunResult.tests.filter((test): test is FailedTestResult => test.status === TestStatus.Failed); const nrOfTests = dryRunResult.tests.filter((test) => test.status !== TestStatus.Skipped).length; - if (killedBy) { + + if (failedTests.length > 0) { return { status: MutantRunStatus.Killed, - failureMessage: killedBy.failureMessage, - killedBy: killedBy.id, + failureMessage: failedTests[0].failureMessage, + killedBy: reportAllKillers ? failedTests.map((test) => test.id) : failedTests[0].id, nrOfTests, }; } else { diff --git a/packages/api/test/unit/test_runner/run-result-helpers.spec.ts b/packages/api/test/unit/test_runner/run-result-helpers.spec.ts index d35dbd25ce..a0b1c11fcd 100644 --- a/packages/api/test/unit/test_runner/run-result-helpers.spec.ts +++ b/packages/api/test/unit/test_runner/run-result-helpers.spec.ts @@ -36,13 +36,41 @@ describe('runResultHelpers', () => { expect(actual).deep.eq(expected); }); - it('should report a failed test as "killed"', () => { - const expected: MutantRunResult = { status: MutantRunStatus.Killed, failureMessage: 'expected foo to be bar', killedBy: '42', nrOfTests: 3 }; + it('should report all failed tests as "killed" when given the option', () => { + const expected: MutantRunResult = { + status: MutantRunStatus.Killed, + failureMessage: 'expected foo to be bar', + killedBy: ['42', '43'], + nrOfTests: 4, + }; + const actual = toMutantRunResult( + { + status: DryRunStatus.Complete, + tests: [ + { status: TestStatus.Success, id: 'success1', name: 'success1', timeSpentMs: 42 }, + { status: TestStatus.Failed, id: '42', name: 'error', timeSpentMs: 42, failureMessage: 'expected foo to be bar' }, + { status: TestStatus.Failed, id: '43', name: 'error', timeSpentMs: 42, failureMessage: 'expected this to be that' }, + { status: TestStatus.Success, id: 'success2', name: 'success2', timeSpentMs: 42 }, + ], + }, + true + ); + expect(actual).deep.eq(expected); + }); + + it('should report a single tests as "killed" by default', () => { + const expected: MutantRunResult = { + status: MutantRunStatus.Killed, + failureMessage: 'expected foo to be bar', + killedBy: '42', + nrOfTests: 4, + }; const actual = toMutantRunResult({ status: DryRunStatus.Complete, tests: [ { status: TestStatus.Success, id: 'success1', name: 'success1', timeSpentMs: 42 }, { status: TestStatus.Failed, id: '42', name: 'error', timeSpentMs: 42, failureMessage: 'expected foo to be bar' }, + { status: TestStatus.Failed, id: '43', name: 'error', timeSpentMs: 42, failureMessage: 'expected this to be that' }, { status: TestStatus.Success, id: 'success2', name: 'success2', timeSpentMs: 42 }, ], }); diff --git a/packages/core/src/config/options-validator.ts b/packages/core/src/config/options-validator.ts index 8170eb2c8b..75fd8615b7 100644 --- a/packages/core/src/config/options-validator.ts +++ b/packages/core/src/config/options-validator.ts @@ -87,6 +87,16 @@ export class OptionsValidator { const existingIgnorePatterns = Array.isArray(rawOptions[ignorePatternsName]) ? (rawOptions[ignorePatternsName] as unknown[]) : []; rawOptions[ignorePatternsName] = [...newIgnorePatterns, ...existingIgnorePatterns]; } + // @ts-expect-error jest.enableBail + if (rawOptions.jest?.enableBail !== undefined) { + this.log.warn( + 'DEPRECATED. Use of "jest.enableBail" inside deprecated, please use "disableBail" instead. See https://stryker-mutator.io/docs/stryker-js/configuration#disablebail-boolean' + ); + // @ts-expect-error jest.enableBail + rawOptions.disableBail = !rawOptions.jest?.enableBail; + // @ts-expect-error jest.enableBail + delete rawOptions.jest.enableBail; + } } private additionalValidation(options: StrykerOptions) { diff --git a/packages/core/src/process/3-dry-run-executor.ts b/packages/core/src/process/3-dry-run-executor.ts index 18b9e5c929..d6c5fe84a5 100644 --- a/packages/core/src/process/3-dry-run-executor.ts +++ b/packages/core/src/process/3-dry-run-executor.ts @@ -128,7 +128,11 @@ export class DryRunExecutor { `Starting initial test run (${this.options.testRunner} test runner with "${this.options.coverageAnalysis}" coverage analysis). This may take a while.` ); this.log.debug(`Using timeout of ${dryRunTimeout} ms.`); - const dryRunResult = await testRunner.dryRun({ timeout: dryRunTimeout, coverageAnalysis: this.options.coverageAnalysis }); + const dryRunResult = await testRunner.dryRun({ + timeout: dryRunTimeout, + coverageAnalysis: this.options.coverageAnalysis, + disableBail: this.options.disableBail, + }); const grossTimeMS = this.timer.elapsedMs(INITIAL_TEST_RUN_MARKER); const humanReadableTimeElapsed = this.timer.humanReadableElapsed(INITIAL_TEST_RUN_MARKER); this.validateResultCompleted(dryRunResult); diff --git a/packages/core/src/process/4-mutation-test-executor.ts b/packages/core/src/process/4-mutation-test-executor.ts index c0ecb9df63..156b5c1bb0 100644 --- a/packages/core/src/process/4-mutation-test-executor.ts +++ b/packages/core/src/process/4-mutation-test-executor.ts @@ -137,6 +137,7 @@ export class MutationTestExecutor { testFilter: activeMutant.coveredBy, sandboxFileName: this.sandbox.sandboxFileFor(activeMutant.fileName), hitLimit, + disableBail: this.options.disableBail, }; } diff --git a/packages/core/src/reporters/mutation-test-report-helper.ts b/packages/core/src/reporters/mutation-test-report-helper.ts index 1ea76d2c2c..b8f9c7bcc7 100644 --- a/packages/core/src/reporters/mutation-test-report-helper.ts +++ b/packages/core/src/reporters/mutation-test-report-helper.ts @@ -66,7 +66,7 @@ export class MutationTestReportHelper { ...mutant, status: MutantStatus.Killed, testsCompleted: result.nrOfTests, - killedBy: [result.killedBy], + killedBy: typeof result.killedBy === 'string' ? [result.killedBy] : result.killedBy, statusReason: result.failureMessage, }); case MutantRunStatus.Timeout: diff --git a/packages/core/src/stryker-cli.ts b/packages/core/src/stryker-cli.ts index 3bb2751db9..1826b7e2ee 100644 --- a/packages/core/src/stryker-cli.ts +++ b/packages/core/src/stryker-cli.ts @@ -67,7 +67,7 @@ export class StrykerCli { }) .option( '-f, --files ', - 'A comma separated list of patterns used for selecting all files needed to run the tests. For a more detailed way of selecting input files, please use a configFile. Example: src/**/*.js,!src/index.js,a.js,test/**/*.js.', + '[DEPRECATED, please use `--ignorePatterns` instead] A comma separated list of patterns used for selecting all files needed to run the tests. For a more detailed way of selecting input files, please use a configFile. Example: src/**/*.js,!src/index.js,a.js,test/**/*.js.', list ) .option( @@ -110,6 +110,7 @@ export class StrykerCli { 'Set the concurrency of workers. Stryker will always run checkers and test runners in parallel by creating worker processes (default: cpuCount - 1)', parseInt ) + .option('--disableBail', 'Force the test runner to keep running tests, even when a mutant is already killed.') .option( '--maxTestRunnerReuse ', 'Restart each test runner worker process after `n` runs. Not recommended unless you are experiencing memory leaks that you are unable to resolve. Configuring `0` here means infinite reuse.', diff --git a/packages/core/test/integration/test-runner/create-test-runner-factory.it.spec.ts b/packages/core/test/integration/test-runner/create-test-runner-factory.it.spec.ts index 2cacaa6abd..84ba755ee5 100644 --- a/packages/core/test/integration/test-runner/create-test-runner-factory.it.spec.ts +++ b/packages/core/test/integration/test-runner/create-test-runner-factory.it.spec.ts @@ -64,7 +64,7 @@ describe(`${createTestRunnerFactory.name} integration`, () => { } function actDryRun(timeout = 4000) { - return sut.dryRun({ timeout, coverageAnalysis: 'all' }); + return sut.dryRun(factory.dryRunOptions({ timeout, coverageAnalysis: 'all' })); } function actMutantRun(options = factory.mutantRunOptions()) { diff --git a/packages/core/test/unit/config/options-validator.spec.ts b/packages/core/test/unit/config/options-validator.spec.ts index 97c45ec980..08ae7425be 100644 --- a/packages/core/test/unit/config/options-validator.spec.ts +++ b/packages/core/test/unit/config/options-validator.spec.ts @@ -83,6 +83,7 @@ describe(OptionsValidator.name, () => { timeoutMS: 5000, tsconfigFile: 'tsconfig.json', warnings: true, + disableBail: false, }; expect(options).deep.eq(expectedOptions); }); @@ -163,6 +164,15 @@ describe(OptionsValidator.name, () => { actValidationErrors('Config option "dryRunTimeoutMinutes" must be >= 0, was -1.'); }); + it('should report a deprecation warning and set disableBail for jest.enableBail', () => { + testInjector.options.jest = { enableBail: false }; + sut.validate(testInjector.options); + expect(testInjector.logger.warn).calledWith( + 'DEPRECATED. Use of "jest.enableBail" inside deprecated, please use "disableBail" instead. See https://stryker-mutator.io/docs/stryker-js/configuration#disablebail-boolean' + ); + expect(testInjector.options.disableBail).true; + }); + describe('plugins', () => { it('should be invalid with non-array plugins', () => { breakConfig('plugins', '@stryker-mutator/typescript'); diff --git a/packages/core/test/unit/process/3-dry-run-executor.spec.ts b/packages/core/test/unit/process/3-dry-run-executor.spec.ts index e8c1fe9c53..6e5ab56f97 100644 --- a/packages/core/test/unit/process/3-dry-run-executor.spec.ts +++ b/packages/core/test/unit/process/3-dry-run-executor.spec.ts @@ -84,6 +84,31 @@ describe(DryRunExecutor.name, () => { }); }); + describe('disable bail', () => { + let runResult: CompleteDryRunResult; + + beforeEach(() => { + runResult = factory.completeDryRunResult(); + testRunnerMock.dryRun.resolves(runResult); + runResult.tests.push(factory.successTestResult()); + }); + + it('should bail by default', async () => { + await sut.execute(); + expect(testRunnerMock.dryRun).calledWithMatch({ + disableBail: false, + }); + }); + + it('should bail when given the option', async () => { + testInjector.options.disableBail = true; + await sut.execute(); + expect(testRunnerMock.dryRun).calledWithMatch({ + disableBail: true, + }); + }); + }); + describe('when the dryRun completes', () => { let runResult: CompleteDryRunResult; diff --git a/packages/core/test/unit/process/4-mutation-test-executor.spec.ts b/packages/core/test/unit/process/4-mutation-test-executor.spec.ts index 81c178dff1..359ddc2c73 100644 --- a/packages/core/test/unit/process/4-mutation-test-executor.spec.ts +++ b/packages/core/test/unit/process/4-mutation-test-executor.spec.ts @@ -189,6 +189,20 @@ describe(MutationTestExecutor.name, () => { expect(sandboxMock.sandboxFileFor).calledWithExactly('src/foo.js'); }); + it('should pass disableBail to test runner', async () => { + // Arrange + arrangeScenario(); + mutants.push(factory.mutantTestCoverage({ id: '1', coveredBy: ['1'] })); + testInjector.options.disableBail = true; + + // Act + await sut.execute(); + + // Assert + const expected: Partial = { disableBail: true }; + expect(testRunner.mutantRun).calledWithMatch(expected); + }); + it('should not run mutants that are uncovered by tests', async () => { // Arrange arrangeScenario(); diff --git a/packages/core/test/unit/reporters/mutation-test-report-helper.spec.ts b/packages/core/test/unit/reporters/mutation-test-report-helper.spec.ts index 6f2179da4c..f8cc629a59 100644 --- a/packages/core/test/unit/reporters/mutation-test-report-helper.spec.ts +++ b/packages/core/test/unit/reporters/mutation-test-report-helper.spec.ts @@ -527,6 +527,27 @@ describe(MutationTestReportHelper.name, () => { expect(actual).deep.include(expected); }); + it('should report a killed mutant when called with a KilledMutantRunResult with KilledBy as array', () => { + // Arrange + dryRunResult.tests.push(factory.failedTestResult({ id: '1', name: 'foo should be bar' })); + const sut = createSut(); + + // Act + const actual = sut.reportMutantRunResult( + factory.mutantTestCoverage({ fileName: 'add.js' }), + factory.killedMutantRunResult({ killedBy: ['1', '2'], nrOfTests: 42, failureMessage: 'foo should have been bar at line 1' }) + ); + + // Assert + const expected: Partial = { + status: MutantStatus.Killed, + killedBy: ['1', '2'], + testsCompleted: 42, + statusReason: 'foo should have been bar at line 1', + }; + expect(actual).deep.include(expected); + }); + it('should report a runtime error when called with an ErrorMutantRunResult', () => { // Arrange const sut = createSut(); diff --git a/packages/core/test/unit/stryker-cli.spec.ts b/packages/core/test/unit/stryker-cli.spec.ts index 1f0842b1f9..57dcba82ea 100644 --- a/packages/core/test/unit/stryker-cli.spec.ts +++ b/packages/core/test/unit/stryker-cli.spec.ts @@ -31,6 +31,7 @@ describe(StrykerCli.name, () => { [['--ignorePatterns', 'foo.js,bar.js'], { ignorePatterns: ['foo.js', 'bar.js'] }], [['--buildCommand', 'npm run build'], { buildCommand: 'npm run build' }], [['-b', 'npm run build'], { buildCommand: 'npm run build' }], + [['--disableBail'], { disableBail: true }], [['--mutate', 'foo.js,bar.js'], { mutate: ['foo.js', 'bar.js'] }], [['--reporters', 'foo,bar'], { reporters: ['foo', 'bar'] }], [['--plugins', 'foo,bar'], { plugins: ['foo', 'bar'] }], diff --git a/packages/core/test/unit/test-runner/timeout-decorator.spec.ts b/packages/core/test/unit/test-runner/timeout-decorator.spec.ts index b9942c3aa8..07e63ff1c8 100644 --- a/packages/core/test/unit/test-runner/timeout-decorator.spec.ts +++ b/packages/core/test/unit/test-runner/timeout-decorator.spec.ts @@ -56,7 +56,7 @@ describe(TimeoutDecorator.name, () => { } describe('dryRun', () => { - itShouldProxyRequests(() => sut.dryRun({ coverageAnalysis: 'all', timeout: 20 }), 'dryRun'); + itShouldProxyRequests(() => sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all', timeout: 20 })), 'dryRun'); it('should not handle timeouts premature', () => { // eslint-disable-next-line @typescript-eslint/no-empty-function diff --git a/packages/cucumber-runner/.vscode/launch.json b/packages/cucumber-runner/.vscode/launch.json index 396f719904..9af5760cb9 100644 --- a/packages/cucumber-runner/.vscode/launch.json +++ b/packages/cucumber-runner/.vscode/launch.json @@ -4,27 +4,6 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { - "type": "node", - "request": "launch", - "name": "🥒 Unit tests", - "program": "${workspaceFolder}/../../node_modules/mocha/bin/_mocha", - "args": [ - "--timeout", - "999999", - "--colors", - "${workspaceFolder}/dist/test/helpers/**/*.js", - "${workspaceFolder}/dist/test/unit/**/*.js" - ], - "internalConsoleOptions": "openOnSessionStart", - "outFiles": [ - "${workspaceRoot}/dist/**/*.js", - "${workspaceFolder}/../test-helpers/dist/**/*.js" - ], - "skipFiles": [ - "/**" - ] - }, { "type": "node", "request": "launch", diff --git a/packages/cucumber-runner/src/cucumber-test-runner.ts b/packages/cucumber-runner/src/cucumber-test-runner.ts index 50f5de2018..93277f3896 100644 --- a/packages/cucumber-runner/src/cucumber-test-runner.ts +++ b/packages/cucumber-runner/src/cucumber-test-runner.ts @@ -68,7 +68,7 @@ export class CucumberTestRunner implements TestRunner { public async dryRun(options: DryRunOptions): Promise { StrykerFormatter.coverageAnalysis = options.coverageAnalysis; - const result = await this.run(); + const result = await this.run(options.disableBail); if ( result.status === DryRunStatus.Complete && options.coverageAnalysis !== 'off' @@ -79,23 +79,30 @@ export class CucumberTestRunner implements TestRunner { } public async mutantRun(options: MutantRunOptions): Promise { this.instrumenterContext.activeMutant = options.activeMutant.id; - return toMutantRunResult(await this.run(options.testFilter)); + return toMutantRunResult( + await this.run(options.disableBail, options.testFilter), + true + ); } - private async run(testFilter?: string[]): Promise { + private async run( + disableBail: boolean, + testFilter?: string[] + ): Promise { const testFilterArgs = this.determineFilterArgs(testFilter); const tagsArgs = this.determineTagsArgs(); const profileArgs = this.determineProfileArgs(); + const bailArgs = disableBail ? [] : ['--fail-fast']; const argv = [ 'node', 'cucumber-js', - '--fail-fast', '--retry', '0', '--parallel', '0', '--format', require.resolve('./stryker-formatter'), + ...bailArgs, ...tagsArgs, ...profileArgs, ...testFilterArgs, diff --git a/packages/cucumber-runner/test/integration/cucumber-runner.it.spec.ts b/packages/cucumber-runner/test/integration/cucumber-runner.it.spec.ts index 4ad3f8dbe5..6a2a70d5bb 100644 --- a/packages/cucumber-runner/test/integration/cucumber-runner.it.spec.ts +++ b/packages/cucumber-runner/test/integration/cucumber-runner.it.spec.ts @@ -79,9 +79,9 @@ describe('Running in an example project', () => { testInjector.logger.isDebugEnabled.returns(true); await sut.dryRun(factory.dryRunOptions()); expect(testInjector.logger.debug).calledWith( - `${process.cwd()} "node" "cucumber-js" "--fail-fast" "--retry" "0" "--parallel" "0" "--format" "${require.resolve( + `${process.cwd()} "node" "cucumber-js" "--retry" "0" "--parallel" "0" "--format" "${require.resolve( '../../src/stryker-formatter' - )}"` + )}" "--fail-fast"` ); }); diff --git a/packages/cucumber-runner/test/integration/example-instrumented.it.spec.ts b/packages/cucumber-runner/test/integration/example-instrumented.it.spec.ts index 4d652667b7..16dd0df3b3 100644 --- a/packages/cucumber-runner/test/integration/example-instrumented.it.spec.ts +++ b/packages/cucumber-runner/test/integration/example-instrumented.it.spec.ts @@ -102,10 +102,28 @@ describe('Running in an instrumented example project', () => { ); assertions.expectKilled(actual); - expect(actual.killedBy).eq(`${simpleMathFileName}:19`); + expect(actual.killedBy).deep.eq([`${simpleMathFileName}:19`]); expect(actual.nrOfTests).eq(2); }); + it('should report all killedBy tests when disableBail is true', async () => { + const sut = createSut(); + const actual = await sut.mutantRun( + factory.mutantRunOptions({ + activeMutant: factory.mutant({ id: '2' }), + disableBail: true, + }) + ); + + assertions.expectKilled(actual); + expect(actual.killedBy).deep.eq([ + `${simpleMathFileName}:19`, + `${simpleMathFileName}:20`, + `${simpleMathFileName}:22`, + ]); + expect(actual.nrOfTests).eq(4); // all tests ran + }); + it('should be able to survive if the filtered tests are not killing', async () => { const sut = createSut(); const actual = await sut.mutantRun( @@ -135,7 +153,7 @@ describe('Running in an instrumented example project', () => { ); assertions.expectKilled(actual); - expect(actual.killedBy).eq(`${simpleMathFileName}:19`); + expect(actual.killedBy).deep.eq([`${simpleMathFileName}:19`]); expect(actual.nrOfTests).eq(1); }); diff --git a/packages/cucumber-runner/test/integration/failures.it.spec.ts b/packages/cucumber-runner/test/integration/failures.it.spec.ts index 4e10910420..a4596ca469 100644 --- a/packages/cucumber-runner/test/integration/failures.it.spec.ts +++ b/packages/cucumber-runner/test/integration/failures.it.spec.ts @@ -92,7 +92,7 @@ describe('Running cucumber when steps are failing', () => { ]); }); - it('should report an test case where multiple things went wrong as "failed"', async () => { + it('should report a test case where multiple things went wrong as "failed"', async () => { // Arrange options.cucumber.tags = ['@multiple-things-wrong']; @@ -111,7 +111,7 @@ describe('Running cucumber when steps are failing', () => { }); it('should correspond the correct failure messages to the responses', async () => { - // Run all of them, multiple failuers + // Run all of them, multiple failures const actual = await sut.dryRun(factory.dryRunOptions()); const fileName = path.join('features', 'failure-examples.feature'); assertions.expectTestResults(actual, [ @@ -138,6 +138,64 @@ describe('Running cucumber when steps are failing', () => { status: TestStatus.Failed, failureMessage: 'Multiple step definitions match:', }, + { + id: `${fileName}:32`, + name: 'Feature: Failure examples -- Scenario: Second failed step', + status: TestStatus.Skipped, + }, + ]); + }); + + it('should report only the first test (bail)', async () => { + // Arrange + options.cucumber.tags = ['@failed or @failed2']; + + // Act + const actual = await sut.dryRun( + factory.dryRunOptions({ disableBail: false }) + ); + + // Assert + const fileName = path.join('features', 'failure-examples.feature'); + assertions.expectTestResults(actual, [ + { + id: `${fileName}:4`, + status: TestStatus.Failed, + failureMessage: 'Error: Failed step', + startPosition: { line: 3, column: 3 }, + }, + { + id: `${fileName}:32`, + status: TestStatus.Skipped, + startPosition: { line: 31, column: 3 }, + }, + ]); + }); + + it('should report all failed tests when disableBail is true', async () => { + // Arrange + options.cucumber.tags = ['@failed or @failed2']; + + // Act + const actual = await sut.dryRun( + factory.dryRunOptions({ disableBail: true }) + ); + + // Assert + const fileName = path.join('features', 'failure-examples.feature'); + assertions.expectTestResults(actual, [ + { + id: `${fileName}:4`, + status: TestStatus.Failed, + failureMessage: 'Error: Failed step', + startPosition: { line: 3, column: 3 }, + }, + { + id: `${fileName}:32`, + status: TestStatus.Failed, + failureMessage: 'Error: Failed step', + startPosition: { line: 31, column: 3 }, + }, ]); }); }); diff --git a/packages/cucumber-runner/testResources/failure-example/features/failure-examples.feature b/packages/cucumber-runner/testResources/failure-example/features/failure-examples.feature index cdf6a2d94d..8bd1ae80d5 100644 --- a/packages/cucumber-runner/testResources/failure-example/features/failure-examples.feature +++ b/packages/cucumber-runner/testResources/failure-example/features/failure-examples.feature @@ -27,3 +27,8 @@ Feature: Failure examples When a failed step Then an ambiguous step Then a pending step + + @failed2 + Scenario: Second failed step + Given a success step + When a failed step diff --git a/packages/jasmine-runner/.vscode/launch.json b/packages/jasmine-runner/.vscode/launch.json index 2247d31a44..0644b1828a 100644 --- a/packages/jasmine-runner/.vscode/launch.json +++ b/packages/jasmine-runner/.vscode/launch.json @@ -7,7 +7,7 @@ { "type": "node", "request": "launch", - "name": "Unit/integration tests", + "name": "🟣 Unit/integration tests", "program": "${workspaceFolder}/../../node_modules/mocha/bin/_mocha", "args": [ "--no-timeout", diff --git a/packages/jasmine-runner/src/jasmine-test-runner.ts b/packages/jasmine-runner/src/jasmine-test-runner.ts index da29b088f1..1164e20516 100644 --- a/packages/jasmine-runner/src/jasmine-test-runner.ts +++ b/packages/jasmine-runner/src/jasmine-test-runner.ts @@ -54,23 +54,23 @@ export class JasmineTestRunner implements TestRunner { } public dryRun(options: DryRunOptions): Promise { - return this.run(undefined, options.coverageAnalysis); + return this.run(undefined, options.coverageAnalysis, options.disableBail); } public async mutantRun(options: MutantRunOptions): Promise { this.instrumenterContext.activeMutant = options.activeMutant.id; - const runResult = await this.run(options.testFilter); - return toMutantRunResult(runResult); + const runResult = await this.run(options.testFilter, undefined, options.disableBail); + return toMutantRunResult(runResult, true); } public async dispose(): Promise { this.requireCache.clear(); } - private async run(testFilter?: string[], coverageAnalysis?: CoverageAnalysis): Promise { + private async run(testFilter: string[] | undefined, coverageAnalysis: CoverageAnalysis | undefined, disableBail: boolean): Promise { this.requireCache.clear(); try { - const jasmine = this.createJasmineRunner(testFilter); + const jasmine = this.createJasmineRunner(testFilter, disableBail); const self = this; const tests: TestResult[] = []; const runTask = new Task(); @@ -117,7 +117,7 @@ export class JasmineTestRunner implements TestRunner { } } - private createJasmineRunner(testFilter: string[] | undefined) { + private createJasmineRunner(testFilter: string[] | undefined, disableBail: boolean) { let specFilter: ((spec: jasmine.Spec) => boolean) | undefined = undefined; if (testFilter) { specFilter = (spec) => testFilter.includes(spec.id.toString()); @@ -126,7 +126,7 @@ export class JasmineTestRunner implements TestRunner { // The `loadConfigFile` will fallback on the default jasmine.loadConfigFile(this.jasmineConfigFile); jasmine.env.configure({ - failFast: true, + failFast: !disableBail, oneFailurePerSpec: true, specFilter, }); diff --git a/packages/jasmine-runner/test/integration/jasmine-init-instrumented.it.spec.ts b/packages/jasmine-runner/test/integration/jasmine-init-instrumented.it.spec.ts index 8a84ded5be..ab6c1a5d71 100644 --- a/packages/jasmine-runner/test/integration/jasmine-init-instrumented.it.spec.ts +++ b/packages/jasmine-runner/test/integration/jasmine-init-instrumented.it.spec.ts @@ -45,7 +45,7 @@ describe('JasmineRunner integration with code instrumentation', () => { it('should be able to kill a mutant', async () => { const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '1' }) })); assertions.expectKilled(result); - expect(result.killedBy).eq('spec0'); + expect(result.killedBy).deep.eq(['spec0']); expect(result.failureMessage).eq('Expected Player({ currentlyPlayingSong: Song({ }), isPlaying: false }) to be playing Song({ }).'); }); @@ -58,12 +58,23 @@ describe('JasmineRunner integration with code instrumentation', () => { await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '12' }) })); const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '2' }) })); const expected = factory.killedMutantRunResult({ - killedBy: 'spec1', + killedBy: ['spec1'], status: MutantRunStatus.Killed, failureMessage: 'Expected true to be falsy.', nrOfTests: 2, // spec0 and spec1 }); expect(result).deep.eq(expected); }); + + it('should report all killed mutants when disableBail is true', async () => { + const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '2' }), disableBail: true })); + const expected = factory.killedMutantRunResult({ + killedBy: ['spec1', 'spec2'], + status: MutantRunStatus.Killed, + failureMessage: 'Expected true to be falsy.', + nrOfTests: 5, // all + }); + expect(result).deep.eq(expected); + }); }); }); diff --git a/packages/jasmine-runner/test/integration/jasmine-runner.it.spec.ts b/packages/jasmine-runner/test/integration/jasmine-runner.it.spec.ts index 190b19acae..e25ec0067c 100644 --- a/packages/jasmine-runner/test/integration/jasmine-runner.it.spec.ts +++ b/packages/jasmine-runner/test/integration/jasmine-runner.it.spec.ts @@ -103,7 +103,7 @@ describe('JasmineRunner integration', () => { sut = testInjector.injector.injectFunction(createJasmineTestRunnerFactory('__stryker2__')); }); - it('should complete with one test failure', async () => { + it('should complete with first test failure (bail)', async () => { const result = await sut.dryRun(factory.dryRunOptions()); assertions.expectCompleted(result); expectTestResultsToEqual(result.tests, [ @@ -115,5 +115,24 @@ describe('JasmineRunner integration', () => { }, ]); }); + + it('should report all failing tests when disableBail is true', async () => { + const result = await sut.dryRun(factory.dryRunOptions({ disableBail: true })); + assertions.expectCompleted(result); + expectTestResultsToEqual(result.tests, [ + { + id: 'spec0', + status: TestStatus.Failed, + failureMessage: "Expected 'bar' to be 'baz'.", + name: 'foo should be baz', + }, + { + id: 'spec1', + status: TestStatus.Failed, + failureMessage: "Expected 'bar' to be 'qux'.", + name: 'foo should be qux', + }, + ]); + }); }); }); diff --git a/packages/jasmine-runner/test/integration/memory-leak.worker.ts b/packages/jasmine-runner/test/integration/memory-leak.worker.ts index a6708828ca..fcbeb60f55 100644 --- a/packages/jasmine-runner/test/integration/memory-leak.worker.ts +++ b/packages/jasmine-runner/test/integration/memory-leak.worker.ts @@ -1,4 +1,4 @@ -import { testInjector } from '@stryker-mutator/test-helpers'; +import { factory, testInjector } from '@stryker-mutator/test-helpers'; import { expect } from 'chai'; import { DryRunStatus, TestStatus } from '@stryker-mutator/api/test-runner'; @@ -30,7 +30,7 @@ async function main() { async function doDryRun(n = 40) { if (n > 0) { console.log(`Iterator count ${n}`); - const result = await jasmineRunner.dryRun({ coverageAnalysis: 'off', timeout: 3000 }); + const result = await jasmineRunner.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off', timeout: 3000 })); if (result.status === DryRunStatus.Complete) { expect(result.tests).lengthOf(1); expect(result.tests[0].status).eq(TestStatus.Success); diff --git a/packages/jasmine-runner/test/unit/jasmine-test-runner.spec.ts b/packages/jasmine-runner/test/unit/jasmine-test-runner.spec.ts index 13e1437e2d..d290f70b6e 100644 --- a/packages/jasmine-runner/test/unit/jasmine-test-runner.spec.ts +++ b/packages/jasmine-runner/test/unit/jasmine-test-runner.spec.ts @@ -82,7 +82,7 @@ describe(JasmineTestRunner.name, () => { } jasmineEnvStub.addReporter.callsFake(addReporter); jasmineStub.execute.callsFake(async () => customReporter.jasmineDone!(createRunDetails())); - return sut.mutantRun({ activeMutant, testFilter, timeout: 2000, sandboxFileName }); + return sut.mutantRun(factory.mutantRunOptions({ activeMutant, testFilter, timeout: 2000, sandboxFileName })); } }); diff --git a/packages/jasmine-runner/testResources/test-failures/spec/fooSpec.js b/packages/jasmine-runner/testResources/test-failures/spec/fooSpec.js index 32ae3d620b..aa2664c55f 100644 --- a/packages/jasmine-runner/testResources/test-failures/spec/fooSpec.js +++ b/packages/jasmine-runner/testResources/test-failures/spec/fooSpec.js @@ -4,4 +4,7 @@ describe('foo', () => { it('should be baz', () => { expect(foo).toBe('baz'); // not true, actually 'bar' }); -}); \ No newline at end of file + it('should be qux', () => { + expect(foo).toBe('qux'); // not true, actually 'bar' + }); +}); diff --git a/packages/jest-runner/schema/jest-runner-options.json b/packages/jest-runner/schema/jest-runner-options.json index e45ffb3b04..c2e791cf8c 100644 --- a/packages/jest-runner/schema/jest-runner-options.json +++ b/packages/jest-runner/schema/jest-runner-options.json @@ -26,11 +26,6 @@ "description": "Whether to run jest with the `--findRelatedTests` flag. When `true`, Jest will only run tests related to the mutated file per test. (See [_--findRelatedTests_](https://jestjs.io/docs/en/cli.html#findrelatedtests-spaceseparatedlistofsourcefiles)", "type": "boolean", "default": true - }, - "enableBail": { - "description": "Whether to run jest with the `--bail` flag. When `true`, Jest stop testing after the first failing test, which boosts performance. (See [_--bail_](https://jestjs.io/docs/en/cli#--bail)", - "type": "boolean", - "default": true } }, "additionalProperties": false diff --git a/packages/jest-runner/src/jest-override-options.ts b/packages/jest-runner/src/jest-override-options.ts index 9df8f040c7..2aec45ea46 100644 --- a/packages/jest-runner/src/jest-override-options.ts +++ b/packages/jest-runner/src/jest-override-options.ts @@ -15,6 +15,10 @@ export const JEST_OVERRIDE_OPTIONS: Readonly = Object.fre // the results each time Stryker runs the tests notify: false, + // Bail isn't supported programmatically in jest + // see https://github.com/facebook/jest/issues/11766 + bail: false, + /** * Disable reporters, they only way us down. */ diff --git a/packages/jest-runner/src/jest-test-runner.ts b/packages/jest-runner/src/jest-test-runner.ts index d2223bd3ca..7d532a4b18 100644 --- a/packages/jest-runner/src/jest-test-runner.ts +++ b/packages/jest-runner/src/jest-test-runner.ts @@ -1,6 +1,3 @@ -// monkey patch exit first!! -import './utils/monkey-patch-exit'; - import path from 'path'; import { StrykerOptions, INSTRUMENTER_CONSTANTS, MutantCoverage } from '@stryker-mutator/api/core'; @@ -94,7 +91,7 @@ export class JestTestRunner implements TestRunner { } } - public async dryRun({ coverageAnalysis }: Pick): Promise { + public async dryRun({ coverageAnalysis, disableBail }: Pick): Promise { state.coverageAnalysis = coverageAnalysis; const mutantCoverage: MutantCoverage = { perTest: {}, static: {} }; const fileNamesWithMutantCoverage: string[] = []; @@ -106,7 +103,7 @@ export class JestTestRunner implements TestRunner { } try { const { dryRunResult, jestResult } = await this.run({ - jestConfig: withCoverageAnalysis(this.jestConfig, coverageAnalysis), + jestConfig: withCoverageAnalysis({ ...this.jestConfig }, coverageAnalysis), testLocationInResults: true, }); if (dryRunResult.status === DryRunStatus.Complete && coverageAnalysis !== 'off') { @@ -126,7 +123,7 @@ export class JestTestRunner implements TestRunner { } } - public async mutantRun({ activeMutant, sandboxFileName, testFilter }: MutantRunOptions): Promise { + public async mutantRun({ activeMutant, sandboxFileName, testFilter, disableBail }: MutantRunOptions): Promise { const fileNameUnderTest = this.enableFindRelatedTests ? sandboxFileName : undefined; state.coverageAnalysis = 'off'; let testNamePattern: string | undefined; @@ -134,27 +131,32 @@ export class JestTestRunner implements TestRunner { testNamePattern = testFilter.map((testId) => `(${escapeRegExp(testId)})`).join('|'); } process.env[INSTRUMENTER_CONSTANTS.ACTIVE_MUTANT_ENV_VARIABLE] = activeMutant.id.toString(); + try { const { dryRunResult } = await this.run({ fileNameUnderTest, jestConfig: this.configForMutantRun(fileNameUnderTest), testNamePattern, }); - return toMutantRunResult(dryRunResult); + return toMutantRunResult(dryRunResult, disableBail); } finally { delete process.env[INSTRUMENTER_CONSTANTS.ACTIVE_MUTANT_ENV_VARIABLE]; } } private configForMutantRun(fileNameUnderTest: string | undefined): jest.Config.InitialOptions { + let config: jest.Config.InitialOptions; + if (fileNameUnderTest && this.jestConfig.roots) { // Make sure the file under test lives inside one of the roots - return { + config = { ...this.jestConfig, roots: [...this.jestConfig.roots, path.dirname(fileNameUnderTest)], }; + } else { + config = this.jestConfig; } - return this.jestConfig; + return config; } private async run(settings: RunSettings): Promise<{ dryRunResult: DryRunResult; jestResult: jestTestResult.AggregatedResult }> { @@ -258,10 +260,9 @@ export class JestTestRunner implements TestRunner { private mergeConfigSettings(configFromFile: jest.Config.InitialOptions, options: JestOptions): jest.Config.InitialOptions { const config = (options.config ?? {}) as jest.Config.InitialOptions; - config.bail = options.enableBail; const stringify = (obj: unknown) => JSON.stringify(obj, null, 2); this.log.debug( - `Merging file-based config ${stringify(configFromFile)} + `Merging file-based config ${stringify(configFromFile)} with custom config ${stringify(config)} and default (internal) stryker config ${stringify(JEST_OVERRIDE_OPTIONS)}` ); diff --git a/packages/jest-runner/src/utils/monkey-patch-exit.ts b/packages/jest-runner/src/utils/monkey-patch-exit.ts deleted file mode 100644 index cbae326521..0000000000 --- a/packages/jest-runner/src/utils/monkey-patch-exit.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Jest uses a module called "exit" to exit when using `--bail` mode. - * It works by monkey-patching the `write` function from stdout and stderr, making the process completely silent, before calling `process.exit` directly. - * Stryker doesn't play nice with these side effects. In order to fix that, we use this very very very dirty hack to monkey-patch the monkey-patch. - * - * It overrides the implementation of `require('exit')` with an empty function. For this to work, it needs to be required before `jest` itself is required. - * Did I mention this hack is dirty? - * - * @see https://github.com/cowboy/node-exit - */ - -try { - const exitModuleId = require.resolve('exit', { paths: [require.resolve('jest', { paths: [process.cwd()] })] }); - // eslint-disable-next-line @typescript-eslint/no-require-imports - require(exitModuleId); - const exitModule = module.children.find((mdl) => mdl.id === exitModuleId); - // eslint-disable-next-line @typescript-eslint/no-empty-function - exitModule!.exports = () => {}; -} catch (error) { - console.log('Unable to monkey-patch exit module', error); -} diff --git a/packages/jest-runner/test/helpers/producers.ts b/packages/jest-runner/test/helpers/producers.ts index e1d7c9b9f4..9e655ebe53 100644 --- a/packages/jest-runner/test/helpers/producers.ts +++ b/packages/jest-runner/test/helpers/producers.ts @@ -13,7 +13,6 @@ export const createJestRunnerOptionsWithStrykerOptions = (overrides?: Partial): JestOptions => { return { - enableBail: true, enableFindRelatedTests: true, projectType: 'custom', ...overrides, diff --git a/packages/jest-runner/test/integration/coverage-analysis.it.spec.ts b/packages/jest-runner/test/integration/coverage-analysis.it.spec.ts index cf62a3b57c..a651f3a848 100644 --- a/packages/jest-runner/test/integration/coverage-analysis.it.spec.ts +++ b/packages/jest-runner/test/integration/coverage-analysis.it.spec.ts @@ -41,23 +41,39 @@ describe('JestTestRunner coverage analysis integration', () => { describe('dryRun', () => { it('should not provide coverage analysis if coverageAnalysis is "off"', async () => { - const result = await sut.dryRun({ coverageAnalysis: 'off' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); assertions.expectCompleted(result); expect(result.mutantCoverage).undefined; }); it('should provide static coverage when coverageAnalysis is "all"', async () => { - const result = await sut.dryRun({ coverageAnalysis: 'all' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all' })); assertions.expectCompleted(result); expect(result.mutantCoverage).not.undefined; expect(result.mutantCoverage!.perTest).deep.eq({}); - for (let i = 0; i < 17; i++) { - expect(result.mutantCoverage!.static[i]).eq(1); - } + expect(result.mutantCoverage!.static).deep.eq({ + '0': 2, + '1': 2, + '2': 1, + '3': 1, + '4': 1, + '5': 1, + '6': 1, + '7': 1, + '8': 1, + '9': 1, + '10': 1, + '11': 1, + '12': 1, + '13': 1, + '14': 1, + '15': 1, + '16': 1, + }); }); it('should provide perTest coverage when coverageAnalysis is "perTest"', async () => { - const result = await sut.dryRun({ coverageAnalysis: 'perTest' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); assertions.expectCompleted(result); expect(result.mutantCoverage).not.undefined; expect(result.mutantCoverage!.static).deep.eq({}); @@ -66,6 +82,10 @@ describe('JestTestRunner coverage analysis integration', () => { 4: 1, 5: 1, }, + 'Add should be able to subtract using a negative number': { + '0': 1, + '1': 1, + }, 'Add should be able to add one to a number': { 2: 1, 3: 1, @@ -135,13 +155,13 @@ describe('JestTestRunner coverage analysis integration', () => { describe('dryRun', () => { it('should not provide coverage analysis if coverageAnalysis is "off"', async () => { - const result = await sut.dryRun({ coverageAnalysis: 'off' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); assertions.expectCompleted(result); expect(result.mutantCoverage).undefined; }); it('should provide static coverage when coverageAnalysis is "all"', async () => { - const result = await sut.dryRun({ coverageAnalysis: 'all' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all' })); assertions.expectCompleted(result); expect(result.mutantCoverage).not.undefined; expect(result.mutantCoverage!.perTest).deep.eq({}); @@ -175,7 +195,7 @@ describe('JestTestRunner coverage analysis integration', () => { }); it('should provide perTest coverage when coverageAnalysis is "perTest"', async () => { - const result = await sut.dryRun({ coverageAnalysis: 'perTest' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); assertions.expectCompleted(result); expect(result.mutantCoverage).not.undefined; expect(result.mutantCoverage!.static).deep.eq({ 22: 1, 30: 1 }); diff --git a/packages/jest-runner/test/integration/jest-test-runner.it.spec.ts b/packages/jest-runner/test/integration/jest-test-runner.it.spec.ts index 4f74b0816f..2e9433bd3a 100644 --- a/packages/jest-runner/test/integration/jest-test-runner.it.spec.ts +++ b/packages/jest-runner/test/integration/jest-test-runner.it.spec.ts @@ -29,6 +29,7 @@ describe(`${JestTestRunner.name} integration test`, () => { const options: JestRunnerOptionsWithStrykerOptions = factory.strykerWithPluginOptions({ jest: createJestOptions(overrides), }); + return testInjector.injector.provideValue(commonTokens.options, options).injectFunction(jestTestRunnerFactory); } @@ -41,18 +42,20 @@ describe(`${JestTestRunner.name} integration test`, () => { process.chdir(resolveTestResource('jasmine2-node')); const jestTestRunner = createSut(); - const runResult = await jestTestRunner.dryRun({ coverageAnalysis: 'off' }); + const runResult = await jestTestRunner.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); assertions.expectCompleted(runResult); - expect(runResult.tests[0].name).to.equal('Add should be able to add two numbers'); - expect(runResult.tests[0].timeSpentMs).to.be.above(-1); + const result = runResult.tests.find((test) => test.id === 'Add should be able to add two numbers'); + expect(result).to.not.be.null; + expect(result!.name).to.equal('Add should be able to add two numbers'); + expect(result!.timeSpentMs).to.be.above(-1); }); it('should run tests on the example custom project using package.json', async () => { process.chdir(resolveTestResource('jasmine2-node')); const jestTestRunner = createSut(); - const runResult = await jestTestRunner.dryRun({ coverageAnalysis: 'off' }); + const runResult = await jestTestRunner.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); assertions.expectCompleted(runResult); expectToHaveSuccessfulTests(runResult, testNames.length); @@ -63,7 +66,7 @@ describe(`${JestTestRunner.name} integration test`, () => { const jestTestRunner = createSut(); - const runResult = await jestTestRunner.dryRun({ coverageAnalysis: 'off' }); + const runResult = await jestTestRunner.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); assertions.expectCompleted(runResult); expectToHaveSuccessfulTests(runResult, testNames.length); @@ -74,7 +77,7 @@ describe(`${JestTestRunner.name} integration test`, () => { const addSpecFileName = resolveTestResource('exampleProjectWithExplicitJestConfig', 'src', '__tests__', 'AddSpec.js'); const circleSpecFileName = resolveTestResource('exampleProjectWithExplicitJestConfig', 'src', '__tests__', 'CircleSpec.js'); const jestTestRunner = createSut(); - const runResult = await jestTestRunner.dryRun({ coverageAnalysis: 'perTest' }); + const runResult = await jestTestRunner.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); assertions.expectCompleted(runResult); expectTestResults(runResult, [ { @@ -157,5 +160,42 @@ describe(`${JestTestRunner.name} integration test`, () => { assertions.expectKilled(firstResult); assertions.expectSurvived(secondResult); }); + + it('should only report the first failing test in `killedBy` when disableBail = false', async () => { + // Arrange + const exampleProjectRoot = resolveTestResource('jasmine2-node-instrumented'); + process.chdir(exampleProjectRoot); + const jestTestRunner = createSut(); + const mutantRunOptions = factory.mutantRunOptions({ + sandboxFileName: require.resolve(path.resolve(exampleProjectRoot, 'src', 'Add.js')), + activeMutant: factory.mutant({ id: '0' }), + }); + + // Act + const result = await jestTestRunner.mutantRun(mutantRunOptions); + + // Assert + assertions.expectKilled(result); + expect(result.killedBy).eq('Add should be able to add two numbers'); + }); + + it('should be able to collect all tests that kill a mutant when disableBail = true', async () => { + // Arrange + const exampleProjectRoot = resolveTestResource('jasmine2-node-instrumented'); + process.chdir(exampleProjectRoot); + const jestTestRunner = createSut(); + const mutantRunOptions = factory.mutantRunOptions({ + sandboxFileName: require.resolve(path.resolve(exampleProjectRoot, 'src', 'Add.js')), + activeMutant: factory.mutant({ id: '0' }), + disableBail: true, + }); + + // Act + const result = await jestTestRunner.mutantRun(mutantRunOptions); + + // Assert + assertions.expectKilled(result); + expect(result.killedBy).to.have.length(2); + }); }); }); diff --git a/packages/jest-runner/test/unit/jest-test-runner.spec.ts b/packages/jest-runner/test/unit/jest-test-runner.spec.ts index 4bfe99347f..bb057731d9 100644 --- a/packages/jest-runner/test/unit/jest-test-runner.spec.ts +++ b/packages/jest-runner/test/unit/jest-test-runner.spec.ts @@ -38,7 +38,6 @@ describe(JestTestRunner.name, () => { options.jest = { enableFindRelatedTests: true, projectType: 'custom', - enableBail: true, }; options.basePath = basePath; @@ -67,14 +66,14 @@ describe(JestTestRunner.name, () => { describe('dryRun', () => { it('should call the run function with the provided config and the projectRoot', async () => { const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); expect(jestTestAdapterMock.run).called; }); it('should set reporters to an empty array', async () => { const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); expect(jestTestAdapterMock.run).calledWithMatch( sinon.match({ jestConfig: sinon.match({ @@ -84,22 +83,19 @@ describe(JestTestRunner.name, () => { ); }); - it('should set bail = true', async () => { + it('should always set bail = false (see https://github.com/facebook/jest/issues/11766)', async () => { const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off', disableBail: true })); expect(jestTestAdapterMock.run).calledWithMatch( sinon.match({ - jestConfig: sinon.match({ - bail: true, - }), + jestConfig: sinon.match({ bail: false }), }) ); }); - it('should set bail = false when enableBail is false', async () => { - options.jest.enableBail = false; + it('should set bail = false when disableBail', async () => { const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun({ coverageAnalysis: 'off', disableBail: true }); expect(jestTestAdapterMock.run).calledWithMatch( sinon.match({ jestConfig: sinon.match({ @@ -112,7 +108,7 @@ describe(JestTestRunner.name, () => { it('should trace log a message when jest is invoked', async () => { const sut = createSut(); testInjector.logger.isTraceEnabled.returns(true); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); expect(testInjector.logger.trace).calledWithMatch(/Invoking Jest with config\s.*/, sinon.match(/.*"jestConfig".*/)); }); @@ -120,7 +116,7 @@ describe(JestTestRunner.name, () => { const sut = createSut(); jestTestAdapterMock.run.resolves(producers.createJestRunResult({ results: producers.createSuccessResult() })); - const result = await sut.dryRun({ coverageAnalysis: 'off' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); const expectedRunResult: CompleteDryRunResult = { status: DryRunStatus.Complete, @@ -142,7 +138,7 @@ describe(JestTestRunner.name, () => { const sut = createSut(); jestTestAdapterMock.run.resolves(producers.createJestRunResult({ results: producers.createPendingResult() })); - const result = await sut.dryRun({ coverageAnalysis: 'off' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); const expectedRunResult: CompleteDryRunResult = { status: DryRunStatus.Complete, @@ -165,7 +161,7 @@ describe(JestTestRunner.name, () => { const sut = createSut(); jestTestAdapterMock.run.resolves(producers.createJestRunResult({ results: producers.createTodoResult() })); - const result = await sut.dryRun({ coverageAnalysis: 'off' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); const expectedRunResult: CompleteDryRunResult = { status: DryRunStatus.Complete, tests: [ @@ -194,7 +190,7 @@ describe(JestTestRunner.name, () => { const sut = createSut(); jestTestAdapterMock.run.resolves(producers.createJestRunResult({ results: producers.createFailResult() })); - const result = await sut.dryRun({ coverageAnalysis: 'off' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); const expectedRunResult: CompleteDryRunResult = { status: DryRunStatus.Complete, @@ -248,7 +244,7 @@ describe(JestTestRunner.name, () => { }); jestTestAdapterMock.run.resolves(producers.createJestRunResult({ results: jestResult })); - const result = await sut.dryRun({ coverageAnalysis: 'off' }); + const result = await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); const expectedRunResult: ErrorDryRunResult = { status: DryRunStatus.Error, @@ -260,7 +256,7 @@ describe(JestTestRunner.name, () => { it("should set process.env.NODE_ENV to 'test' when process.env.NODE_ENV is null", async () => { const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); expect(processEnvMock.NODE_ENV).to.equal('test'); }); @@ -269,7 +265,7 @@ describe(JestTestRunner.name, () => { const sut = createSut(); processEnvMock.NODE_ENV = 'stryker'; - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); expect(processEnvMock.NODE_ENV).to.equal('stryker'); }); @@ -277,17 +273,17 @@ describe(JestTestRunner.name, () => { it('should load "react-scripts/config/env.js" when projectType = create-react-app', async () => { options.jest.projectType = 'create-react-app'; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); expect(requireResolveStub).calledWith('react-scripts/config/env.js'); }); it('should override verbose, collectCoverage, testResultsProcessor, notify and bail on all loaded configs', async () => { const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'off' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ - bail: true, + bail: false, collectCoverage: false, notify: false, testResultsProcessor: undefined, @@ -304,7 +300,7 @@ describe(JestTestRunner.name, () => { jestTestAdapterMock.run.returns(runTask.promise); // Act - const onGoingDryRun = sut.dryRun({ coverageAnalysis: 'all' }); + const onGoingDryRun = sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all' })); state.handleMutantCoverage('foo.js', { static: { 0: 2 }, perTest: { 'foo should be bar': { 3: 1 } } }); state.handleMutantCoverage('bar.js', { static: { 0: 3, 1: 2 }, perTest: { 'foo should be bar': { 7: 1 }, 'baz should be qux': { 6: 1 } } }); runTask.resolve({ @@ -333,7 +329,7 @@ describe(JestTestRunner.name, () => { it('should remove the coverage handler afterwards', async () => { const sut = createSut(); const resetSpy = sinon.spy(state, 'resetMutantCoverageHandler'); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(resetSpy).called; }); @@ -341,7 +337,7 @@ describe(JestTestRunner.name, () => { const testEnvironment = 'my-test-environment'; options.jest.config = { testEnvironment }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'all' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ testEnvironment: require.resolve('../../src/jest-plugins/jest-environment-generic') }), }); @@ -351,7 +347,7 @@ describe(JestTestRunner.name, () => { it('should set the set the jestEnvironment to "jest-environment-jsdom" in the messaging state when the jest environment is "jsdom"', async () => { options.jest.config = { testEnvironment: 'jsdom' }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'all' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all' })); expect(state.jestEnvironment).eq('jest-environment-jsdom'); }); @@ -359,7 +355,7 @@ describe(JestTestRunner.name, () => { it('should set the set the jestEnvironment to "jest-environment-node" in the messaging state when the jest environment is "node"', async () => { options.jest.config = { testEnvironment: 'node' }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'all' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all' })); expect(state.jestEnvironment).eq('jest-environment-node'); }); @@ -367,7 +363,7 @@ describe(JestTestRunner.name, () => { it('should add a set setupFile if testRunner = "jest-jasmine2"', async () => { options.jest.config = { testRunner: 'jest-jasmine2' }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ setupFilesAfterEnv: [require.resolve('../../src/jest-plugins/jasmine2-setup-coverage-analysis')] }), }); @@ -378,7 +374,7 @@ describe(JestTestRunner.name, () => { getVersionStub.returns('26.999.999'); options.jest.config = { testRunner: undefined }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ setupFilesAfterEnv: [require.resolve('../../src/jest-plugins/jasmine2-setup-coverage-analysis')] }), }); @@ -389,7 +385,7 @@ describe(JestTestRunner.name, () => { getVersionStub.returns('27.0.0'); options.jest.config = { testRunner: undefined }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ setupFilesAfterEnv: undefined }), }); @@ -398,7 +394,7 @@ describe(JestTestRunner.name, () => { it('should not allow the circus test runner for coverage analysis "perTest"', async () => { options.jest.config = { testRunner: 'jest-circus/runner' }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ setupFilesAfterEnv: undefined }), }); @@ -407,7 +403,7 @@ describe(JestTestRunner.name, () => { it('should not allow a full path to circus test runner for coverage analysis "perTest"', async () => { options.jest.config = { testRunner: require.resolve('jest-circus/runner') }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ setupFilesAfterEnv: undefined }), }); @@ -416,7 +412,7 @@ describe(JestTestRunner.name, () => { it('should not remove existing setup files if testRunner = "jest-jasmine2"', async () => { options.jest.config = { testRunner: 'jest-jasmine2', setupFilesAfterEnv: ['setup/env.js', 'setup/unit.js'] }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ setupFilesAfterEnv: [require.resolve('../../src/jest-plugins/jasmine2-setup-coverage-analysis'), 'setup/env.js', 'setup/unit.js'], @@ -427,7 +423,7 @@ describe(JestTestRunner.name, () => { it('should not add a setupFile if coverageAnalysis = "all"', async () => { options.jest.config = { testRunner: 'jest-jasmine2' }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'all' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'all' })); const { jestConfig } = jestTestAdapterMock.run.getCall(0).args[0]; expect(jestConfig).has.not.property('setupFilesAfterEnv'); }); @@ -435,7 +431,7 @@ describe(JestTestRunner.name, () => { it('should not add a set setupFile if testRunner = "jest-circus/runner"', async () => { options.jest.config = { testRunner: 'jest-circus/runner', setupFilesAfterEnv: ['setup.js'] }; const sut = createSut(); - await sut.dryRun({ coverageAnalysis: 'perTest' }); + await sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); expect(jestTestAdapterMock.run).calledWithMatch({ jestConfig: sinon.match({ setupFilesAfterEnv: ['setup.js'] }), }); @@ -444,7 +440,7 @@ describe(JestTestRunner.name, () => { it('should reject if coverageAnalysis = perTest and test runner is not recognized', async () => { options.jest.config = { testRunner: 'foo/runner' }; const sut = createSut(); - const onGoingRun = sut.dryRun({ coverageAnalysis: 'perTest' }); + const onGoingRun = sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); await expect(onGoingRun).rejectedWith( 'The @stryker-mutator/jest-runner doesn\'t support coverageAnalysis "perTest" with "jestConfig.testRunner": "foo/runner". Please open an issue if you want support for this: https://github.com/stryker-mutator/stryker-js/issues' ); @@ -457,7 +453,7 @@ describe(JestTestRunner.name, () => { jestTestAdapterMock.run.returns(runTask.promise); // Act - const onGoingRun = sut.dryRun({ coverageAnalysis: 'perTest' }); + const onGoingRun = sut.dryRun(factory.dryRunOptions({ coverageAnalysis: 'perTest' })); state.handleMutantCoverage(path.resolve('foo.js'), { perTest: {}, static: {} }); // mutant coverage for bar.js is missing runTask.resolve( @@ -560,6 +556,18 @@ describe(JestTestRunner.name, () => { }) ); }); + + it('should set bail if disableBail is passed', async () => { + const sut = createSut(); + await sut.mutantRun(factory.mutantRunOptions({ disableBail: true })); + expect(jestTestAdapterMock.run).calledWithMatch( + sinon.match({ + jestConfig: sinon.match({ + bail: false, + }), + }) + ); + }); }); function createSut() { diff --git a/packages/jest-runner/testResources/jasmine2-node-instrumented/src/__tests__/AddSpec.js b/packages/jest-runner/testResources/jasmine2-node-instrumented/src/__tests__/AddSpec.js index 0d65de9d43..e0572863df 100644 --- a/packages/jest-runner/testResources/jasmine2-node-instrumented/src/__tests__/AddSpec.js +++ b/packages/jest-runner/testResources/jasmine2-node-instrumented/src/__tests__/AddSpec.js @@ -13,6 +13,16 @@ describe('Add', function() { expect(actual).toBe(expected); }); + + it('should be able to subtract using a negative number', function() { + var num1 = 5; + var num2 = -2; + var expected = num1 + num2; + + var actual = add(num1, num2); + + expect(actual).toBe(expected); + }); it('should be able to add one to a number', function() { var number = 2; diff --git a/packages/karma-runner/src/karma-test-runner.ts b/packages/karma-runner/src/karma-test-runner.ts index 5d0033451c..d279f24a87 100644 --- a/packages/karma-runner/src/karma-test-runner.ts +++ b/packages/karma-runner/src/karma-test-runner.ts @@ -22,7 +22,12 @@ export class KarmaTestRunner implements TestRunner { constructor(private readonly log: Logger, getLogger: LoggerFactoryMethod, options: StrykerOptions) { const setup = this.loadSetup(options); this.starter = new ProjectStarter(getLogger, setup); - this.setGlobals(setup, getLogger); + strykerKarmaConf.setGlobals({ + getLogger, + karmaConfig: setup.config, + karmaConfigFile: setup.configFile, + disableBail: options.disableBail, + }); } public async init(): Promise { @@ -47,15 +52,14 @@ export class KarmaTestRunner implements TestRunner { public async dryRun(options: DryRunOptions): Promise { TestHooksMiddleware.instance.configureCoverageAnalysis(options.coverageAnalysis); - const res = await this.run(); - return res; + return await this.run(); } public async mutantRun(options: MutantRunOptions): Promise { TestHooksMiddleware.instance.configureMutantRun(options); StrykerReporter.instance.configureHitLimit(options.hitLimit); const dryRunResult = await this.run(); - return toMutantRunResult(dryRunResult); + return toMutantRunResult(dryRunResult, true); } private run(): Promise { @@ -80,14 +84,6 @@ export class KarmaTestRunner implements TestRunner { return Object.assign(defaultKarmaConfig, (options as KarmaRunnerOptionsWithStrykerOptions).karma); } - private setGlobals(setup: StrykerKarmaSetup, getLogger: LoggerFactoryMethod) { - strykerKarmaConf.setGlobals({ - getLogger, - karmaConfig: setup.config, - karmaConfigFile: setup.configFile, - }); - } - private runServer(): void { karma.runner.run(this.runConfig, (exitCode) => { this.log.debug('karma run done with ', exitCode); diff --git a/packages/karma-runner/src/starters/stryker-karma.conf.ts b/packages/karma-runner/src/starters/stryker-karma.conf.ts index 0d3c4a10b2..51cd127148 100644 --- a/packages/karma-runner/src/starters/stryker-karma.conf.ts +++ b/packages/karma-runner/src/starters/stryker-karma.conf.ts @@ -71,12 +71,12 @@ function setClientOptions(config: Config) { if (config.frameworks?.includes('jasmine')) { (clientOptions as any).jasmine = { random: false, - failFast: true, + failFast: !globalSettings.disableBail, }; } if (config.frameworks?.includes('mocha')) { - (clientOptions as any).mocha = { bail: true }; + (clientOptions as any).mocha = { bail: !globalSettings.disableBail }; } config.set({ client: clientOptions }); } @@ -140,14 +140,18 @@ function configureStrykerReporter(config: Config) { config.reporters.push(StrykerReporter.name); } -const globalSettings: { +interface GlobalSettings { karmaConfig?: ConfigOptions; karmaConfigFile?: string; getLogger: LoggerFactoryMethod; -} = { + disableBail: boolean; +} + +const globalSettings: GlobalSettings = { getLogger() { return noopLogger; }, + disableBail: false, }; function configureKarma(config: Config): void { @@ -168,10 +172,11 @@ function configureKarma(config: Config): void { * This is the only way we can pass through any values between the `KarmaTestRunner` and the stryker-karma.conf file. * (not counting environment variables) */ -configureKarma.setGlobals = (globals: { karmaConfig?: ConfigOptions; karmaConfigFile?: string; getLogger?: LoggerFactoryMethod }) => { +configureKarma.setGlobals = (globals: Partial) => { globalSettings.karmaConfig = globals.karmaConfig; globalSettings.karmaConfigFile = globals.karmaConfigFile; globalSettings.getLogger = globals.getLogger ?? (() => noopLogger); + globalSettings.disableBail = globals.disableBail ?? false; }; export = configureKarma; diff --git a/packages/karma-runner/test/integration/instrumented.it.spec.ts b/packages/karma-runner/test/integration/instrumented.it.spec.ts index 8a2da8dc74..cc9d72ba4e 100644 --- a/packages/karma-runner/test/integration/instrumented.it.spec.ts +++ b/packages/karma-runner/test/integration/instrumented.it.spec.ts @@ -109,7 +109,7 @@ describe(`${KarmaTestRunner.name} running on instrumented code`, () => { it('should be able to kill a mutant', async () => { const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '0' }) })); assertions.expectKilled(result); - expect(result.killedBy).eq('spec0'); + expect(result.killedBy).deep.eq(['spec0']); expect(result.failureMessage.split('\n')[0]).eq('Error: Expected undefined to be 7.'); }); @@ -133,7 +133,7 @@ describe(`${KarmaTestRunner.name} running on instrumented code`, () => { assertions.expectKilled(result); result.failureMessage = result.failureMessage.split('\n')[0]; const expected = factory.killedMutantRunResult({ - killedBy: 'spec1', + killedBy: ['spec1'], status: MutantRunStatus.Killed, failureMessage: 'Error: Expected undefined to be 3.', nrOfTests: 1, @@ -237,7 +237,7 @@ describe(`${KarmaTestRunner.name} running on instrumented code`, () => { it('should be able to kill a mutant', async () => { const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '0' }) })); assertions.expectKilled(result); - expect(result.killedBy).eq('Add should be able to add two numbers'); + expect(result.killedBy).deep.eq(['Add should be able to add two numbers']); expect(result.failureMessage.split('\n')[0]).eq('AssertionError: expected undefined to equal 7'); }); @@ -270,7 +270,7 @@ describe(`${KarmaTestRunner.name} running on instrumented code`, () => { assertions.expectKilled(result); result.failureMessage = result.failureMessage.split('\n')[0]; const expected: KilledMutantRunResult = { - killedBy: 'Add should be able 1 to a number', + killedBy: ['Add should be able 1 to a number'], status: MutantRunStatus.Killed, failureMessage: 'AssertionError: expected undefined to equal 3', nrOfTests: 1, diff --git a/packages/karma-runner/test/integration/karma-test-runner.it.spec.ts b/packages/karma-runner/test/integration/karma-test-runner.it.spec.ts index 8bdff86465..10a696a68d 100644 --- a/packages/karma-runner/test/integration/karma-test-runner.it.spec.ts +++ b/packages/karma-runner/test/integration/karma-test-runner.it.spec.ts @@ -1,7 +1,7 @@ import { promisify } from 'util'; import http from 'http'; -import { DryRunStatus, TestStatus, CompleteDryRunResult, TestResult, FailedTestResult } from '@stryker-mutator/api/test-runner'; +import { TestStatus, CompleteDryRunResult, TestResult, FailedTestResult } from '@stryker-mutator/api/test-runner'; import { testInjector, assertions, factory } from '@stryker-mutator/test-helpers'; import { expect } from 'chai'; import { FilePattern } from 'karma'; @@ -80,7 +80,7 @@ describe(`${KarmaTestRunner.name} integration`, () => { }); describe('when some tests fail', () => { - before(() => { + beforeEach(() => { setOptions({ files: [ 'testResources/sampleProject/src/Add.js', @@ -88,26 +88,68 @@ describe(`${KarmaTestRunner.name} integration`, () => { 'testResources/sampleProject/test-jasmine/AddFailedSpec.js', ], }); - sut = createSut(); - return sut.init(); }); - after(async () => { + afterEach(async () => { await sut.dispose(); }); describe('dryRun', () => { it('should report the first failed test (bail)', async () => { + // Arrange + sut = createSut(); + await sut.init(); + + // Act const runResult = await sut.dryRun(factory.dryRunOptions()); + + // Assert assertions.expectCompleted(runResult); expectToHaveSuccessfulTests(runResult, 5); expectToHaveFailedTests(runResult, ['Error: Expected 7 to be 8.']); - expect(runResult.status).to.be.eq(DryRunStatus.Complete); + }); + + it('should report all failing tests when disableBail is true', async () => { + // Arrange + testInjector.options.disableBail = true; + sut = createSut(); + await sut.init(); + + // Act + const runResult = await sut.dryRun(factory.dryRunOptions()); + + // Assert + assertions.expectCompleted(runResult); + expectToHaveSuccessfulTests(runResult, 5); + expectToHaveFailedTests(runResult, ['Error: Expected 7 to be 8.', 'Error: Expected 3 to be 4.']); }); }); + describe('runMutant()', () => { it('should report the mutant as killed', async () => { + // Arrange + sut = createSut(); + await sut.init(); + + // Act + const mutantResult = await sut.mutantRun(factory.mutantRunOptions()); + + // Assert + assertions.expectKilled(mutantResult); + expect(mutantResult.killedBy).deep.eq(['spec5']); + expect(mutantResult.failureMessage.split('\n')[0]).eq('Error: Expected 7 to be 8.'); + }); + + it('should report all failed tests when disableBail is true', async () => { + // Arrange + testInjector.options.disableBail = true; + sut = createSut(); + await sut.init(); + + // Act const mutantResult = await sut.mutantRun(factory.mutantRunOptions()); + + // Assert assertions.expectKilled(mutantResult); - expect(mutantResult.killedBy).eq('spec5'); + expect(mutantResult.killedBy).deep.eq(['spec5', 'spec6']); expect(mutantResult.failureMessage.split('\n')[0]).eq('Error: Expected 7 to be 8.'); }); }); diff --git a/packages/karma-runner/test/unit/karma-test-runner.spec.ts b/packages/karma-runner/test/unit/karma-test-runner.spec.ts index a4d756f9cb..9b87bf58f9 100644 --- a/packages/karma-runner/test/unit/karma-test-runner.spec.ts +++ b/packages/karma-runner/test/unit/karma-test-runner.spec.ts @@ -24,7 +24,7 @@ import { karma } from '../../src/karma-wrapper'; describe(KarmaTestRunner.name, () => { let projectStarterMock: sinon.SinonStubbedInstance; - let setGlobalsStub: sinon.SinonStub; + let setGlobalsStub: sinon.SinonStubbedMember; let karmaRunStub: sinon.SinonStubbedMember; let getLogger: LoggerFactoryMethod; let testHooksMiddlewareMock: sinon.SinonStubbedInstance; @@ -49,6 +49,7 @@ describe(KarmaTestRunner.name, () => { getLogger, karmaConfig: undefined, karmaConfigFile: undefined, + disableBail: false, }); }); @@ -61,11 +62,13 @@ describe(KarmaTestRunner.name, () => { projectType: 'angular-cli', }; testInjector.options.karma = expectedSetup; + testInjector.options.disableBail = true; createSut(); expect(setGlobalsStub).calledWith({ getLogger, karmaConfig: expectedSetup.config, karmaConfigFile: expectedSetup.configFile, + disableBail: true, }); expect(testInjector.logger.warn).not.called; @@ -86,11 +89,13 @@ describe(KarmaTestRunner.name, () => { projectType: 'angular-cli', }; testInjector.options.karma = expectedSetup; + testInjector.options.disableBail = true; createSut(); expect(setGlobalsStub).calledWith({ getLogger, karmaConfig: expectedSetup.config, karmaConfigFile: expectedSetup.configFile, + disableBail: true, }); expect(testInjector.logger.warn).not.called; expect(projectStarter.ProjectStarter).calledWith(sinon.match.func, expectedSetup); diff --git a/packages/karma-runner/test/unit/starters/stryker-karma.conf.spec.ts b/packages/karma-runner/test/unit/starters/stryker-karma.conf.spec.ts index 8fad412124..00c147c942 100644 --- a/packages/karma-runner/test/unit/starters/stryker-karma.conf.spec.ts +++ b/packages/karma-runner/test/unit/starters/stryker-karma.conf.spec.ts @@ -189,7 +189,7 @@ describe('stryker-karma.conf.js', () => { }); it('should set basePath to location of karma.conf.js', () => { - sut.setGlobals({ karmaConfigFile: '../foobar.conf.js' }); + sut.setGlobals({ karmaConfigFile: '../foobar.conf.js', disableBail: false }); requireModuleStub.returns(() => { /* noop */ }); diff --git a/packages/mocha-runner/.vscode/launch.json b/packages/mocha-runner/.vscode/launch.json index 78937dc2ee..64da58d37f 100644 --- a/packages/mocha-runner/.vscode/launch.json +++ b/packages/mocha-runner/.vscode/launch.json @@ -7,7 +7,7 @@ { "type": "node", "request": "launch", - "name": "Unit tests", + "name": "☕ Unit tests", "program": "${workspaceFolder}/../../node_modules/mocha/bin/_mocha", "args": [ "--timeout", @@ -27,7 +27,7 @@ { "type": "node", "request": "launch", - "name": "Integration tests", + "name": "☕ Integration tests", "program": "${workspaceFolder}/../../node_modules/mocha/bin/_mocha", "args": [ "--timeout", diff --git a/packages/mocha-runner/src/mocha-test-runner.ts b/packages/mocha-runner/src/mocha-test-runner.ts index 87811f326d..c9b6b7515d 100644 --- a/packages/mocha-runner/src/mocha-test-runner.ts +++ b/packages/mocha-runner/src/mocha-test-runner.ts @@ -60,10 +60,10 @@ export class MochaTestRunner implements TestRunner { } } - public async dryRun(options: DryRunOptions): Promise { + public async dryRun({ coverageAnalysis, disableBail }: DryRunOptions): Promise { // eslint-disable-next-line @typescript-eslint/no-empty-function let interceptor: (mocha: Mocha) => void = () => {}; - if (options.coverageAnalysis === 'perTest') { + if (coverageAnalysis === 'perTest') { interceptor = (mocha) => { const self = this; mocha.suite.beforeEach('StrykerIntercept', function () { @@ -71,14 +71,14 @@ export class MochaTestRunner implements TestRunner { }); }; } - const runResult = await this.run(interceptor); - if (runResult.status === DryRunStatus.Complete && options.coverageAnalysis !== 'off') { + const runResult = await this.run(interceptor, disableBail); + if (runResult.status === DryRunStatus.Complete && coverageAnalysis !== 'off') { runResult.mutantCoverage = this.instrumenterContext.mutantCoverage; } return runResult; } - public async mutantRun({ activeMutant, testFilter }: MutantRunOptions): Promise { + public async mutantRun({ activeMutant, testFilter, disableBail }: MutantRunOptions): Promise { this.instrumenterContext.activeMutant = activeMutant.id; // eslint-disable-next-line @typescript-eslint/no-empty-function let intercept: (mocha: Mocha) => void = () => {}; @@ -89,15 +89,15 @@ export class MochaTestRunner implements TestRunner { mocha.grep(regex); }; } - const dryRunResult = await this.run(intercept); - return toMutantRunResult(dryRunResult); + const dryRunResult = await this.run(intercept, disableBail); + return toMutantRunResult(dryRunResult, true); } - public async run(intercept: (mocha: Mocha) => void): Promise { + public async run(intercept: (mocha: Mocha) => void, disableBail: boolean): Promise { this.requireCache.clear(); const mocha = this.mochaAdapter.create({ reporter: StrykerMochaReporter as any, - bail: true, + bail: !disableBail, timeout: false as any, // Mocha 5 doesn't support `0` rootHooks: this.rootHooks, } as Mocha.MochaOptions); diff --git a/packages/mocha-runner/test/integration/memory-leak.worker.ts b/packages/mocha-runner/test/integration/memory-leak.worker.ts index acbc383229..42633dec2e 100644 --- a/packages/mocha-runner/test/integration/memory-leak.worker.ts +++ b/packages/mocha-runner/test/integration/memory-leak.worker.ts @@ -1,4 +1,4 @@ -import { testInjector } from '@stryker-mutator/test-helpers'; +import { factory, testInjector } from '@stryker-mutator/test-helpers'; import { expect } from 'chai'; import { DryRunStatus, TestStatus } from '@stryker-mutator/api/test-runner'; @@ -34,7 +34,7 @@ async function main() { async function doDryRun(n = 40) { if (n > 0) { console.log(`Iterator count ${n}`); - const result = await mochaRunner.dryRun({ coverageAnalysis: 'off', timeout: 3000 }); + const result = await mochaRunner.dryRun(factory.dryRunOptions({ coverageAnalysis: 'off', timeout: 3000 })); if (result.status === DryRunStatus.Complete) { expect(result.tests).lengthOf(1); expect(result.tests[0].status).eq(TestStatus.Success); diff --git a/packages/mocha-runner/test/integration/sample-project-instrumented.it.spec.ts b/packages/mocha-runner/test/integration/sample-project-instrumented.it.spec.ts index 228c5934bd..7f3d28f3e3 100644 --- a/packages/mocha-runner/test/integration/sample-project-instrumented.it.spec.ts +++ b/packages/mocha-runner/test/integration/sample-project-instrumented.it.spec.ts @@ -111,14 +111,25 @@ describe('Running an instrumented project', () => { it('should be able to kill a mutant', async () => { const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '3' }) })); assertions.expectKilled(result); - expect(result.killedBy).eq('MyMath should be able to add two numbers'); + expect(result.killedBy).deep.eq(['MyMath should be able to add two numbers']); expect(result.failureMessage).eq('expected -3 to equal 7'); }); it('should bail after the first failed test', async () => { - const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '3' }) })); + const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '8' }) })); + assertions.expectKilled(result); + expect(result.killedBy).deep.eq(['MyMath should be able to recognize a negative number']); + expect(result.nrOfTests).eq(4); // 5th test shouldn't have run + }); + + it('should report all killedBy tests when bail is disabled', async () => { + const result = await sut.mutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '8' }), disableBail: true })); assertions.expectKilled(result); - expect(result.nrOfTests).eq(1); + expect(result.killedBy).deep.eq([ + 'MyMath should be able to recognize a negative number', + 'MyMath should be able to recognize that 0 is not a negative number', + ]); + expect(result.nrOfTests).eq(5); }); it('should be able to kill a mutant with filtered test', async () => { @@ -126,7 +137,7 @@ describe('Running an instrumented project', () => { factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '3' }), testFilter: ['MyMath should be able to add two numbers'] }) ); assertions.expectKilled(result); - expect(result.killedBy).eq('MyMath should be able to add two numbers'); + expect(result.killedBy).deep.eq(['MyMath should be able to add two numbers']); expect(result.failureMessage).eq('expected -3 to equal 7'); }); diff --git a/packages/mocha-runner/test/integration/sample-project.it.spec.ts b/packages/mocha-runner/test/integration/sample-project.it.spec.ts index 315ac09bf6..e88dcb2b85 100644 --- a/packages/mocha-runner/test/integration/sample-project.it.spec.ts +++ b/packages/mocha-runner/test/integration/sample-project.it.spec.ts @@ -67,11 +67,17 @@ describe('Running a sample project', () => { return sut.init(); }); - it('should only report the first failure', async () => { + it('should only report the first failure (bail)', async () => { const runResult = await sut.dryRun(factory.dryRunOptions()); assertions.expectCompleted(runResult); expect(countFailed(runResult)).to.be.eq(1); }); + + it('should report all failures with disableBail = true', async () => { + const runResult = await sut.dryRun(factory.dryRunOptions({ disableBail: true })); + assertions.expectCompleted(runResult); + expect(countFailed(runResult)).to.be.eq(2); + }); }); describe('when no tests are executed', () => { diff --git a/packages/mocha-runner/test/unit/mocha-test-runner.spec.ts b/packages/mocha-runner/test/unit/mocha-test-runner.spec.ts index 778bf73bdb..3b442de300 100644 --- a/packages/mocha-runner/test/unit/mocha-test-runner.spec.ts +++ b/packages/mocha-runner/test/unit/mocha-test-runner.spec.ts @@ -135,11 +135,16 @@ describe(MochaTestRunner.name, () => { expect(mochaAdapterMock.create).calledWithMatch({ timeout: false }); }); - it('should force bail', async () => { - await actDryRun(); + it('should set bail to true when disableBail is false', async () => { + await actDryRun(factory.dryRunOptions({ disableBail: false })); expect(mochaAdapterMock.create).calledWithMatch({ bail: true }); }); + it('should set bail to false when disableBail is true', async () => { + await actDryRun(factory.dryRunOptions({ disableBail: true })); + expect(mochaAdapterMock.create).calledWithMatch({ bail: false }); + }); + it("should don't set asyncOnly if asyncOnly is false", async () => { sut.mochaOptions['async-only'] = false; await actDryRun(); @@ -247,11 +252,21 @@ describe(MochaTestRunner.name, () => { StrykerMochaReporter.currentInstance = reporterMock; }); - it('should active the given mutant', async () => { + it('should activate the given mutant', async () => { await actMutantRun(factory.mutantRunOptions({ activeMutant: factory.mutant({ id: '42' }) })); expect(global.__stryker2__?.activeMutant).eq('42'); }); + it('should set bail to false when disableBail is true', async () => { + await actMutantRun(factory.mutantRunOptions({ disableBail: true })); + expect(mochaAdapterMock.create).calledWithMatch({ bail: false }); + }); + + it('should set bail to true when disableBail is false', async () => { + await actMutantRun(factory.mutantRunOptions({ disableBail: false })); + expect(mochaAdapterMock.create).calledWithMatch({ bail: true }); + }); + it('should use `grep` to when the test filter is specified', async () => { await actMutantRun(factory.mutantRunOptions({ testFilter: ['foo should be bar', 'baz should be qux'] })); expect(mocha.grep).calledWith(new RegExp('(foo should be bar)|(baz should be qux)')); @@ -267,7 +282,7 @@ describe(MochaTestRunner.name, () => { const result = await actMutantRun(); const expectedResult: KilledMutantRunResult = { failureMessage: 'foo was baz', - killedBy: 'foo should be bar', + killedBy: ['foo should be bar'], status: MutantRunStatus.Killed, nrOfTests: 2, }; diff --git a/packages/test-helpers/src/factory.ts b/packages/test-helpers/src/factory.ts index 325c531cf3..addb3e377a 100644 --- a/packages/test-helpers/src/factory.ts +++ b/packages/test-helpers/src/factory.ts @@ -254,11 +254,13 @@ export const mutantRunOptions = factoryMethod(() => ({ activeMutant: mutant(), timeout: 2000, sandboxFileName: '.stryker-tmp/sandbox123/file', + disableBail: false, })); export const dryRunOptions = factoryMethod(() => ({ coverageAnalysis: 'off', timeout: 2000, + disableBail: false, })); export const completeDryRunResult = factoryMethod(() => ({ @@ -282,7 +284,7 @@ export const timeoutDryRunResult = factoryMethod(() => ({ export const killedMutantRunResult = factoryMethod(() => ({ status: MutantRunStatus.Killed, - killedBy: 'spec1', + killedBy: ['spec1'], failureMessage: 'foo should be bar', nrOfTests: 1, })); diff --git a/tasks/instrument-test-resources.js b/tasks/instrument-test-resources.js index 6e0c833f0f..8785c07a54 100644 --- a/tasks/instrument-test-resources.js +++ b/tasks/instrument-test-resources.js @@ -34,9 +34,9 @@ async function main() { } /** - * - * @param {object} fromTo - * @param {'__stryker__' | '__stryker2__'} globalNamespace + * + * @param {object} fromTo + * @param {'__stryker__' | '__stryker2__'} globalNamespace */ async function instrument(fromTo, globalNamespace = INSTRUMENTER_CONSTANTS.NAMESPACE) { const files = Object.keys(fromTo).map(fileName => new File(fileName, fs.readFileSync(fileName))); @@ -44,7 +44,7 @@ async function instrument(fromTo, globalNamespace = INSTRUMENTER_CONSTANTS.NAMES out.files.forEach(file => { const toFileName = fromTo[file.name]; fs.writeFileSync(toFileName, `// This file is generated with ${path.relative(process.cwd(), __filename)}\n ${file.textContent.replace(new RegExp(INSTRUMENTER_CONSTANTS.NAMESPACE, 'g'), globalNamespace)}`); - + console.log(`✅ ${toFileName}`); }); }