diff --git a/.vscode/settings.json b/.vscode/settings.json index 7e54e9736..ac2a17725 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,4 +18,8 @@ "cSpell.words": [ "unmock" ], + "testing.openTesting": "neverOpen", + "jest.outputConfig": { + "clearOnRun": "terminal" + } } diff --git a/README.md b/README.md index 2d5b68d1e..b637800a8 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ Content - [rootPath](#rootpath) - [coverageFormatter](#coverageformatter) - [coverageColors](#coveragecolors) + - [outputConfig](#outputconfig) - [runMode](#runmode) - [autoRun](#autorun) - [testExplorer](#testexplorer) @@ -280,13 +281,14 @@ useDashedArgs| Determine if to use dashed arguments for jest processes |undefine |[parserPluginOptions](#parserpluginoptions)|Configure babel parser plugins|null|`"jest.parserPluginOptions": {decorators: 'legacy'}`| |[virtualFolders](#virtual-folders)|defines multiple jest runs in a given vscode workspace folder|undefined|`"jest.virtualFolders": "[{"name": "front-end", "rootPath': "packages/front-end"}, {"name": "back-end", "rootPath': "packages/back-end"} ]"`| >= v6.0.0 |**UX**| -|[runMode](#runmode)|Controls most test UX, including when tests should be run, output management, etc|undefined|`"jest.runMode": "watch"` or `"jest.runMode": "on-demand"` or `"jest.runMode": {"type": "on-demand", "deferred": true}`| >= v6.0.2 -|autoClearTerminal|Clear the terminal output at the start of any new test run.|false|`"jest.autoClearTerminal": true`| >= v6.0.0 -|[testExplorer](#testexplorer) |Configure jest test explorer|null|`{"showInlineError": "true"}`| -|:x: [autoRun](#autorun)|Controls when and what tests should be run|undefined|`"jest.autoRun": "off"` or `"jest.autoRun": "watch"` or `"jest.autoRun": {"watch": false, "onSave":"test-only"}`| <= v6.0.2 (replaced by runMode) -|:x: [autoRevealOutput](#autoRevealOutput)|Determine when to show test output|"on-run"|`"jest.autoRevealOutput": "on-exec-error"`| <= v6.0.2 (replaced by runMode) +|[outputConfig](#outputconfig) 💼|Controls test output experience across the whole workspace.|undefined|`"jest.outputConfig": "neutral"` or `"jest.outputConfig": {"revealOn": "run", "revealWithFocus": "terminal", "clearOnRun": 'terminal"`| >= v6.1.0 +|[runMode](#runmode)|Controls most test UX, including when tests should be run, output management, etc|undefined|`"jest.runMode": "watch"` or `"jest.runMode": "on-demand"` or `"jest.runMode": {"type": "on-demand", "deferred": true}`| >= v6.1.0 +|:x: autoClearTerminal|Clear the terminal output at the start of any new test run.|false|`"jest.autoClearTerminal": true`| >= v6.0.0 < 6.1 (replaced by outputConfig) +|:x: [testExplorer](#testexplorer) |Configure jest test explorer|null|`{"showInlineError": "true"}`| < 6.1.0 (replaced by runMode) +|:x: [autoRun](#autorun)|Controls when and what tests should be run|undefined|`"jest.autoRun": "off"` or `"jest.autoRun": "watch"` or `"jest.autoRun": {"watch": false, "onSave":"test-only"}`| <= v6.1.0 (replaced by runMode) +|:x: [autoRevealOutput](#autoRevealOutput)|Determine when to show test output|"on-run"|`"jest.autoRevealOutput": "on-exec-error"`| <= v6.1.0 (replaced by outputConfig) |**Coverage**| -|:x: showCoverageOnLoad|Show code coverage when extension starts|false|`"jest.showCoverageOnLoad": true`| <= v6.0.2 (replaced by runMode) +|:x: showCoverageOnLoad|Show code coverage when extension starts|false|`"jest.showCoverageOnLoad": true`| <= v6.1.0 (replaced by runMode) |[coverageFormatter](#coverageFormatter)|Determine the coverage overlay style|"DefaultFormatter"|`"jest.coverageFormatter": "GutterFormatter"`| |[coverageColors](#coverageColors)|Coverage indicator color override|undefined|`"jest.coverageColors": { "uncovered": "rgba(255,99,71, 0.2)", "partially-covered": "rgba(255,215,0, 0.2)"}`| |**Misc**| @@ -354,16 +356,133 @@ for example: --- +#### outputConfig + +The `outputConfig` controls the Jest output experience by specifying when and where to create, display, and clear the output content. It supports 2 output panels: `TEST RESULTS` and `TERMINAL`. The `TEST RESULTS` panel displays test results in the order they were run, while the `TERMINAL` panel organizes outputs by workspace folder. `TERMINAL` panel also contains the non-test run outputs, such as [quick-fix link](quick-fix-chooser), extension auto-config info and tips. + +**Type Definitions** +```ts +// typescript type definition +export interface JestRawOutputSetting { + revealOn?: 'run' | 'error' | 'demand'; + revealWithFocus?: 'terminal' | 'test-results' | 'none'; + clearOnRun?: 'both' | 'terminal' | 'test-results' | 'none'; +} +export type JestPredefinedOutputSetting = 'neutral' | 'terminal-based' | 'test-results-based'; +export type JestOutputSetting = JestPredefinedOutputSetting | JestRawOutputSetting; +``` +**JestOutputSetting** +This setting can be one of the predefined types or a custom object. + +- **Predefined OutputConfig Settings** (JestPredefinedOutputSetting): + Predefined outputConfig|Description|JestRawOutputSetting| + |:---:|---|---| + |"neutral"| A passive setting that does not favor either panel | {revealOn: "run", revealWithFocus: "none", clearOnRun: "none"} | + |"terminal-based"| A terminal-centric output experience|{revealOn: "run", revealWithFocus: "terminal", clearOnRun: "none"}| + |"test-results-based"|A test-results-centric output experience|{revealOn: "run", revealWithFocus: "test-results", clearOnRun: "none"} | + +- **Custom Config Object** (JestRawOutputSetting): + - **revealOn**: Create or make output window available (without automatic focus switch). Possible values: + 1. "run": On test starts. (default) + 2. "error": On test failure. + 3. "demand": On manual trigger. + - **revealWithFocus**: When revealing the output, which panel should have the focus, i.e. panel will become active. Possible values: + 1. "terminal": Show output in terminal panel and focus on it. + 2. "test-results": Show output in test results panel and focus on it. + 3. "none": No automatic focus change. (default) + - **clearOnRun**: Determine if to automatically clear the output before each test run. Possible values: + 1. "both": Clear both terminal and test results panel. + 2. "terminal": Clear the terminal panel only. + 3. "test-results": clear the test results panel only. + 4. "none": Do not clear any panel. (default) + (_**Note**: As of the current version, the testing framework does not support the clearing of the "TEST RESULTS" panel without side effects. The closest available command also clears all test item statuses, which may not be desirable. We are aware of this limitation and will raise the issue with the VS Code team._) + +**Handling Conflicts with "TEST RESULTS" panel** + + +_The Problem_ + +The behavior of the "TEST RESULTS" panel is influenced by VSCode's native `"testing.openTesting"` setting. This can cause inconsistencies with your `"jest.outputConfig"` settings. + +For instance, if you set `"jest.outputConfig": {"revealWithFocus": "none"}` to prevent automatic focus changes, but leave `"testing.openTesting"` at its default value of `"openOnTestStart"`, the "TEST RESULTS" panel will still automatically switch focus whenever tests run. + +_The Universal Solution_ + +For a consistent Jest output experience, the simplest solution is to set `"testing.openTesting": "neverOpen"`. This allows the extension to manage the "TEST RESULTS" and "TERMINAL" panels together using `"jest.outputConfig"` alone. + +_Further Customization_ + +However, if you prefer "TEST RESULTS" and "TERMINAL" panels to behave differently and don't mind managing 2 settings yourself, you could play with different combinations. + +For instance, if `"testing.openTesting"` is set to `"openOnTestFailure"`, and you want your terminal panel to still reveal when any tests run, your setting would look like this: `"jest.outputConfig": {revealWithFocus: "test-results"}` + +_Built-in Validation_ + +The extension also features built-in conflict detection and quick fixes to assist. + +**Examples** +- Choose a passive output experience that is identical to the previous version. + ```json + "testing.openTesting": "neverOpen", + "jest.outputConfig": "neutral" + ``` +- Choose a terminal-based experience and switch focus to it when test run starts. + ```json + "testing.openTesting": "neverOpen", + "jest.outputConfig": "terminal-based" + ``` +- Choose a test-results-based experience and switch focus to it when test fails. + ```json + "testing.openTesting": "neverOpen", + "jest.outputConfig": { + "revealOn": "error", + "revealWithFocus": "test-results", + } + ``` + alternatively: + ```json + "testing.openTesting": "openOnTestFailure", + "jest.outputConfig": { + "revealOn": "error", + "revealWithFocus": "test-results" + } + ``` +- Clear the terminal output on each run but do not automatically switch focus to any panel. + ```json + "testing.openTesting": "neverOpen", + "jest.outputConfig": { + "clearOnRun": "terminal" + } + ``` + +**Migration Guide** + + +Migrating to the new `"jest.outputConfig"` can require some manual adjustments, especially if you're working in a multi-root workspace. Here are some guidelines to help with the transition: + +1. **Workspace Level vs Workspace-Folder Level**: The new `"jest.outputConfig"` is a workspace-level setting, unlike legacy settings like `"jest.autoClearTerminal"` and `"jest.autoRevealOutput"`, which are workspace-folder level settings. + +2. **Backward Compatibility**: If no `"jest.outputConfig"` is defined in your settings.json, the extension will attempt to generate a backward-compatible outputConfig in memory. This uses the `"testing.openTesting"` setting and any legacy settings (`"jest.autoClearTerminal"`, `"jest.autoRevealOutput"`) you might have. Note that this might only work for single-root workspaces. + +3. **Migration Steps**: + - Use the `"Jest: Save Current Output Config"` command from the command palette to update your settings.json. + - (optional) Fix warning: The save does not include `"testing.openTesting"`, so you might see the conflict warning message. You can either use the "Quick Fix" action or adjust the `settings.json` manually (see [handling conflict](#outputconfig-conflict)). + - Finally, remove any deprecated settings. + +By following these guidelines, you should be able to smoothly transition to using `"jest.outputConfig"`. + +--- + #### runMode The `runMode` controls test UX, determining when tests should run, and housing the common run-time toggles like coverage. -**runMode type** +**Type Definitions** ```ts +// typescript types interface JestRunModeOptions { runAllTestsOnStartup?: boolean; coverage?: boolean; - revealOutput?: 'on-run' | 'on-exec-error' | 'on-demand'; deferred?: boolean; } export type JestRunMode = JestRunModeOptions & ( @@ -380,17 +499,13 @@ export type JestRunMode = JestRunModeOptions & ( - **JestRunModeOptions**: Options applicable for all `runMode` types: - **runAllTestsOnStartup**: Want to run all tests as soon as the extension starts? Use this. - **coverage**: To get those coverage metrics, turn this on. - - **revealOutput**: Control when your test output window shows up: - - "on-run": Default behavior, pops up as tests begin. - - "on-exec-error": Shows up only if there's an execution glitch. - - "on-demand": Displays only when you ask it to via the UI. - **deferred**: Usually, the extension sets things up before any test run, verifying the Jest env and discovering tests. This process is generally quick, but if you've got a hefty project or your setup isn't Jest-ready, this option helps: - `true`: Suspend the initial setup. Most UI components remain active. If you toggle `runMode.deferred` or manually trigger a test run, the setup will resume, deferred option will be set to false, and the runMode will operate as usual. - `false`: Default behavior, the setup process gets going before any test run.
- 🤔 defer vs. disable? + defer vs. disable? 🤔 📌 Note: There's a distinction between the deferred mode and disabling the extension via "jest.enable: false". Disabling the extension will remove all test features for the given workspace-folder. In contrast, deferred just delays the setup but most UI features are still visible. @@ -408,7 +523,7 @@ The following are the predefined `runMode` configurations for convenience. They |"on-demand"|run tests on-demand through UI | {type: "on-demand", revealOutput: "on-run"} | |"deferred"|defer test run and discovery until the first on-demand run | {type: "on-demand", revealOutput: "on-run", deferred: true } | -**runMode Examples** +**Examples** - Run jest with watch mode - the default runMode if none is specified. ```json "jest.runMode": "watch" @@ -450,15 +565,15 @@ While the concepts of performance and automation are generally clear, "completen 3. Tests bearing dynamic names, like those using test.each with variables or template literals, won't be translated. As a result, they must be executed through higher-level constructs, such as describe blocks with static names or entire test suites. -**runMode migration** +**Migration Guide** -Starting from v6.0.2, if no runMode is defined in settings.json, the extension will automatically generate one using legacy settings (`autoRun`, `autoRevealOutput`, `showCoverageOnLoad`). To migrate, simply use the `"Jest: Save Current RunMode"` command from the command palette to update the setting, then remove the legacy settings. +Starting from v6.1.0, if no runMode is defined in settings.json, the extension will automatically generate one using legacy settings (`autoRun`, `autoRevealOutput`, `showCoverageOnLoad`). To migrate, simply use the `"Jest: Save Current RunMode"` command from the command palette to update the setting, then remove the deprecated settings. --- #### autoRun
- As of v6.0.2, runMode has superseded autoRun. For transition details, please refer to the runMode migration. + Note: As of v6.1.0, autoRun will be replaced by runMode. For transition details, please refer to the runMode migration.
AutoRun controls when tests should be executed automatically. @@ -586,7 +701,7 @@ Default is `"jest.monitorLongRun":60000` (1 minute) #### autoRevealOutput
- As of v6.0.2, runMode has superseded autoRevealOutput. For transition details, please refer to the runMode migration. + As of v6.1.0, runMode has superseded autoRevealOutput. For transition details, please refer to the runMode migration.
```ts @@ -781,7 +896,8 @@ This extension contributes the following commands and can be accessed via [Comma |Jest: Run All Tests (Select Workspace)| run all tests for the selected workspace|multi-root workspace |Jest: Run All Tests in Current Workspace| run all tests for the current workspace based on the active editor| always |Jest: Toggle Coverage for Current Workspace| toggle coverage mode for the current workspace based on the active editor| always -|Jest: Save Current RunMode| update runMode in `settings.json` based on the current value| always (>= 6.0.2) +|Jest: Save Current RunMode| update `"jest.runMode"` in `settings.json` based on the current value| always (>= 6.1.0) +|Jest: Save Current Output Config| update `"jest.outputConfig"` in `settings.json` based on the current value| always (>= 6.1.0) |Jest: Setup Extension| start the setup tool|always| In addition, TestExplorer also exposed many handy commands, see the full list by searching for `testing` in [vscode keyboard shortcuts editor](https://code.visualstudio.com/docs/getstarted/keybindings#_keyboard-shortcuts-editor). One can assign/change keyboard shortcut to any of these commands, see [vscode Key Bindings](https://code.visualstudio.com/docs/getstarted/keybindings) for more details. diff --git a/jest.config.js b/jest.config.js index 43b877ea8..b93e94829 100644 --- a/jest.config.js +++ b/jest.config.js @@ -23,7 +23,7 @@ module.exports = { 'debug', '@babel/template', 'graceful-fs', - '@babel/core', + '@babel/types', ], moduleNameMapper: { '\\.(svg)$': '/tests/fileMock.ts', diff --git a/package.json b/package.json index 3dff3f4fd..6bbfa1c86 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-jest", "displayName": "Jest", "description": "Use Facebook's Jest With Pleasure.", - "version": "6.0.2", + "version": "6.1.0", "publisher": "Orta", "engines": { "vscode": "^1.68.1" @@ -81,7 +81,9 @@ "jest.autoClearTerminal": { "description": "Clear the terminal output at the start of any new test run.", "type": "boolean", - "scope": "resource" + "scope": "resource", + "markdownDeprecationMessage": "**Deprecated**: Please use [outputConfig](https://github.com/jest-community/vscode-jest#outputconfig) instead.", + "deprecationMessage": "Deprecated: Please use jest.outputConfig instead." }, "jest.rootPath": { "description": "The path to your frontend src folder", @@ -156,7 +158,9 @@ "markdownDescription": "Configure jest TestExplorer. See valid [formats](https://github.com/jest-community/vscode-jest/blob/master/README.md#testexplorer) or [how to use test explorer](https://github.com/jest-community/vscode-jest/blob/master/README.md#how-to-use-the-test-explorer) for more details", "type": "object", "default": null, - "scope": "resource" + "scope": "resource", + "markdownDeprecationMessage": "**Deprecated**: Please use [runMode](https://github.com/jest-community/vscode-jest/blob/master/README.md#runmode) instead.", + "deprecationMessage": "Deprecated: Please use jest.runMode instead." }, "jest.monitorLongRun": { "markdownDescription": "Enable monitoring for long running test process. See valid [monitorLongRun](https://github.com/jest-community/vscode-jest/blob/master/README.md#monitorLongRun) for details", @@ -182,11 +186,11 @@ "disable auto show test output" ], "scope": "resource", - "markdownDeprecationMessage": "**Deprecated**: Please use [runMode](https://github.com/jest-community/vscode-jest/blob/master/README.md#runmode) instead.", - "deprecationMessage": "Deprecated: Please use jest.runMode instead." + "markdownDeprecationMessage": "**Deprecated**: Please use [outputConfig](https://github.com/jest-community/vscode-jest#outputconfig) instead.", + "deprecationMessage": "Deprecated: Please use jest.outputConfig instead." }, "jest.parserPluginOptions": { - "markdownDescription": "Configure babel parser plugins. See valid [format](https://github.com/jest-community/vscode-jest/blob/master/README.md#parserpluginoptions)", + "markdownDescription": "Configure babel parser plugins. See valid [format](https://github.com/jest-community/vscode-jest#parserpluginoptions)", "type": "object", "default": null, "scope": "resource" @@ -208,6 +212,84 @@ "type": "object" } }, + "jest.outputConfig": { + "scope": "window", + "type": [ + "string", + "object" + ], + "markdownDescription": "Control jest output preference. See details in [outputConfig](https://github.com/jest-community/vscode-jest#outputconfig).", + "default": null, + "oneOf": [ + { + "type": "string", + "enum": [ + "neutral", + "terminal-based", + "test-results-based" + ], + "enumDescriptions": [ + "A passive and neutral config, will not automatically change active panel nor clear output.", + "Switch to terminal panel when running tests.", + "Switch to test-results panel when running tests." + ], + "description": "Specifies the predefined common outputConfig in a string form." + }, + { + "type": "object", + "properties": { + "revealOn": { + "type": "string", + "enum": [ + "run", + "error", + "demand" + ], + "enumDescriptions": [ + "Reveal the output upon test run.", + "Reveal the output upon test error.", + "Reveal the output on demand." + ], + "default": "run", + "description": "Determines when to reveal the test run output. Default is 'run'." + }, + "revealWithFocus": { + "type": "string", + "enum": [ + "none", + "terminal", + "test-results" + ], + "enumDescriptions": [ + "Do not change focus when revealing output.", + "Switch to terminal when revealing output.", + "Switch to test-results panel when revealing output." + ], + "default": "none", + "description": "Specifies which output panel, if any, to switch focus to when revealing. Default is 'none'." + }, + "clearOnRun": { + "type": "string", + "enum": [ + "none", + "both", + "terminal", + "test-results" + ], + "enumDescriptions": [ + "Do not automatically clear the output before each run.", + "Clear both the terminal and test results output before each run.", + "Clear the terminal output before each run.", + "Clear the test results output before each run." + ], + "default": "none", + "description": "Specifies which output, if any, to be cleared before each run. Default is 'none'." + } + }, + "description": "Specifies a custom output config in an object form." + } + ] + }, "jest.runMode": { "markdownDescription": "Control when to run jest tests and present the results. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)", "default": null, @@ -243,14 +325,9 @@ "type": "boolean", "description": "Specifies whether to collect and report coverage information." }, - "revealOutput": { - "type": "string", - "enum": [ - "on-run", - "on-exec-error", - "on-demand" - ], - "description": "Determines when to reveal the test run output." + "showInlineError": { + "type": "boolean", + "description": "Specify if to enable inline error display in test file editor" }, "deferred": { "type": "boolean", @@ -325,6 +402,10 @@ "command": "io.orta.jest.workspace.save-run-mode", "title": "Jest: Save Current RunMode" }, + { + "command": "io.orta.jest.save-output-config", + "title": "Jest: Save Current Output Config" + }, { "command": "io.orta.jest.run-all-tests", "title": "Jest: Run All Tests" @@ -582,13 +663,13 @@ "dependencies": { "istanbul-lib-coverage": "^3.2.0", "istanbul-lib-source-maps": "^4.0.1", - "jest-editor-support": "^31.1.1" + "jest-editor-support": "^31.1.2" }, "devDependencies": { "@types/fs-extra": "^11.0.2", "@types/istanbul-lib-coverage": "^2.0.4", "@types/istanbul-lib-source-maps": "^4.0.1", - "@types/jest": "^29.2.5", + "@types/jest": "^29.5.6", "@types/node": "^18.11.18", "@typescript-eslint/eslint-plugin": "^5.48.1", "@typescript-eslint/parser": "^5.48.1", @@ -600,7 +681,7 @@ "eslint-plugin-prefer-arrow": "^1.2.3", "eslint-plugin-prettier": "^4.2.1", "fs-extra": "^11.1.1", - "jest": "^29.3.1", + "jest": "^29.7", "jest-snapshot": "^27.2.0", "prettier": "^2.8.2", "raw-loader": "^4.0.1", diff --git a/src/JestExt/core.ts b/src/JestExt/core.ts index 1fe27aeed..7a2719a25 100644 --- a/src/JestExt/core.ts +++ b/src/JestExt/core.ts @@ -43,6 +43,7 @@ import { WorkspaceManager, isInFolder } from '../workspace-manager'; import { ansiEsc, JestOutputTerminal } from './output-terminal'; import { QuickFixActionType } from '../quick-fix'; import { executableTerminalLinkProvider } from '../terminal-link-provider'; +import { outputManager } from '../output-manager'; interface RunTestPickItem extends vscode.QuickPickItem { id: DebugTestIdentifier; @@ -195,12 +196,7 @@ export class JestExt { } private enableOutputOnRun(): void { - if ( - !this.extContext.settings.runMode.config.revealOutput || - this.extContext.settings.runMode.config.revealOutput === 'on-run' - ) { - this.output.enable(); - } + outputManager.showOutputOn('run', this.output); } private setupRunEvents(events: JestSessionEvents): void { events.onRunEvent.event((event: JestRunEvent) => { @@ -223,14 +219,14 @@ export class JestExt { case 'exit': if (event.error) { this.updateStatusBar({ state: 'exec-error' }); - if (!event.process.userData?.errorReported) { + if (!event.process.userData?.execError) { this.outputActionMessages( `Jest process exited unexpectedly: ${event.error}`, ['wizard', 'defer', 'disable-folder', 'help'], true, event.error ); - event.process.userData = { ...(event.process.userData ?? {}), errorReported: true }; + event.process.userData = { ...(event.process.userData ?? {}), execError: true }; } } else { this.updateStatusBar({ state: 'done' }); @@ -242,6 +238,13 @@ export class JestExt { } break; } + case 'test-error': { + if (!event.process.userData?.testError) { + outputManager.showOutputOn('test-error', this.output); + event.process.userData = { ...(event.process.userData ?? {}), testError: true }; + } + break; + } case 'long-run': { this.outputActionMessages(this.longRunMessage(event), ['help-long-run'], false); break; @@ -298,10 +301,6 @@ export class JestExt { }); return; } - const readyState = await this.validateJestCommandLine(); - if (readyState !== 'pass') { - return; - } this.dirtyFiles.clear(); this.resetStatusBar(); @@ -315,6 +314,11 @@ export class JestExt { this.testProvider?.dispose(); this.testProvider = new JestTestProvider(this.getExtExplorerContext()); + const readyState = await this.validateJestCommandLine(); + if (readyState !== 'pass') { + return; + } + await this.processSession.start(); this.events.onTestSessionStarted.fire({ ...this.extContext, session: this.processSession }); @@ -395,8 +399,7 @@ export class JestExt { } private updateOutputSetting(settings: PluginResourceSettings): void { - this.output.revealOnError = - !settings.runMode.config.deferred && settings.runMode.config.revealOutput === 'on-exec-error'; + this.output.revealOnError = !settings.runMode.config.deferred; this.output.close(); } private testResultProviderOptions(settings: PluginResourceSettings): TestResultProviderOptions { @@ -412,13 +415,7 @@ export class JestExt { newSettings ?? this.getExtensionResourceSettings(this.extContext.workspace); // output - if ( - this.extContext.settings.runMode.config.revealOutput !== - updatedSettings.runMode.config.revealOutput || - this.extContext.settings.runMode.config.deferred !== updatedSettings.runMode.config.deferred - ) { - this.updateOutputSetting(updatedSettings); - } + this.updateOutputSetting(updatedSettings); // TestResultProvider this.testResultProvider.options = this.testResultProviderOptions(updatedSettings); diff --git a/src/JestExt/helper.ts b/src/JestExt/helper.ts index 3606334e1..703d6ad4d 100644 --- a/src/JestExt/helper.ts +++ b/src/JestExt/helper.ts @@ -9,9 +9,7 @@ import { TestExplorerConfig, NodeEnv, MonitorLongRun, - TestExplorerConfigLegacy, JestExtAutoRunSetting, - AutoRevealOutputType, createJestSettingGetter, JestRunModeType, JestRunMode, @@ -82,31 +80,6 @@ export const createJestExtContext = ( }; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const isTestExplorerConfigLegacy = (arg: any): arg is TestExplorerConfigLegacy => - typeof arg.enabled === 'boolean'; - -const DefaultTestExplorerSetting: TestExplorerConfig = {}; -const adaptTestExplorer = ( - setting?: TestExplorerConfig | TestExplorerConfigLegacy -): TestExplorerConfig => { - if (!setting) { - return DefaultTestExplorerSetting; - } - - if (isTestExplorerConfigLegacy(setting)) { - if (setting.enabled === false || setting.showClassicStatus === true) { - const message = `Invalid TestExplorer setting: please check README to upgrade. Will use the default setting instead`; - console.error(message); - vscode.window.showWarningMessage(message); - return DefaultTestExplorerSetting; - } - return { showInlineError: setting.showInlineError }; - } - - return setting; -}; - export const getExtensionResourceSettings = ( workspaceFolder: vscode.WorkspaceFolder ): PluginResourceSettings => { @@ -114,20 +87,16 @@ export const getExtensionResourceSettings = ( const deprecatedSettings: DeprecatedPluginResourceSettings = { showCoverageOnLoad: getSetting('showCoverageOnLoad') ?? false, - autoRevealOutput: getSetting('autoRevealOutput') ?? 'on-run', autoRun: getSetting('autoRun'), + testExplorer: getSetting('testExplorer'), }; return { jestCommandLine: getSetting('jestCommandLine'), - autoClearTerminal: getSetting('autoClearTerminal') ?? false, rootPath: toAbsoluteRootPath(workspaceFolder, getSetting('rootPath')), coverageFormatter: getSetting('coverageFormatter') ?? 'DefaultFormatter', debugMode: getSetting('debugMode'), coverageColors: getSetting('coverageColors'), - testExplorer: adaptTestExplorer( - getSetting('testExplorer') - ), nodeEnv: getSetting('nodeEnv') ?? undefined, shell: new RunShell(getSetting('shell')), monitorLongRun: getSetting('monitorLongRun') ?? undefined, diff --git a/src/JestExt/output-terminal.ts b/src/JestExt/output-terminal.ts index 3f9a55824..e308728f2 100644 --- a/src/JestExt/output-terminal.ts +++ b/src/JestExt/output-terminal.ts @@ -1,5 +1,6 @@ import * as vscode from 'vscode'; import { ExtErrorDef } from '../errors'; +import { outputManager } from '../output-manager'; /** * This class write out Jest run output to vscode.Terminal @@ -118,7 +119,7 @@ export class ExtOutputTerminal implements JestExtOutput { this.appendRaw(text); if (isErrorOutputType(opt) && (this.enabled || this.revealOnError)) { - this.show(); + outputManager.showOutputOn('exec-error', this); } return text; } diff --git a/src/JestExt/process-listeners.ts b/src/JestExt/process-listeners.ts index a9385993b..ccbd92ed0 100644 --- a/src/JestExt/process-listeners.ts +++ b/src/JestExt/process-listeners.ts @@ -168,14 +168,15 @@ const WATCH_IS_NOT_SUPPORTED_REGEXP = /^s*--watch is not supported without git\/hg, please use --watchAlls*/im; const RUN_EXEC_ERROR = /onRunComplete: execError: (.*)/im; const RUN_START_TEST_SUITES_REGEX = /onRunStart: numTotalTestSuites: ((\d)+)/im; -const CONTROL_MESSAGES = /^(onRunStart|onRunComplete|Test results written to)[^\n]+\n/gim; +const CONTROL_MESSAGES = + /^(onRunStart|onRunComplete|onTestFileResult|Test results written to)[^\n]+\n/gim; /** * monitor for long test run, default is 1 minute */ export const DEFAULT_LONG_RUN_THRESHOLD = 60000; export class LongRunMonitor { - private timer: NodeJS.Timer | undefined; + private timer: NodeJS.Timeout | undefined; public readonly thresholdMs: number; constructor(private callback: () => void, private logging: Logging, option?: MonitorLongRun) { if (option == null) { @@ -298,6 +299,7 @@ export class RunTestListener extends AbstractProcessListener { const cleaned = this.cleanupOutput(raw); this.handleRunStart(process, message); + this.handleTestFileResult(process, message); this.onRunEvent.fire({ type: 'data', process, text: message, raw: cleaned }); @@ -322,6 +324,11 @@ export class RunTestListener extends AbstractProcessListener { this.onRunEvent.fire({ type: 'start', process }); } } + protected handleTestFileResult(process: JestProcess, output: string): void { + if (output.includes('onTestFileResult: encountered errors')) { + this.onRunEvent.fire({ type: 'test-error', process }); + } + } protected handleRunComplete(process: JestProcess, output: string): void { if (output.includes('onRunComplete')) { this.runEnded(); diff --git a/src/JestExt/run-mode.ts b/src/JestExt/run-mode.ts index 5dc8e85b9..d229c1d64 100644 --- a/src/JestExt/run-mode.ts +++ b/src/JestExt/run-mode.ts @@ -92,11 +92,11 @@ export class RunMode { private getDefaultRunMode(setting: JestPredefinedRunModeType): JestRunMode { switch (setting.toLocaleLowerCase()) { case 'watch': - return { type: 'watch', revealOutput: 'on-run' }; + return { type: 'watch' }; case 'on-save': - return { type: 'on-save', revealOutput: 'on-run' }; + return { type: 'on-save' }; case 'on-demand': - return { type: 'on-demand', revealOutput: 'on-run' }; + return { type: 'on-demand' }; case 'deferred': return { ...this.getDefaultRunMode('on-demand'), @@ -177,19 +177,11 @@ export class RunMode { if (legacySettings?.showCoverageOnLoad) { base.coverage = true; } - if (legacySettings?.autoRevealOutput) { - switch (legacySettings.autoRevealOutput) { - case 'on-run': - case 'on-exec-error': - base.revealOutput = legacySettings.autoRevealOutput; - break; - case 'off': - base.revealOutput = 'on-demand'; - break; - default: - throw new Error(`invalid autoRevealOutput ${legacySettings.autoRevealOutput}`); - } + + if (legacySettings?.testExplorer?.showInlineError) { + base.showInlineError = true; } + return base; } catch (e) { // sever user error, while we can fallback to the default, it might not be what the user intended. @@ -232,7 +224,7 @@ export class RunMode { ? vscode.Uri.file(context.asAbsolutePath('icons/pause-on-20.svg')) : new vscode.ThemeIcon('debug-pause'); const runModeSchemaUri = vscode.Uri.file( - context.asAbsolutePath('syntaxes/jestRunModeSchema.json') + context.asAbsolutePath('syntaxes/ExtSettingsSchema.json') ); const deferredButton = { iconPath: deferredIcon, @@ -396,11 +388,10 @@ const showRunModeQuickPick = async ( const RunModeEditInstruction = ` // Save the file to accept the change. // close without saving to cancel the change. -// RunMode reference: https://github.com/jest-community/vscode-jest/blob/master/README.md#runmode +// RunMode reference: https://github.com/jest-community/vscode-jest#runmode `; export class RunModeEditor { - // private doc?: vscode.TextDocument; private disposables: vscode.Disposable[] = []; private docUri = vscode.Uri.parse(`${NoOpFileSystemProvider.scheme}://workspace/runMode.json`); diff --git a/src/JestExt/types.ts b/src/JestExt/types.ts index 4189a2dce..ae2f8599b 100644 --- a/src/JestExt/types.ts +++ b/src/JestExt/types.ts @@ -35,6 +35,7 @@ export type JestRunEvent = RunEventBase & ( | { type: 'scheduled' } | { type: 'data'; text: string; raw?: string; newLine?: boolean; isError?: boolean } + | { type: 'test-error' } | { type: 'process-start' } | { type: 'start' } | { type: 'end'; error?: string } diff --git a/src/JestProcessManagement/types.ts b/src/JestProcessManagement/types.ts index e126250ab..de803c5e5 100644 --- a/src/JestProcessManagement/types.ts +++ b/src/JestProcessManagement/types.ts @@ -1,7 +1,8 @@ +import * as vscode from 'vscode'; import { RunnerEvent } from 'jest-editor-support'; import { JestTestProcessType } from '../Settings'; import { JestProcess } from './JestProcess'; -import { JestTestRun } from '../test-provider/test-provider-helper'; +import { JestTestRun } from '../test-provider/jest-test-run'; export interface JestProcessListener { onEvent: (process: JestProcess, event: RunnerEvent, ...args: unknown[]) => unknown; @@ -9,7 +10,9 @@ export interface JestProcessListener { export type JestProcessStatus = 'pending' | 'running' | 'stopping' | 'stopped'; export interface UserDataType { run?: JestTestRun; - errorReported?: boolean; + execError?: boolean; + testError?: boolean; + testItem?: vscode.TestItem; } export interface JestProcessInfo { readonly id: string; diff --git a/src/Settings/helper.ts b/src/Settings/helper.ts new file mode 100644 index 000000000..b1200cce4 --- /dev/null +++ b/src/Settings/helper.ts @@ -0,0 +1,57 @@ +import * as vscode from 'vscode'; +import { GetConfigFunction, VirtualFolderSettings, VirtualFolderSettingKey } from './types'; +import { isVirtualWorkspaceFolder } from '../virtual-workspace-folder'; + +/** + * Returns a function that retrieves Jest configuration settings for a given workspace folder. + * If the workspace folder is a virtual folder, it first checks for the corresponding virtual folder setting. + * If the setting is not found, it falls back to the workspace setting. + * @param workspaceFolder The workspace folder to retrieve Jest configuration settings for. + * @returns A function that takes a `VirtualFolderSettingKey` as an argument and returns the corresponding setting value. + */ +export const createJestSettingGetter = ( + workspaceFolder: vscode.WorkspaceFolder +): GetConfigFunction => { + const config = vscode.workspace.getConfiguration('jest', workspaceFolder.uri); + let vFolder: VirtualFolderSettings | undefined; + + if (isVirtualWorkspaceFolder(workspaceFolder)) { + const virtualFolders = config.get('virtualFolders'); + vFolder = virtualFolders?.find((v) => v.name === workspaceFolder.name); + if (!vFolder) { + throw new Error(`[${workspaceFolder.name}] is missing corresponding virtual folder setting`); + } + } + + // get setting from virtual folder first, fallback to workspace setting if not found + const getSetting = (key: VirtualFolderSettingKey): T | undefined => { + if (key === 'enable') { + // if any of the folders is disabled, then the whole workspace is disabled + return (config.get(key) !== false && vFolder?.enable !== false) as T; + } + + return (vFolder?.[key] as T) ?? config.get(key); + }; + return getSetting; +}; + +// get setting from virtual folder first, fallback to workspace setting if not found +export const updateSetting = async ( + workspaceFolder: vscode.WorkspaceFolder, + key: VirtualFolderSettingKey, + value: unknown +): Promise => { + const config = vscode.workspace.getConfiguration('jest', workspaceFolder.uri); + if (!isVirtualWorkspaceFolder(workspaceFolder)) { + await config.update(key, value); + return; + } + const virtualFolders = config.get('virtualFolders'); + const vFolder = virtualFolders?.find((v) => v.name === workspaceFolder.name); + if (!vFolder) { + throw new Error(`[${workspaceFolder.name}] is missing corresponding virtual folder setting`); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (vFolder as any)[key] = value; + await config.update('virtualFolders', virtualFolders); +}; diff --git a/src/Settings/index.ts b/src/Settings/index.ts index 55cc0060c..28f3a81f4 100644 --- a/src/Settings/index.ts +++ b/src/Settings/index.ts @@ -1,146 +1,2 @@ -import * as vscode from 'vscode'; -import { CoverageColors } from '../Coverage/CoverageOverlay'; -import { JESParserPluginOptions, ProjectWorkspace } from 'jest-editor-support'; -import { RunShell } from '../JestExt/run-shell'; -import { isVirtualWorkspaceFolder } from '../virtual-workspace-folder'; -import { RunMode } from '../JestExt/run-mode'; - -export type JestTestProcessType = - | 'all-tests' - | 'watch-tests' - | 'watch-all-tests' - | 'by-file' - | 'by-file-test' - | 'not-test' - | 'by-file-test-pattern' - | 'by-file-pattern'; - -export type OnStartupType = Extract[]; -export type OnSaveFileType = 'test-file' | 'test-src-file'; -export type JestExtAutoRunShortHand = 'default' | 'watch' | 'on-save' | 'legacy' | 'off'; - -export type JestExtAutoRunConfig = - | { watch: true; onStartup?: OnStartupType } - | { - watch: false; - onStartup?: OnStartupType; - onSave?: OnSaveFileType; - }; -export type JestExtAutoRunSetting = JestExtAutoRunShortHand | JestExtAutoRunConfig; - -interface JestRunModeOptions { - runAllTestsOnStartup?: boolean; - coverage?: boolean; - revealOutput?: 'on-run' | 'on-exec-error' | 'on-demand'; - deferred?: boolean; -} -export type JestRunMode = ( - | { type: 'watch' } - | { type: 'on-demand' } - | { type: 'on-save'; testFileOnly?: boolean } -) & - JestRunModeOptions; - -export type JestRunModeType = JestRunMode['type']; -export type JestPredefinedRunModeType = JestRunModeType | 'deferred'; -export type JestRunModeSetting = JestRunMode | JestPredefinedRunModeType; - -export type TestExplorerConfigLegacy = - | { enabled: false } - | { enabled: true; showClassicStatus?: boolean; showInlineError?: boolean }; - -export interface TestExplorerConfig { - showInlineError?: boolean; -} - -export type NodeEnv = ProjectWorkspace['nodeEnv']; -export type MonitorLongRun = 'off' | number; -export type AutoRevealOutputType = 'on-run' | 'on-exec-error' | 'off'; -export interface PluginResourceSettings { - jestCommandLine?: string; - autoClearTerminal?: boolean; - rootPath: string; - coverageFormatter: string; - debugMode?: boolean; - coverageColors?: CoverageColors; - runMode: RunMode; - testExplorer: TestExplorerConfig; - nodeEnv?: NodeEnv; - shell: RunShell; - monitorLongRun?: MonitorLongRun; - enable?: boolean; - parserPluginOptions?: JESParserPluginOptions; - useDashedArgs?: boolean; -} - -export interface DeprecatedPluginResourceSettings { - showCoverageOnLoad?: boolean; - autoRevealOutput?: AutoRevealOutputType; - autoRun?: JestExtAutoRunSetting | null; -} - -export interface PluginWindowSettings { - disabledWorkspaceFolders: string[]; -} - -export type AllPluginResourceSettings = PluginResourceSettings & DeprecatedPluginResourceSettings; - -export type VirtualFolderSettingKey = keyof AllPluginResourceSettings; -export interface VirtualFolderSettings extends AllPluginResourceSettings { - name: string; -} - -export type GetConfigFunction = (key: VirtualFolderSettingKey) => T | undefined; -/** - * Returns a function that retrieves Jest configuration settings for a given workspace folder. - * If the workspace folder is a virtual folder, it first checks for the corresponding virtual folder setting. - * If the setting is not found, it falls back to the workspace setting. - * @param workspaceFolder The workspace folder to retrieve Jest configuration settings for. - * @returns A function that takes a `VirtualFolderSettingKey` as an argument and returns the corresponding setting value. - */ -export const createJestSettingGetter = ( - workspaceFolder: vscode.WorkspaceFolder -): GetConfigFunction => { - const config = vscode.workspace.getConfiguration('jest', workspaceFolder.uri); - let vFolder: VirtualFolderSettings | undefined; - - if (isVirtualWorkspaceFolder(workspaceFolder)) { - const virtualFolders = config.get('virtualFolders'); - vFolder = virtualFolders?.find((v) => v.name === workspaceFolder.name); - if (!vFolder) { - throw new Error(`[${workspaceFolder.name}] is missing corresponding virtual folder setting`); - } - } - - // get setting from virtual folder first, fallback to workspace setting if not found - const getSetting = (key: VirtualFolderSettingKey): T | undefined => { - if (key === 'enable') { - // if any of the folders is disabled, then the whole workspace is disabled - return (config.get(key) !== false && vFolder?.enable !== false) as T; - } - - return (vFolder?.[key] as T) ?? config.get(key); - }; - return getSetting; -}; - -// get setting from virtual folder first, fallback to workspace setting if not found -export const updateSetting = async ( - workspaceFolder: vscode.WorkspaceFolder, - key: VirtualFolderSettingKey, - value: unknown -): Promise => { - const config = vscode.workspace.getConfiguration('jest', workspaceFolder.uri); - if (!isVirtualWorkspaceFolder(workspaceFolder)) { - await config.update(key, value); - return; - } - const virtualFolders = config.get('virtualFolders'); - const vFolder = virtualFolders?.find((v) => v.name === workspaceFolder.name); - if (!vFolder) { - throw new Error(`[${workspaceFolder.name}] is missing corresponding virtual folder setting`); - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (vFolder as any)[key] = value; - await config.update('virtualFolders', virtualFolders); -}; +export * from './types'; +export * from './helper'; diff --git a/src/Settings/types.ts b/src/Settings/types.ts new file mode 100644 index 000000000..9f37d1d21 --- /dev/null +++ b/src/Settings/types.ts @@ -0,0 +1,99 @@ +import { CoverageColors } from '../Coverage/CoverageOverlay'; +import { JESParserPluginOptions, ProjectWorkspace } from 'jest-editor-support'; +import { RunShell } from '../JestExt/run-shell'; +import { RunMode } from '../JestExt/run-mode'; + +export type JestTestProcessType = + | 'all-tests' + | 'watch-tests' + | 'watch-all-tests' + | 'by-file' + | 'by-file-test' + | 'not-test' + | 'by-file-test-pattern' + | 'by-file-pattern'; + +export type OnStartupType = Extract[]; +export type OnSaveFileType = 'test-file' | 'test-src-file'; +export type JestExtAutoRunShortHand = 'default' | 'watch' | 'on-save' | 'legacy' | 'off'; + +export type JestExtAutoRunConfig = + | { watch: true; onStartup?: OnStartupType } + | { + watch: false; + onStartup?: OnStartupType; + onSave?: OnSaveFileType; + }; +export type JestExtAutoRunSetting = JestExtAutoRunShortHand | JestExtAutoRunConfig; + +export interface JestRunModeOptions { + runAllTestsOnStartup?: boolean; + coverage?: boolean; + deferred?: boolean; + + // TestExplorer related settings + showInlineError?: boolean; +} +export type JestRunMode = ( + | { type: 'watch' } + | { type: 'on-demand' } + | { type: 'on-save'; testFileOnly?: boolean } +) & + JestRunModeOptions; + +export type JestRunModeType = JestRunMode['type']; +export type JestPredefinedRunModeType = JestRunModeType | 'deferred'; +export type JestRunModeSetting = JestRunMode | JestPredefinedRunModeType; + +export interface JestRawOutputSetting { + revealWithFocus?: 'terminal' | 'test-results' | 'none'; + revealOn?: 'run' | 'error' | 'demand'; + clearOnRun?: 'both' | 'terminal' | 'test-results' | 'none'; +} +export type JestPredefinedOutputSetting = 'neutral' | 'terminal-based' | 'test-results-based'; +export type JestOutputSetting = JestPredefinedOutputSetting | JestRawOutputSetting; + +export type TestExplorerConfigLegacy = + | { enabled: false } + | { enabled: true; showClassicStatus?: boolean; showInlineError?: boolean }; + +export interface TestExplorerConfig { + showInlineError?: boolean; +} + +export type NodeEnv = ProjectWorkspace['nodeEnv']; +export type MonitorLongRun = 'off' | number; +export type AutoRevealOutputType = 'on-run' | 'on-exec-error' | 'off'; +export interface PluginResourceSettings { + jestCommandLine?: string; + rootPath: string; + coverageFormatter: string; + debugMode?: boolean; + coverageColors?: CoverageColors; + runMode: RunMode; + nodeEnv?: NodeEnv; + shell: RunShell; + monitorLongRun?: MonitorLongRun; + enable?: boolean; + parserPluginOptions?: JESParserPluginOptions; + useDashedArgs?: boolean; +} + +export interface DeprecatedPluginResourceSettings { + showCoverageOnLoad?: boolean; + autoRun?: JestExtAutoRunSetting | null; + testExplorer?: TestExplorerConfig; +} + +export interface PluginWindowSettings { + disabledWorkspaceFolders: string[]; +} + +export type AllPluginResourceSettings = PluginResourceSettings & DeprecatedPluginResourceSettings; + +export type VirtualFolderSettingKey = keyof AllPluginResourceSettings; +export interface VirtualFolderSettings extends AllPluginResourceSettings { + name: string; +} + +export type GetConfigFunction = (key: VirtualFolderSettingKey) => T | undefined; diff --git a/src/StatusBar.ts b/src/StatusBar.ts index 1a59aea98..10bcc31f7 100644 --- a/src/StatusBar.ts +++ b/src/StatusBar.ts @@ -50,7 +50,7 @@ class TypedStatusBarItem { const { text, tooltip, backgroundColor } = options; this.actual.text = text ?? this.actual.text; this.actual.tooltip = tooltip ?? this.actual.tooltip; - this.actual.backgroundColor = backgroundColor ?? this.actual.backgroundColor; + this.actual.backgroundColor = backgroundColor; } dispose() { this.actual.dispose(); diff --git a/src/extension-manager.ts b/src/extension-manager.ts index bd1b54594..68b0314f3 100644 --- a/src/extension-manager.ts +++ b/src/extension-manager.ts @@ -502,19 +502,18 @@ export class ExtensionManager { } const key = `${extensionId}-${version}-launch`; const didLaunch = this.context.globalState.get(key, false); - if (!didLaunch) { - vscode.window - .showInformationMessage( - `vscode-jest has been updated to ${version}.`, - 'See What Is Changed' - ) - .then((value) => { - if (value === 'See What Is Changed') { - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(releaseNote)); - } - }); - this.context.globalState.update(key, true); + if (didLaunch) { + return; } + const button = "See What's Changed"; + vscode.window + .showInformationMessage(`vscode-jest has been updated to ${version}.`, button) + .then((value) => { + if (value === button) { + vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(releaseNote)); + } + }); + this.context.globalState.update(key, true); } activate(): void { @@ -530,6 +529,7 @@ export class ExtensionManager { const ReleaseNoteBase = 'https://github.com/jest-community/vscode-jest/blob/master/release-notes'; const ReleaseNotes: Record = { + '6.1.0': `${ReleaseNoteBase}/release-note-v6.md#v610-pre-release`, '6.0.0': `${ReleaseNoteBase}/release-note-v6.md#v600-pre-release`, '5.2.3': `${ReleaseNoteBase}/release-note-v5.x.md#v523`, '5.2.2': `${ReleaseNoteBase}/release-note-v5.x.md#v522`, diff --git a/src/extension.ts b/src/extension.ts index af88bfa01..d5ea44a6f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,6 +6,7 @@ import { tiContextManager } from './test-provider/test-item-context-manager'; import * as languageProvider from './language-provider'; import { noOpFileSystemProvider } from './noop-fs-provider'; import { executableTerminalLinkProvider } from './terminal-link-provider'; +import { outputManager } from './output-manager'; let extensionManager: ExtensionManager; @@ -27,7 +28,8 @@ const addSubscriptions = (context: vscode.ExtensionContext): void => { ...tiContextManager.registerCommands(), ...languageProvider.register(), noOpFileSystemProvider.register(), - executableTerminalLinkProvider.register() + executableTerminalLinkProvider.register(), + ...outputManager.register() ); }; diff --git a/src/output-manager.ts b/src/output-manager.ts new file mode 100644 index 000000000..72892d966 --- /dev/null +++ b/src/output-manager.ts @@ -0,0 +1,277 @@ +import * as vscode from 'vscode'; +import { AutoRevealOutputType, JestOutputSetting, JestRawOutputSetting } from './Settings/types'; +import { ExtOutputTerminal } from './JestExt/output-terminal'; +import { extensionName } from './appGlobals'; + +export type OutputConfig = Required; +export const DefaultJestOutputSetting: OutputConfig = { + revealOn: 'run', + revealWithFocus: 'none', + clearOnRun: 'none', +}; + +const OUTPUT_CONFIG_HELP_URL = 'https://github.com/jest-community/vscode-jest#outputconfig'; + +export class OutputManager { + private config: OutputConfig; + + constructor() { + this.config = this.getConfig(); + } + + private getConfig(): OutputConfig { + const config = vscode.workspace.getConfiguration('jest').get('outputConfig'); + return config + ? this.resolveSetting(config) + : { ...DefaultJestOutputSetting, ...this.fromLegacySettings() }; + } + + private resolveSetting(setting: JestOutputSetting): OutputConfig { + if (typeof setting === 'string') { + switch (setting) { + case 'neutral': + return DefaultJestOutputSetting; + case 'terminal-based': + return { + revealOn: 'run', + revealWithFocus: 'terminal', + clearOnRun: 'none', + }; + case 'test-results-based': + return { + revealOn: 'run', + revealWithFocus: 'test-results', + clearOnRun: 'none', + }; + default: { + console.warn( + `Unknown predefined output setting: ${setting}, will use default setting ("neutral") instead.` + ); + return DefaultJestOutputSetting; + } + } + } + + return { ...DefaultJestOutputSetting, ...setting }; + } + + private fromLegacySettings(scope?: vscode.ConfigurationScope): JestRawOutputSetting { + const vscodeConfig = vscode.workspace.getConfiguration('jest', scope); + const autoClearTerminal = vscodeConfig.get('autoClearTerminal'); + const autoRevealOutput = vscodeConfig.get('autoRevealOutput'); + const openTesting = vscode.workspace.getConfiguration('testing').get('openTesting'); + + const config = {} as JestRawOutputSetting; + + switch (openTesting) { + case 'neverOpen': + case 'openExplorerOnTestStart': + // no-op + break; + case 'openOnTestStart': + config.revealWithFocus = 'test-results'; + break; + case 'openOnTestFailure': + config.revealOn = 'error'; + config.revealWithFocus = 'test-results'; + break; + default: + console.warn(`Unrecognized "testing.openTesting" setting: ${openTesting}`); + } + + switch (autoRevealOutput) { + case undefined: + // no-op + break; + case 'on-run': + case 'on-exec-error': + config.revealOn = 'run'; + break; + case 'off': + config.revealOn = 'demand'; + config.revealWithFocus = 'none'; + break; + } + config.clearOnRun = autoClearTerminal ? 'terminal' : 'none'; + return config; + } + + public showOutputOn( + type: 'run' | 'test-error' | 'exec-error', + terminalOutput: ExtOutputTerminal + ): void { + // will not reveal output for the following cases: + switch (type) { + case 'run': + if (this.config.revealOn !== 'run') { + return; + } + break; + case 'test-error': + if (this.config.revealOn !== 'error') { + return; + } + break; + case 'exec-error': + if (this.config.revealOn === 'demand') { + return; + } + break; + } + terminalOutput.enable(); + + // check to see if we need to show with the focus + if (this.config.revealWithFocus === 'terminal') { + return terminalOutput.show(); + } else if (type !== 'exec-error' && this.config.revealWithFocus === 'test-results') { + // exec-error will only show in terminal + return this.showTestResultsOutput(); + } + } + + public clearOutputOnRun(terminalOutput: ExtOutputTerminal): void { + if (this.config.clearOnRun === 'none') { + return; + } + if (this.config.clearOnRun === 'terminal' || this.config.clearOnRun === 'both') { + terminalOutput.clear(); + } + if (this.config.clearOnRun === 'test-results' || this.config.clearOnRun === 'both') { + this.clearTestResultsOutput(); + } + } + + private clearTestResultsOutput(): void { + // Note: this command is probably not the right one as it will clear all test items status as well, not just the output like in the terminal. + // should file a feature request for testing framework to provide a command to clear the output history only. + vscode.commands.executeCommand('testing.clearTestResults'); + } + private showTestResultsOutput(): void { + vscode.commands.executeCommand('workbench.panel.testResults.view.focus'); + } + + private async updateTestResultsSettings(): Promise { + const value = 'neverOpen'; + await vscode.workspace + .getConfiguration('testing') + .update('openTesting', value, vscode.ConfigurationTarget.Workspace); + console.warn(`set "testing.openTesting" to "${value}"`); + } + + public register(): vscode.Disposable[] { + return [ + vscode.workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this), + vscode.commands.registerCommand(`${extensionName}.save-output-config`, async () => + this.save() + ), + ]; + } + + /** + * Check if "testing.openTesting" setting conflict with outputConfig. + * This occurred when "testing.openTesting" is not set to "neverOpen" + * and the 'revealWithFocus' is not set to "test-results" + * + * @returns boolean + */ + private isTestingSettingValid(): boolean { + const testingSetting = vscode.workspace.getConfiguration('testing').get('openTesting'); + return testingSetting === 'neverOpen' || this.config.revealWithFocus === 'test-results'; + } + + /** + * Validates output settings for potential conflicts. + * If conflict detected, show a warning message with options to update the settings. + * @returns void + */ + public async validate(): Promise { + if (this.isTestingSettingValid()) { + return true; + } + + const testingSetting = vscode.workspace.getConfiguration('testing').get('openTesting'); + const detail = `test-results panel setting "testing.openTesting: ${testingSetting}" conflicts with jest.outputConfig "revalWithFocus: ${this.config.revealWithFocus}".`; + console.warn(detail); + + const actions = { + fixIt: 'Fix it', + help: 'Help', + cancel: 'Cancel', + }; + + const buttons: string[] = [actions.fixIt, actions.help, actions.cancel]; + const selection = await vscode.window.showWarningMessage( + `Output Config Conflict Detected`, + ...buttons + ); + switch (selection) { + case actions.fixIt: + return await this.showFixChooser(); + case actions.help: + vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(OUTPUT_CONFIG_HELP_URL)); + break; + } + return false; + } + + private async showFixChooser(): Promise { + const items = { + fixTestResults: { + label: '$(sync) Fix test-results panel setting', + description: '(Extension manages the test-results panel)', + detail: 'Set "testing.openTesting" to "neverOpen"', + }, + fixOutputConfig: { + label: '$(sync-ignored) Fix outputConfig setting', + description: '(Extension will NOT manage the test-results panel)', + detail: 'Set "jest.outputConfig.revealWithFocus" to "test-results"', + }, + editSettings: { + label: '$(tools) Edit Settings Manually', + detail: 'Open workspace settings', + }, + help: { + label: '$(info) Help', + detail: 'What is "jest.outputConfig"?', + }, + cancel: { + label: '$(close) Cancel', + }, + }; + const item = await vscode.window.showQuickPick(Object.values(items), { + placeHolder: 'Select an action', + }); + switch (item) { + case items.fixTestResults: + await this.updateTestResultsSettings(); + return true; + case items.fixOutputConfig: + this.config.revealWithFocus = 'test-results'; + await this.save(); + return true; + case items.editSettings: + vscode.commands.executeCommand('workbench.action.openWorkspaceSettings'); + break; + case items.help: + vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(OUTPUT_CONFIG_HELP_URL)); + break; + } + return false; + } + + private async onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent): Promise { + if ( + e.affectsConfiguration('jest.outputConfig') || + e.affectsConfiguration('testing.openTesting') + ) { + this.config = this.getConfig(); + this.validate(); + } + } + + public async save(): Promise { + await vscode.workspace.getConfiguration('jest').update('outputConfig', this.config); + } +} + +export const outputManager = new OutputManager(); diff --git a/src/reporter.ts b/src/reporter.ts index fad88f4bc..f510f89a0 100644 --- a/src/reporter.ts +++ b/src/reporter.ts @@ -1,6 +1,6 @@ // Custom Jest reporter used by jest-vscode extension -import type { AggregatedResult } from '@jest/test-result'; +import type { AggregatedResult, Test, TestResult } from '@jest/test-result'; import { Reporter, TestContext } from '@jest/reporters'; class VSCodeJestReporter implements Reporter { @@ -18,6 +18,19 @@ class VSCodeJestReporter implements Reporter { process.stderr.write('onRunComplete\r\n'); } } + + // report any test or exec errors + onTestFileResult( + _test: Test, + testResult: TestResult, + _aggregatedResult: AggregatedResult + ): Promise | void { + if (testResult.numFailingTests > 0 || testResult.testExecError) { + const msg = `onTestFileResult: encountered errors`; + process.stderr.write(`${msg}\r\n`); + } + } + getLastError(): Error | undefined { return; } diff --git a/src/test-provider/jest-test-run.ts b/src/test-provider/jest-test-run.ts new file mode 100644 index 000000000..e25d3ee7f --- /dev/null +++ b/src/test-provider/jest-test-run.ts @@ -0,0 +1,147 @@ +import * as vscode from 'vscode'; +import { JestExtOutput, JestOutputTerminal, OutputOptions } from '../JestExt/output-terminal'; +import { JestTestProviderContext } from './test-provider-context'; + +export type TestRunProtocol = Pick< + vscode.TestRun, + 'name' | 'enqueued' | 'started' | 'errored' | 'failed' | 'passed' | 'skipped' | 'end' +>; + +export type CreateRun = (name: string) => vscode.TestRun; +export type EndProcessOption = { pid: string; delay?: number; reason?: string }; +export type EndOption = EndProcessOption | { reason: string }; +const isEndProcessOption = (arg?: EndOption): arg is EndProcessOption => + arg != null && 'pid' in arg; +let SEQ = 0; + +/** + * A wrapper class for vscode.TestRun to support + * 1. JIT creation of TestRun + * 2. delayed end of TestRun (to prevent the TestRun from being closed before the test is completely done) + * 3. allow multiple processes to use the same TestRun. And the TestRun will be closed only when all processes are done. + */ +export class JestTestRun implements JestExtOutput, TestRunProtocol { + private output: JestOutputTerminal; + private _run?: vscode.TestRun; + private processes: Map; + private verbose: boolean; + private runCount = 0; + public readonly name: string; + + constructor( + name: string, + private context: JestTestProviderContext, + private createRun: CreateRun + ) { + this.name = `${this.context.ext.workspace.name}:${name}:${SEQ++}`; + this.output = context.output; + this.processes = new Map(); + this.verbose = context.ext.settings.debugMode === true; + } + write(msg: string, opt?: OutputOptions): string { + const text = this.output.write(msg, opt); + this._run?.appendOutput(text); + return text; + } + + isClosed(): boolean { + return !this._run; + } + + public addProcess(pid: string): void { + if (!this.processes.has(pid)) { + this.processes.set(pid, undefined); + } + } + /** + * returns the underlying vscode.TestRun, if existing. + * If no run then create one with this.createRun and return it. + **/ + private safeRun(): vscode.TestRun { + if (!this._run) { + const runName = `${this.name} (${this.runCount++})`; + this._run = this.createRun(runName); + if (this.verbose) { + console.log(`[${this.context.ext.workspace.name}] JestTestRun "${runName}": created.`); + } + } + return this._run; + } + + // TestRunProtocol + public enqueued = (test: vscode.TestItem): void => { + this.safeRun().enqueued(test); + }; + public started = (test: vscode.TestItem): void => { + this.safeRun().started(test); + }; + public errored = ( + test: vscode.TestItem, + message: vscode.TestMessage | readonly vscode.TestMessage[], + duration?: number | undefined + ): void => { + const _msg = this.context.ext.settings.runMode.config.showInlineError ? message : []; + this.safeRun().errored(test, _msg, duration); + }; + public failed = ( + test: vscode.TestItem, + message: vscode.TestMessage | readonly vscode.TestMessage[], + duration?: number | undefined + ): void => { + const _msg = this.context.ext.settings.runMode.config.showInlineError ? message : []; + this.safeRun().failed(test, _msg, duration); + }; + public passed = (test: vscode.TestItem, duration?: number | undefined): void => { + this.safeRun().passed(test, duration); + }; + public skipped = (test: vscode.TestItem): void => { + this.safeRun().skipped(test); + }; + public end = (options?: EndOption): void => { + if (!this._run) { + return; + } + const runName = this._run.name; + if (isEndProcessOption(options)) { + const { pid, delay, reason } = options; + let timeoutId = this.processes.get(pid); + if (timeoutId) { + clearTimeout(timeoutId); + } + + if (!delay) { + this.processes.delete(pid); + if (this.verbose) { + console.log(`JestTestRun "${runName}": process "${pid}" ended because: ${reason}`); + } + } else { + timeoutId = setTimeout(() => { + if (this.verbose) { + console.log( + `JestTestRun "${runName}": process "${pid}" ended after ${delay} msec delay because: ${reason}` + ); + } + this.processes.delete(pid); + this.end({ + reason: `last process "${pid}" ended by ${reason}`, + }); + }, delay); + this.processes.set(pid, timeoutId); + if (this.verbose) { + console.log( + `JestTestRun "${runName}": starting a ${delay} msec timer to end process "${pid}" because: ${reason}` + ); + } + } + } + // close the run only when all processes are done + if (this.processes.size > 0) { + return; + } + this._run.end(); + this._run = undefined; + if (this.verbose) { + console.log(`JestTestRun "${runName}": TestRun ended because: ${options?.reason}.`); + } + }; +} diff --git a/src/test-provider/test-item-data.ts b/src/test-provider/test-item-data.ts index 22e6a81bf..a3def7b3f 100644 --- a/src/test-provider/test-item-data.ts +++ b/src/test-provider/test-item-data.ts @@ -9,14 +9,16 @@ import { ContainerNode, DataNode, NodeType, ROOT_NODE_NAME } from '../TestResult import { Logging } from '../logging'; import { TestSuitChangeEvent } from '../TestResults/test-result-events'; import { Debuggable, ItemCommand, TestItemData } from './types'; -import { JestTestProviderContext, JestTestRun, JestTestRunOptions } from './test-provider-helper'; -import { JestProcessInfo, JestProcessRequest, UserDataType } from '../JestProcessManagement'; +import { JestTestProviderContext } from './test-provider-context'; +import { JestTestRun } from './jest-test-run'; +import { JestProcessInfo, JestProcessRequest } from '../JestProcessManagement'; import { GENERIC_ERROR, LONG_RUNNING_TESTS, getExitErrorDef } from '../errors'; import { JestExtOutput } from '../JestExt/output-terminal'; import { tiContextManager } from './test-item-context-manager'; import { toAbsoluteRootPath } from '../helpers'; import { runModeDescription } from '../JestExt/run-mode'; import { isVirtualWorkspaceFolder } from '../virtual-workspace-folder'; +import { outputManager } from '../output-manager'; interface JestRunnable { getJestRunRequest: () => JestExtRequestType; @@ -28,9 +30,6 @@ interface WithUri { type TypedRunEvent = RunEventBase & { type: string }; -const hasRunInfo = (userData?: UserDataType): userData is { run: JestTestRun } => - userData?.run instanceof JestTestRun; - abstract class TestItemDataBase implements TestItemData, JestRunnable, WithUri { item!: vscode.TestItem; log: Logging; @@ -69,16 +68,20 @@ abstract class TestItemDataBase implements TestItemData, JestRunnable, WithUri { } const jestRequest = this.getJestRunRequest(itemCommand); - run.item = this.item; this.deepItemState(this.item, run.enqueued); - const process = this.context.ext.session.scheduleProcess(jestRequest, { run }); + const process = this.context.ext.session.scheduleProcess(jestRequest, { + run, + testItem: this.item, + }); if (!process) { const msg = `failed to schedule test for ${this.item.id}`; run.errored(this.item, new vscode.TestMessage(msg)); run.write(msg, 'error'); - run.end(); + run.end({ reason: 'failed to schedule test' }); + } else { + run.addProcess(process.id); } } @@ -118,14 +121,12 @@ interface SnapshotItemCollection { export class WorkspaceRoot extends TestItemDataBase { private testDocuments: Map; private listeners: vscode.Disposable[]; - private cachedRun: Map; constructor(context: JestTestProviderContext) { super(context, 'WorkspaceRoot'); this.item = this.createTestItem(); this.testDocuments = new Map(); this.listeners = []; - this.cachedRun = new Map(); this.registerEvents(); } @@ -163,7 +164,7 @@ export class WorkspaceRoot extends TestItemDataBase { if (testList.length > 0) { this.onTestListUpdated(testList, run); } else { - run.end(); + run.end({ reason: 'no test found' }); this.item.canResolveChildren = false; } } @@ -181,13 +182,11 @@ export class WorkspaceRoot extends TestItemDataBase { this.listeners.length = 0; }; - private createRun = (options?: JestTestRunOptions): JestTestRun => { - const item = options?.item ?? this.item; + private createRun = (name: string, testItem?: vscode.TestItem): JestTestRun => { + const item = testItem ?? this.item; const request = new vscode.TestRunRequest([item]); return this.context.createTestRun(request, { - ...options, - name: options?.name ?? item.id, - item, + name, }); }; @@ -250,7 +249,7 @@ export class WorkspaceRoot extends TestItemDataBase { this.item.children.replace([]); const testRoots: TestDocumentRoot[] = []; - const aRun = run ?? this.createRun(); + const aRun = run ?? this.createRun('onTestListUpdated'); absoluteFileNames?.forEach((f) => this.addTestFile(f, (testRoot) => { testRoot.updateResultState(aRun); @@ -260,7 +259,7 @@ export class WorkspaceRoot extends TestItemDataBase { //sync testDocuments this.testDocuments.clear(); testRoots.forEach((t) => this.testDocuments.set(t.item.id, t)); - aRun.end(); + aRun.end({ reason: 'onTestListUpdated' }); this.item.canResolveChildren = false; }; @@ -274,14 +273,18 @@ export class WorkspaceRoot extends TestItemDataBase { private onTestSuiteChanged = (event: TestSuitChangeEvent): void => { switch (event.type) { case 'assertions-updated': { - const run = this.getJestRun(event.process) ?? this.createRunForEvent(event); + const run = this.getJestRun(event, true); this.log( 'debug', `update status from run "${event.process.id}": ${event.files.length} files` ); - event.files.forEach((f) => this.addTestFile(f, (testRoot) => testRoot.discoverTest(run))); - run.end(); + if (event.files.length === 0) { + run.write(`No tests were run.`, `new-line`); + } else { + event.files.forEach((f) => this.addTestFile(f, (testRoot) => testRoot.discoverTest(run))); + } + run.end({ pid: event.process.id, delay: 1000, reason: 'assertions-updated' }); break; } case 'result-matched': { @@ -338,8 +341,8 @@ export class WorkspaceRoot extends TestItemDataBase { /** get test item from jest process. If running tests from source file, will return undefined */ private getItemFromProcess = (process: JestProcessInfo): vscode.TestItem | undefined => { // the TestExplorer triggered run should already have item associated - if (hasRunInfo(process.userData) && process.userData.run.item) { - return process.userData.run.item; + if (process.userData?.testItem) { + return process.userData.testItem; } // should only come here for autoRun processes @@ -362,32 +365,24 @@ export class WorkspaceRoot extends TestItemDataBase { return this.testDocuments.get(fileName)?.item; }; - private createRunForEvent = (event: TypedRunEvent): JestTestRun => { - const item = this.getItemFromProcess(event.process) ?? this.item; - const name = hasRunInfo(event.process.userData) - ? event.process.userData.run.name - : `${event.type}:${event.process.id}`; - const run = this.createRun({ - name, - item, - onEnd: () => this.cachedRun.delete(event.process.id), - }); - - this.cachedRun.set(event.process.id, run); - return run; - }; - /** return a valid run from process or process-run-cache. return undefined if run is closed. */ - private getJestRun = (process: JestProcessInfo): JestTestRun | undefined => { - if (hasRunInfo(process.userData) && !process.userData.run.isClosed()) { - return process.userData.run; + /** return a valid run from event. if createIfMissing is true, then create a new one if none exist in the event **/ + private getJestRun(event: TypedRunEvent, createIfMissing: true): JestTestRun; + private getJestRun(event: TypedRunEvent, createIfMissing?: false): JestTestRun | undefined; + private getJestRun(event: TypedRunEvent, createIfMissing = false): JestTestRun | undefined { + if (event.process.userData?.run) { + return event.process.userData.run; } - const run = this.cachedRun.get(process.id); - if (run?.isClosed()) { - this.cachedRun.delete(process.id); - return; + + if (createIfMissing) { + const name = (event.process.userData?.run?.name ?? event.process.id) + `:${event.type}`; + const testItem = this.getItemFromProcess(event.process) ?? this.item; + const run = this.createRun(name, testItem); + run.addProcess(event.process.id); + event.process.userData = { ...event.process.userData, run, testItem }; + + return run; } - return run; - }; + } private runLog(type: string): void { const d = new Date(); @@ -404,19 +399,11 @@ export class WorkspaceRoot extends TestItemDataBase { return; } - let run = this.getJestRun(event.process); - try { + const run = this.getJestRun(event, true); switch (event.type) { case 'scheduled': { - if (!run) { - run = this.createRunForEvent(event); - this.deepItemState(run.item, run.enqueued); - } - if (this.context.ext.settings.autoClearTerminal === true) { - this.context.output.clear(); - } - + this.deepItemState(event.process.userData?.testItem, run.enqueued); break; } case 'data': { @@ -428,38 +415,34 @@ export class WorkspaceRoot extends TestItemDataBase { break; } case 'start': { - run = run ?? this.createRunForEvent(event); - this.deepItemState(run.item, run.started); - if (this.context.ext.settings.autoClearTerminal === true) { - this.context.output.clear(); - } + this.deepItemState(event.process.userData?.testItem, run.started); + outputManager.clearOutputOnRun(this.context.ext.output); this.runLog('started'); break; } case 'end': { - if (event.error && !event.process.userData?.errorReported) { + if (event.error && !event.process.userData?.execError) { this.writer(run).write(event.error, 'error'); - event.process.userData = { ...(event.process.userData ?? {}), errorReported: true }; + event.process.userData = { ...(event.process.userData ?? {}), execError: true }; } this.runLog('finished'); - run?.end(); + run?.end({ pid: event.process.id, delay: 30000, reason: 'process end' }); break; } case 'exit': { if (event.error) { - run = run ?? this.createRunForEvent(event); - - if (run.item) { - run.errored(run.item, new vscode.TestMessage(event.error)); + const testItem = event.process.userData?.testItem; + if (testItem) { + run.errored(testItem, new vscode.TestMessage(event.error)); } - if (!event.process.userData?.errorReported) { + if (!event.process.userData?.execError) { const type = getExitErrorDef(event.code) ?? GENERIC_ERROR; run.write(event.error, type); - event.process.userData = { ...(event.process.userData ?? {}), errorReported: true }; + event.process.userData = { ...(event.process.userData ?? {}), execError: true }; } } this.runLog('exited'); - run?.end(); + run.end({ pid: event.process.id, delay: 1000, reason: 'process exit' }); break; } case 'long-run': { @@ -478,7 +461,6 @@ export class WorkspaceRoot extends TestItemDataBase { dispose(): void { this.unregisterEvents(); - this.cachedRun.forEach((run) => run.end()); } } diff --git a/src/test-provider/test-provider-helper.ts b/src/test-provider/test-provider-context.ts similarity index 54% rename from src/test-provider/test-provider-helper.ts rename to src/test-provider/test-provider-context.ts index 477382ee7..f7230a89b 100644 --- a/src/test-provider/test-provider-helper.ts +++ b/src/test-provider/test-provider-context.ts @@ -1,6 +1,7 @@ import * as vscode from 'vscode'; -import { JestExtOutput, JestOutputTerminal, OutputOptions } from '../JestExt/output-terminal'; +import { JestOutputTerminal } from '../JestExt/output-terminal'; import { JestExtExplorerContext, TestItemData } from './types'; +import { JestTestRun } from './jest-test-run'; /** * provide context information from JestExt and test provider state: @@ -11,7 +12,11 @@ import { JestExtExplorerContext, TestItemData } from './types'; export type TagIdType = 'run' | 'debug' | 'update-snapshot'; -let RunSeq = 0; +export interface JestTestRunOptions { + name?: string; +} + +let SEQ = 0; export class JestTestProviderContext { private testItemData: WeakMap; @@ -78,10 +83,14 @@ export class JestTestProviderContext { }; createTestRun = (request: vscode.TestRunRequest, options?: JestTestRunOptions): JestTestRun => { - const name = options?.name ?? `run-${RunSeq++}`; - const opt = { ...(options ?? {}), name }; - const vscodeRun = this.controller.createTestRun(request, name); - return new JestTestRun(this, vscodeRun, opt); + const name = options?.name ?? `testRun-${SEQ++}`; + const createRun = (name: string) => { + const vscodeRun = this.controller.createTestRun(request, name); + vscodeRun.appendOutput(`\r\nTestRun "${name}" started\r\n`); + return vscodeRun; + }; + + return new JestTestRun(name, this, createRun); }; // tags @@ -132,114 +141,3 @@ export class JestTestProviderContext { return new vscode.TestRunRequest(include, exclude, profile); }; } - -export interface JestTestRunOptions { - name?: string; - item?: vscode.TestItem; - - // in addition to the regular end() method - onEnd?: () => void; - - // replace the end function - end?: () => void; -} - -export type TestRunProtocol = Pick< - vscode.TestRun, - 'name' | 'enqueued' | 'started' | 'errored' | 'failed' | 'passed' | 'skipped' | 'end' ->; -export type ParentRun = vscode.TestRun | JestTestRun; -const isVscodeRun = (arg: ParentRun | undefined): arg is vscode.TestRun => - // eslint-disable-next-line @typescript-eslint/no-explicit-any - arg != null && typeof (arg as any).appendOutput === 'function'; - -/** a wrapper for vscode.TestRun or another JestTestRun */ -export class JestTestRun implements JestExtOutput, TestRunProtocol { - private output: JestOutputTerminal; - public item?: vscode.TestItem; - private parentRun?: ParentRun; - - constructor( - private context: JestTestProviderContext, - parentRun: ParentRun, - private options?: JestTestRunOptions - ) { - this.parentRun = parentRun; - this.output = context.output; - this.item = options?.item; - } - - get vscodeRun(): vscode.TestRun | undefined { - if (!this.parentRun) { - return; - } - if (isVscodeRun(this.parentRun)) { - return this.parentRun; - } - return this.parentRun.vscodeRun; - } - - write(msg: string, opt?: OutputOptions): string { - const text = this.output.write(msg, opt); - this.vscodeRun?.appendOutput(text); - return text; - } - - isClosed(): boolean { - return this.vscodeRun === undefined; - } - - private updateState = (f: (pRun: ParentRun) => void): void => { - if (!this.parentRun || !this.vscodeRun) { - throw new Error(`run "${this.name}" has already closed`); - } - f(this.parentRun); - }; - - // TestRunProtocol - public get name(): string | undefined { - return this.options?.name; - } - public enqueued = (test: vscode.TestItem): void => { - this.updateState((pRun) => pRun.enqueued(test)); - }; - public started = (test: vscode.TestItem): void => { - this.updateState((pRun) => pRun.started(test)); - }; - public errored = ( - test: vscode.TestItem, - message: vscode.TestMessage | readonly vscode.TestMessage[], - duration?: number | undefined - ): void => { - const _msg = this.context.ext.settings.testExplorer.showInlineError ? message : []; - this.updateState((pRun) => pRun.errored(test, _msg, duration)); - }; - public failed = ( - test: vscode.TestItem, - message: vscode.TestMessage | readonly vscode.TestMessage[], - duration?: number | undefined - ): void => { - const _msg = this.context.ext.settings.testExplorer.showInlineError ? message : []; - this.updateState((pRun) => pRun.failed(test, _msg, duration)); - }; - public passed = (test: vscode.TestItem, duration?: number | undefined): void => { - this.updateState((pRun) => pRun.passed(test, duration)); - }; - public skipped = (test: vscode.TestItem): void => { - this.updateState((pRun) => pRun.skipped(test)); - }; - public end = (): void => { - if (this.options?.end) { - return this.options.end(); - } - - if (this.parentRun) { - this.parentRun.end(); - if (isVscodeRun(this.parentRun)) { - this.parentRun = undefined; - } - } - - this.options?.onEnd?.(); - }; -} diff --git a/src/test-provider/test-provider.ts b/src/test-provider/test-provider.ts index 3c379deb7..2a4369f58 100644 --- a/src/test-provider/test-provider.ts +++ b/src/test-provider/test-provider.ts @@ -1,11 +1,12 @@ import * as vscode from 'vscode'; -import { JestTestProviderContext, JestTestRun } from './test-provider-helper'; +import { JestTestProviderContext } from './test-provider-context'; import { WorkspaceRoot } from './test-item-data'; import { Debuggable, ItemCommand, JestExtExplorerContext, TestItemData, TestTagId } from './types'; import { extensionId, extensionName } from '../appGlobals'; import { Logging } from '../logging'; import { toErrorString } from '../helpers'; import { tiContextManager } from './test-item-context-manager'; +import { JestTestRun } from './jest-test-run'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const isDebuggable = (arg: any): arg is Debuggable => arg && typeof arg.getDebugInfo === 'function'; @@ -98,7 +99,7 @@ export class JestTestProvider { this.log('error', `[JestTestProvider]: discoverTest error for "${theItem.id}" : `, e); theItem.error = `discoverTest error: ${JSON.stringify(e)}`; } finally { - run.end(); + run.end({ reason: 'discoverTest' }); } }; @@ -159,45 +160,31 @@ export class JestTestProvider { return Promise.reject(message); } - const run = this.context.createTestRun(req, { name: this.controller.id }); + const run = this.context.createTestRun(req, { + name: `runTest: ${this.controller.id}`, + }); const tests = (req.include ?? this.getAllItems()).filter((t) => !req.exclude?.includes(t)); - const promises: Promise[] = []; - try { - for (const test of tests) { - const tData = this.context.getData(test); - if (!tData || cancelToken?.isCancellationRequested) { - run.skipped(test); - continue; - } - if (req.profile.kind === vscode.TestRunProfileKind.Debug) { - await this.debugTest(tData, run); - } else { - promises.push( - new Promise((resolve, reject) => { - try { - const itemRun = new JestTestRun(this.context, run, { - item: test, - end: resolve, - }); - tData.scheduleTest(itemRun); - } catch (e) { - const msg = `failed to schedule test for ${tData.item.id}: ${toErrorString(e)}`; - this.log('error', msg, e); - run.errored(test, new vscode.TestMessage(msg)); - reject(msg); - } - }) - ); + for (const test of tests) { + const tData = this.context.getData(test); + if (!tData || cancelToken?.isCancellationRequested) { + run.skipped(test); + continue; + } + if (req.profile.kind === vscode.TestRunProfileKind.Debug) { + await this.debugTest(tData, run); + } else { + try { + tData.scheduleTest(run); + } catch (e) { + const msg = `failed to schedule test for ${tData.item.id}: ${toErrorString(e)}`; + this.log('error', msg, e); + run.errored(test, new vscode.TestMessage(msg)); } } - - await Promise.allSettled(promises); - } catch (e) { - const msg = `failed to execute profile "${req.profile.label}": ${e}`; - run.write(msg, 'error'); } - run.end(); + + run.end({ reason: 'runTests ends' }); }; public runItemCommand(testItem: vscode.TestItem, command: ItemCommand): void | Promise { diff --git a/src/test-provider/types.ts b/src/test-provider/types.ts index 7b554150e..c23dbe959 100644 --- a/src/test-provider/types.ts +++ b/src/test-provider/types.ts @@ -2,7 +2,8 @@ import * as vscode from 'vscode'; import { DebugFunction, JestSessionEvents, JestExtSessionContext } from '../JestExt'; import { TestResultProvider } from '../TestResults'; import { WorkspaceRoot, FolderData, TestData, TestDocumentRoot } from './test-item-data'; -import { JestTestProviderContext, JestTestRun } from './test-provider-helper'; +import { JestTestProviderContext } from './test-provider-context'; +import { JestTestRun } from './jest-test-run'; export type TestItemDataType = WorkspaceRoot | FolderData | TestDocumentRoot | TestData; diff --git a/syntaxes/ExtSettingsSchema.json b/syntaxes/ExtSettingsSchema.json new file mode 100644 index 000000000..b5b92e927 --- /dev/null +++ b/syntaxes/ExtSettingsSchema.json @@ -0,0 +1,161 @@ +{ + "title": "Jest V6 Setting", + "markdownDescription": "Schema for validating the new v6 settings in vscode. See details in [settings](https://github.com/jest-community/vscode-jest#customization)", + "type": "object", + "properties": { + "jest.runMode": { + "markdownDescription": "Control when and how jest tests should be run. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)", + "default": "watch", + "oneOf": [ + { + "type": "string", + "enum": [ + "watch", + "on-demand", + "on-save", + "deferred" + ], + "markdownDescription": "A predefined Jest run mode. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "watch", + "on-demand", + "on-save" + ], + "description": "Specifies the jest run mode type." + }, + "runAllTestsOnStartup": { + "type": "boolean", + "description": "Specifies whether to run all tests on startup." + }, + "coverage": { + "type": "boolean", + "description": "Specifies whether to collect and report coverage information." + }, + "showInlineError": { + "type": "boolean", + "description": "Specify if to enable inline error display in test file editor" + }, + "deferred": { + "type": "boolean", + "description": "Specifies whether the run mode is deferred." + } + }, + "required": [ + "type" + ], + "additionalProperties": true, + "if": { + "properties": { + "type": { + "const": "on-save" + } + } + }, + "then": { + "properties": { + "testFileOnly": { + "type": "boolean", + "description": "if true, will run tests only when saving test files." + } + }, + "additionalProperties": true + }, + "else": { + "not": { + "required": [ + "testFileOnly" + ] + }, + "errorMessage": "The property 'testFileOnly' should only be present when 'type' is 'on-save'.", + "additionalProperties": true + }, + "markdownDescription": "A detailed runMode configuration. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)" + } + ] + }, + "jest.outputConfig": { + "scope": "window", + "type": [ + "string", + "object" + ], + "markdownDescription": "Control jest output preference. See details in [outputConfig](https://github.com/jest-community/vscode-jest#outputconfig).", + "default": "neutral", + "oneOf": [ + { + "type": "string", + "enum": [ + "neutral", + "terminal-based", + "test-results-based" + ], + "enumDescriptions": [ + "A passive and neutral config, will not automatically change active panel nor clear output.", + "Switch to terminal panel when running tests.", + "Switch to test-results panel when running tests." + ], + "description": "Specifies the predefined common outputConfig in a string form." + }, + { + "type": "object", + "properties": { + "revealOn": { + "type": "string", + "enum": [ + "run", + "error", + "demand" + ], + "enumDescriptions": [ + "Reveal the output upon test run.", + "Reveal the output upon test error.", + "Reveal the output on demand." + ], + "default": "run", + "description": "Determines when to reveal the test run output. Default is 'run'." + }, + "revealWithFocus": { + "type": "string", + "enum": [ + "none", + "terminal", + "test-results" + ], + "enumDescriptions": [ + "Do not change focus when revealing output.", + "Switch to terminal when revealing output.", + "Switch to test-results panel when revealing output." + ], + "default": "none", + "description": "Specifies which output panel, if any, to switch focus to when revealing. Default is 'none'." + }, + "clearOnRun": { + "type": "string", + "enum": [ + "none", + "both", + "terminal", + "test-results" + ], + "enumDescriptions": [ + "Do not automatically clear the output before each run.", + "Clear both the terminal and test results output before each run.", + "Clear the terminal output before each run.", + "Clear the test results output before each run." + ], + "default": "none", + "description": "Specifies which output, if any, to be cleared before each run. Default is 'none'." + } + }, + "description": "Specifies a custom output config in an object form." + } + ] + } + } +} \ No newline at end of file diff --git a/syntaxes/jestRunModeSchema.json b/syntaxes/jestRunModeSchema.json deleted file mode 100644 index 2edd8afd0..000000000 --- a/syntaxes/jestRunModeSchema.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "title": "Jest Run Mode Setting", - "markdownDescription": "Schema for validating the jest.runMode setting in vscode. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)", - "type": "object", - "properties": { - "jest.runMode": { - "markdownDescription": "Control when and how jest tests should be run. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)", - "default": "watch", - "oneOf": [ - { - "type": "string", - "enum": [ - "watch", - "on-demand", - "on-save", - "deferred" - ], - "markdownDescription": "A predefined Jest run mode. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)" - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "watch", - "on-demand", - "on-save" - ], - "description": "Specifies the jest run mode type." - }, - "runAllTestsOnStartup": { - "type": "boolean", - "description": "Specifies whether to run all tests on startup." - }, - "coverage": { - "type": "boolean", - "description": "Specifies whether to collect and report coverage information." - }, - "revealOutput": { - "type": "string", - "enum": [ - "on-run", - "on-exec-error", - "on-demand" - ], - "description": "Determines when to reveal the test run output." - }, - "deferred": { - "type": "boolean", - "description": "Specifies whether the run mode is deferred." - } - }, - "required": ["type"], - "additionalProperties": true, - "if": { - "properties": { - "type": { - "const": "on-save" - } - } - }, - "then": { - "properties": { - "testFileOnly": { - "type": "boolean", - "description": "if true, will run tests only when saving test files." - } - }, - "additionalProperties":true - }, - "else": { - "not": { - "required": ["testFileOnly"] - }, - "errorMessage": "The property 'testFileOnly' should only be present when 'type' is 'on-save'.", - "additionalProperties":true - }, - "markdownDescription": "A detailed runMode configuration. See details in [runMode](https://github.com/jest-community/vscode-jest#runmode)" - } - ] - } - } -} diff --git a/tests/JestExt/core.test.ts b/tests/JestExt/core.test.ts index 60366fd67..ea771d724 100644 --- a/tests/JestExt/core.test.ts +++ b/tests/JestExt/core.test.ts @@ -27,6 +27,12 @@ jest.mock('../../src/workspace-manager', () => ({ WorkspaceManager: jest.fn().mockReturnValue(mockWorkspaceManager), isInFolder: mockIsInFolder, })); +const mockOutputManager = { + showOutputOn: jest.fn(), +}; +jest.mock('../../src/output-manager', () => ({ + outputManager: mockOutputManager, +})); import * as vscode from 'vscode'; import { JestExt } from '../../src/JestExt/core'; @@ -906,12 +912,9 @@ describe('JestExt', () => { const validateJestCommandLineSpy = jest.spyOn(sut, 'validateJestCommandLine'); validateJestCommandLineSpy.mockReturnValue(Promise.resolve(validationResult)); await sut.startSession(); - - if (abort) { - expect(JestTestProvider).not.toHaveBeenCalled(); - } else { - expect(JestTestProvider).toHaveBeenCalled(); - } + // testProvider will always be created + expect(JestTestProvider).toHaveBeenCalled(); + expect(mockProcessSession.start).toHaveBeenCalledTimes(abort ? 0 : 1); }); }); it('will update statusBar', async () => { @@ -1211,11 +1214,11 @@ describe('JestExt', () => { expect(sbUpdateMock).toHaveBeenCalledWith({ state: 'exec-error' }); expect(executableTerminalLinkProvider.executableLink).toHaveBeenCalled(); expect(mockOutputTerminal.write).toHaveBeenCalledWith(expect.anything(), 'info'); - expect(process.userData?.errorReported).toEqual(true); + expect(process.userData?.execError).toEqual(true); }); it('will not report error if already reported', () => { mockOutputTerminal.write.mockClear(); - process.userData = { errorReported: true }; + process.userData = { execError: true }; onRunEvent({ type: 'exit', error: 'something is wrong', process }); expect(sbUpdateMock).toHaveBeenCalledWith({ state: 'exec-error' }); expect(executableTerminalLinkProvider.executableLink).not.toHaveBeenCalled(); @@ -1435,33 +1438,27 @@ describe('JestExt', () => { }); }); }); - describe('autoRevealOutput', () => { - it.each` - revealOutput | shouldReveal | revealOnError - ${'on-run'} | ${true} | ${false} - ${'on-exec-error'} | ${false} | ${true} - ${'on-demand'} | ${false} | ${false} - `( - 'revealOutput = $revealOutput, shouldReveal = $shouldReveal', - ({ revealOutput, shouldReveal, revealOnError }) => { - const runMode = new RunMode({ type: 'watch', revealOutput }); - const sut = newJestExt({ settings: { runMode } }); - const onRunEvent = (sut.events.onRunEvent.event as jest.Mocked).mock.calls[0][0]; - const process = { id: 'a process id', request: { type: 'watch' } }; - onRunEvent({ type: 'start', process }); - if (shouldReveal) { - expect(mockOutputTerminal.enable).toHaveBeenCalled(); - } else { - expect(mockOutputTerminal.enable).not.toHaveBeenCalled(); - } - expect(mockOutputTerminal.revealOnError).toEqual(revealOnError); - } - ); + describe('output handling', () => { + it('delegate output handling to outputManager during runEvent', () => { + const sut = newJestExt(); + const onRunEvent = (sut.events.onRunEvent.event as jest.Mocked).mock.calls[0][0]; + const process = { id: 'a process id', request: { type: 'watch' } }; + onRunEvent({ type: 'start', process }); + expect(mockOutputManager.showOutputOn).toHaveBeenCalledWith('run', expect.anything()); + }); + it('notify outputManager for test-error event', () => { + const sut = newJestExt(); + const onRunEvent = (sut.events.onRunEvent.event as jest.Mocked).mock.calls[0][0]; + const process = { id: 'a process id', request: { type: 'watch' } }; + onRunEvent({ type: 'test-error', process }); + expect(mockOutputManager.showOutputOn).toHaveBeenCalledWith('run', expect.anything()); + expect(mockOutputManager.showOutputOn).toHaveBeenCalledWith('test-error', expect.anything()); + }); it('when setting changed, output setting will change accordingly', () => { - const runMode = new RunMode({ type: 'watch', revealOutput: 'on-exec-error' }); + const runMode = new RunMode({ type: 'watch', deferred: false }); const sut = newJestExt({ settings: { runMode } }); expect(mockOutputTerminal.revealOnError).toEqual(true); - const runMode2 = new RunMode({ type: 'watch', revealOutput: 'on-demand' }); + const runMode2 = new RunMode({ type: 'watch', deferred: true }); sut.triggerUpdateSettings({ runMode: runMode2 } as any); expect(mockOutputTerminal.revealOnError).toEqual(false); expect(mockOutputTerminal.close).toHaveBeenCalled(); @@ -1549,18 +1546,6 @@ describe('JestExt', () => { expect(validateJestCommandLineSpy).not.toHaveBeenCalled(); expect(mockProcessSession.scheduleProcess).not.toHaveBeenCalled(); }); - it('will not show output even in exec-error', async () => { - expect.hasAssertions(); - - let runMode = new RunMode({ type: 'watch', revealOutput: 'on-exec-error', deferred: true }); - newJestExt({ settings: { runMode } }); - expect(mockOutputTerminal.revealOnError).toEqual(false); - - // while in non-deferred mode, the revealOnError will be true - runMode = new RunMode({ type: 'watch', revealOutput: 'on-exec-error', deferred: false }); - newJestExt({ settings: { runMode } }); - expect(mockOutputTerminal.revealOnError).toEqual(true); - }); it('will not do any auto-run for on-save mode either', async () => { expect.hasAssertions(); let runMode = new RunMode({ type: 'on-save', deferred: true }); @@ -1590,13 +1575,15 @@ describe('JestExt', () => { await jestExt.startSession(); expect(runMode.config.deferred).toBe(true); - expect(mockOutputTerminal.enable).not.toHaveBeenCalled(); + expect(mockOutputManager.showOutputOn).not.toHaveBeenCalled(); + expect(mockOutputTerminal.revealOnError).toEqual(false); expect(mockProcessSession.scheduleProcess).not.toHaveBeenCalled(); await jestExt.runAllTests(); expect(runMode.config.deferred).toBe(false); - expect(mockOutputTerminal.enable).toHaveBeenCalled(); + expect(mockOutputManager.showOutputOn).toHaveBeenCalledWith('run', expect.anything()); + expect(mockOutputTerminal.revealOnError).toEqual(true); expect(mockProcessSession.scheduleProcess).toHaveBeenCalledWith( expect.objectContaining({ type: 'all-tests' }) ); @@ -1609,7 +1596,7 @@ describe('JestExt', () => { await jestExt.startSession(); expect(runMode.config.deferred).toBe(true); - expect(mockOutputTerminal.enable).not.toHaveBeenCalled(); + expect(mockOutputManager.showOutputOn).not.toHaveBeenCalled(); expect(mockTestProvider.runItemCommand).not.toHaveBeenCalled(); const testItem: any = {}; @@ -1617,7 +1604,7 @@ describe('JestExt', () => { await jestExt.runItemCommand(testItem, itemCommand); expect(runMode.config.deferred).toBe(false); - expect(mockOutputTerminal.enable).toHaveBeenCalled(); + expect(mockOutputManager.showOutputOn).toHaveBeenCalledWith('run', expect.anything()); expect(mockTestProvider.runItemCommand).toHaveBeenCalled(); }); describe('when triggered explicitly (by UI)', () => { diff --git a/tests/JestExt/helper.test.ts b/tests/JestExt/helper.test.ts index b252bfc61..8ace06726 100644 --- a/tests/JestExt/helper.test.ts +++ b/tests/JestExt/helper.test.ts @@ -170,9 +170,7 @@ describe('getExtensionResourceSettings()', () => { rootPath: 'workspaceFolder1', debugMode: false, coverageColors: null, - autoClearTerminal: false, - runMode: expect.objectContaining({ config: { type: 'watch', revealOutput: 'on-run' } }), - testExplorer: {}, + runMode: expect.objectContaining({ config: { type: 'watch' } }), monitorLongRun: 60000, shell: mockShell, parserPluginOptions: null, @@ -196,52 +194,25 @@ describe('getExtensionResourceSettings()', () => { }) ); }); - describe('testExplorer', () => { - it.each` - testExplorer | showWarning | converted - ${{ enabled: true }} | ${false} | ${{}} - ${{ enabled: false }} | ${true} | ${{}} - ${{ enabled: true, showClassicStatus: true }} | ${true} | ${{}} - ${{ enabled: true, showClassicStatus: true, showInlineError: true }} | ${true} | ${{}} - ${{ showInlineError: true }} | ${false} | ${{ showInlineError: true }} - ${{}} | ${false} | ${{}} - ${null} | ${false} | ${{}} - `( - 'testExplorer: $testExplorer => show legacy warning? $showWarning', - ({ testExplorer, showWarning, converted }) => { - userSettings = { testExplorer }; - const folder = makeWorkspaceFolder('workspaceFolder1'); - const settings = getExtensionResourceSettings(folder); - expect(settings).toEqual( - expect.objectContaining({ - testExplorer: converted, - }) - ); - if (showWarning) { - expect(vscode.window.showWarningMessage).toHaveBeenCalled(); - } - } - ); - }); + describe('runMode', () => { it('pass along legacy settings', () => { userSettings = { showCoverageOnLoad: true, - autoRevealOutput: 'off', autoRun: 'off', + testExplorer: { showInlineError: true }, }; const folder = makeWorkspaceFolder('workspaceFolder1'); const settings = getExtensionResourceSettings(folder); expect(settings.runMode.config).toEqual({ type: 'on-demand', - revealOutput: 'on-demand', coverage: true, + showInlineError: true, }); }); it('if there is runMode, it will ignore the legacy settings', () => { userSettings = { showCoverageOnLoad: true, - autoRevealOutput: 'off', autoRun: 'off', runMode: 'on-save', }; @@ -249,7 +220,6 @@ describe('getExtensionResourceSettings()', () => { const settings = getExtensionResourceSettings(folder); expect(settings.runMode.config).toEqual({ type: 'on-save', - revealOutput: 'on-run', }); }); }); diff --git a/tests/JestExt/outpt-terminal.test.ts b/tests/JestExt/outpt-terminal.test.ts index cc37629d5..22014be94 100644 --- a/tests/JestExt/outpt-terminal.test.ts +++ b/tests/JestExt/outpt-terminal.test.ts @@ -10,6 +10,13 @@ import { toAnsi, } from '../../src/JestExt/output-terminal'; import * as errors from '../../src/errors'; +import { outputManager } from '../../src/output-manager'; + +jest.mock('../../src/output-manager', () => ({ + outputManager: { + showOutputOn: jest.fn(), + }, +})); describe('JestOutputTerminal', () => { let mockTerminal; @@ -86,29 +93,51 @@ describe('JestOutputTerminal', () => { const { pty: pty2 } = (vscode.window.createTerminal as jest.Mocked).mock.calls[1][0]; expect(pty2).toBe(pty); }); - it('will show terminal when writing error messages', () => { - const output = new JestOutputTerminal('a'); + describe('interact with outputManager', () => { + it('will delegate output decision when writing error messages', () => { + const output = new JestOutputTerminal('a'); - output.write('1'); - expect(mockTerminal.show).not.toHaveBeenCalled(); + output.write('1'); + expect(outputManager.showOutputOn).not.toHaveBeenCalled(); - output.write('2', 'error'); - expect(mockTerminal.show).toHaveBeenCalledTimes(1); + output.write('2', 'error'); + expect(outputManager.showOutputOn).toHaveBeenCalledWith('exec-error', output); + (outputManager.showOutputOn as jest.Mocked).mockClear(); + + output.write('2', errors.GENERIC_ERROR); + expect(outputManager.showOutputOn).toHaveBeenCalledWith('exec-error', output); + }); + it('will not call outputManager when writing error messages if revalOnError is false', () => { + const output = new JestOutputTerminal('a'); + output.revealOnError = false; + + output.write('an error', 'error'); + expect(outputManager.showOutputOn).not.toHaveBeenCalled(); - output.write('2', errors.GENERIC_ERROR); - expect(mockTerminal.show).toHaveBeenCalledTimes(2); + output.revealOnError = true; + output.write('an error', 'error'); + expect(outputManager.showOutputOn).toHaveBeenCalled(); + }); }); - it('will not show terminal when writing error messages if revalOnError is false', () => { + it('enable terminal will create the terminal if needed', () => { const output = new JestOutputTerminal('a'); - output.revealOnError = false; - - output.write('an error', 'error'); + expect(vscode.window.createTerminal).not.toHaveBeenCalled(); + output.enable(); + expect(vscode.window.createTerminal).toHaveBeenCalledTimes(1); expect(mockTerminal.show).not.toHaveBeenCalled(); - output.revealOnError = true; - output.write('an error', 'error'); + // calling enable again is no-op + output.enable(); + expect(vscode.window.createTerminal).toHaveBeenCalledTimes(1); + }); + it('can show the terminal', () => { + const output = new JestOutputTerminal('a'); + const enableSpy = jest.spyOn(output, 'enable'); + output.show(); + expect(enableSpy).toHaveBeenCalled(); expect(mockTerminal.show).toHaveBeenCalledTimes(1); }); + it('will properly dispose terminal and emitter', () => { const output = new JestOutputTerminal('a'); output.enable(); diff --git a/tests/JestExt/process-listeners.test.ts b/tests/JestExt/process-listeners.test.ts index c47cb674f..ca780528d 100644 --- a/tests/JestExt/process-listeners.test.ts +++ b/tests/JestExt/process-listeners.test.ts @@ -252,11 +252,12 @@ describe('jest process listeners', () => { }); }); describe.each` - output | stdout | stderr | error - ${'whatever'} | ${'data'} | ${'data'} | ${'data'} - ${'onRunStart'} | ${'data'} | ${'start'} | ${'data'} - ${'onRunComplete'} | ${'data'} | ${'end'} | ${'data'} - ${'Watch Usage'} | ${undefined} | ${undefined} | ${'data'} + output | stdout | stderr | error + ${'whatever'} | ${'data'} | ${'data'} | ${'data'} + ${'onRunStart'} | ${'data'} | ${'start'} | ${'data'} + ${'onRunComplete'} | ${'data'} | ${'end'} | ${'data'} + ${'onTestFileResult: encountered errors'} | ${'data'} | ${'test-error'} | ${'data'} + ${'Watch Usage'} | ${undefined} | ${undefined} | ${'data'} `('propagate run events: $output', ({ output, stdout, stderr, error }) => { it('from stdout: eventType=$stdout', () => { expect.hasAssertions(); diff --git a/tests/JestExt/run-mode.test.ts b/tests/JestExt/run-mode.test.ts index 9da623009..47d2f5cc4 100644 --- a/tests/JestExt/run-mode.test.ts +++ b/tests/JestExt/run-mode.test.ts @@ -11,16 +11,16 @@ import * as vscode from 'vscode'; import { updateSetting } from '../../src/Settings'; describe('RunMode', () => { - const defaultRunModeConfig = { type: 'watch', revealOutput: 'on-run' }; + const defaultRunModeConfig = { type: 'watch' }; describe('constructor', () => { it.each` seq | setting | legacySettings | expected - ${1} | ${'watch'} | ${undefined} | ${{ type: 'watch', revealOutput: 'on-run' }} - ${2} | ${'on-save'} | ${undefined} | ${{ type: 'on-save', revealOutput: 'on-run' }} - ${3} | ${'on-demand'} | ${undefined} | ${{ type: 'on-demand', revealOutput: 'on-run' }} - ${4} | ${'deferred'} | ${undefined} | ${{ type: 'on-demand', revealOutput: 'on-run', deferred: true }} + ${1} | ${'watch'} | ${undefined} | ${{ type: 'watch' }} + ${2} | ${'on-save'} | ${undefined} | ${{ type: 'on-save' }} + ${3} | ${'on-demand'} | ${undefined} | ${{ type: 'on-demand' }} + ${4} | ${'deferred'} | ${undefined} | ${{ type: 'on-demand', deferred: true }} ${5} | ${'typo'} | ${undefined} | ${'error'} - ${6} | ${'watch'} | ${{ autoRun: 'off' }} | ${{ type: 'watch', revealOutput: 'on-run' }} + ${6} | ${'watch'} | ${{ autoRun: 'off' }} | ${{ type: 'watch' }} `( 'case $seq: creating a RunMode from predefined type: $setting', ({ setting, legacySettings, expected }) => { @@ -34,12 +34,12 @@ describe('RunMode', () => { } ); it.each` - seq | setting | legacySettings | expected - ${1} | ${{ type: 'watch', revealOutput: 'on-run' }} | ${undefined} | ${{ type: 'watch', revealOutput: 'on-run' }} - ${2} | ${{ type: 'watch' }} | ${undefined} | ${{ type: 'watch' }} - ${3} | ${{ type: 'on-save', testFileOnly: true }} | ${undefined} | ${{ type: 'on-save', testFileOnly: true }} - ${4} | ${{ type: 'manual' }} | ${undefined} | ${'error'} - ${5} | ${{ type: 'watch', revealOutput: 'on-run' }} | ${{ autoRun: 'off' }} | ${{ type: 'watch', revealOutput: 'on-run' }} + seq | setting | legacySettings | expected + ${1} | ${{ type: 'watch' }} | ${undefined} | ${{ type: 'watch' }} + ${2} | ${{ type: 'watch' }} | ${undefined} | ${{ type: 'watch' }} + ${3} | ${{ type: 'on-save', testFileOnly: true }} | ${undefined} | ${{ type: 'on-save', testFileOnly: true }} + ${4} | ${{ type: 'manual' }} | ${undefined} | ${'error'} + ${5} | ${{ type: 'watch' }} | ${{ autoRun: 'off' }} | ${{ type: 'watch' }} `( 'case $seq: creating a RunMode from existing config without change: $setting', ({ setting, legacySettings, expected }) => { @@ -55,13 +55,13 @@ describe('RunMode', () => { describe(`migrating from existing settings`, () => { it.each` seq | legacySettings | expected - ${1} | ${{ autoRun: 'off' }} | ${{ type: 'on-demand', revealOutput: 'on-run' }} - ${2} | ${{ autoRun: 'watch' }} | ${{ type: 'watch', revealOutput: 'on-run' }} - ${3} | ${{ autoRun: 'on-save' }} | ${{ type: 'on-save', revealOutput: 'on-run' }} - ${4} | ${{ autoRun: 'legacy' }} | ${{ type: 'watch', revealOutput: 'on-run', runAllTestsOnStartup: true }} - ${5} | ${{ autoRun: { watch: true, onStartup: ['all-tests'] } }} | ${{ type: 'watch', revealOutput: 'on-run', runAllTestsOnStartup: true }} - ${6} | ${{ autoRun: { watch: false, onSave: 'test-src-file' } }} | ${{ type: 'on-save', revealOutput: 'on-run' }} - ${7} | ${{ autoRun: { watch: false, onSave: 'test-file' } }} | ${{ type: 'on-save', revealOutput: 'on-run', testFileOnly: true }} + ${1} | ${{ autoRun: 'off' }} | ${{ type: 'on-demand' }} + ${2} | ${{ autoRun: 'watch' }} | ${{ type: 'watch' }} + ${3} | ${{ autoRun: 'on-save' }} | ${{ type: 'on-save' }} + ${4} | ${{ autoRun: 'legacy' }} | ${{ type: 'watch', runAllTestsOnStartup: true }} + ${5} | ${{ autoRun: { watch: true, onStartup: ['all-tests'] } }} | ${{ type: 'watch', runAllTestsOnStartup: true }} + ${6} | ${{ autoRun: { watch: false, onSave: 'test-src-file' } }} | ${{ type: 'on-save' }} + ${7} | ${{ autoRun: { watch: false, onSave: 'test-file' } }} | ${{ type: 'on-save', testFileOnly: true }} ${8} | ${{ autoRun: 'typo' }} | ${'error'} `('case $seq: can create autoRun from autoRun settings', ({ legacySettings, expected }) => { const runMode = new RunMode(undefined, legacySettings); @@ -73,16 +73,13 @@ describe('RunMode', () => { } }); it.each` - seq | setting | legacySettings | expected - ${1} | ${undefined} | ${{ showCoverageOnLoad: true }} | ${{ type: 'watch', revealOutput: 'on-run', coverage: true }} - ${2} | ${'watch'} | ${{ showCoverageOnLoad: true }} | ${{ type: 'watch', revealOutput: 'on-run' }} - ${3} | ${undefined} | ${{ autoRevealOutput: 'off' }} | ${{ type: 'watch', revealOutput: 'on-demand' }} - ${4} | ${undefined} | ${{ autoRevealOutput: 'on-run' }} | ${{ type: 'watch', revealOutput: 'on-run' }} - ${5} | ${undefined} | ${{ autoRevealOutput: 'on-exec-error' }} | ${{ type: 'watch', revealOutput: 'on-exec-error' }} - ${6} | ${undefined} | ${{ autoRevealOutput: 'something' }} | ${'error'} - ${7} | ${undefined} | ${{ showCoverageOnLoad: true }} | ${{ type: 'watch', revealOutput: 'on-run', coverage: true }} - ${8} | ${undefined} | ${{ showCoverageOnLoad: false }} | ${{ type: 'watch', revealOutput: 'on-run' }} - ${9} | ${undefined} | ${{ autoRun: 'off', autoRevealOutput: 'off', showCoverageOnLoad: true }} | ${{ type: 'on-demand', revealOutput: 'on-demand', coverage: true }} + seq | setting | legacySettings | expected + ${1} | ${undefined} | ${{ showCoverageOnLoad: true }} | ${{ type: 'watch', coverage: true }} + ${2} | ${'watch'} | ${{ showCoverageOnLoad: true }} | ${{ type: 'watch' }} + ${3} | ${undefined} | ${{ showCoverageOnLoad: true }} | ${{ type: 'watch', coverage: true }} + ${4} | ${undefined} | ${{ showCoverageOnLoad: false }} | ${{ type: 'watch' }} + ${5} | ${undefined} | ${{ testExplorer: { showInlineError: true } }} | ${{ type: 'watch', showInlineError: true }} + ${6} | ${undefined} | ${{ autoRun: 'off', showCoverageOnLoad: true }} | ${{ type: 'on-demand', coverage: true }} `( 'case $seq: migrating other legacy settings to RunMode', ({ setting, legacySettings, expected }) => { diff --git a/tests/Settings/index.test.ts b/tests/Settings/helper.test.ts similarity index 95% rename from tests/Settings/index.test.ts rename to tests/Settings/helper.test.ts index 2c113875f..82185de1e 100644 --- a/tests/Settings/index.test.ts +++ b/tests/Settings/helper.test.ts @@ -1,15 +1,13 @@ -jest.unmock('../../src/Settings/index'); +jest.unmock('../../src/Settings/helper'); +jest.unmock('../../src/Settings/types'); jest.unmock('../test-helper'); jest.unmock('../../src/virtual-workspace-folder'); import * as vscode from 'vscode'; -import { - VirtualFolderSettingKey, - createJestSettingGetter, - updateSetting, -} from '../../src/Settings/index'; +import { createJestSettingGetter, updateSetting } from '../../src/Settings/helper'; import { VirtualWorkspaceFolder } from '../../src/virtual-workspace-folder'; import { makeWorkspaceFolder } from '../test-helper'; +import { VirtualFolderSettingKey } from '../../src/Settings/types'; const mockConfiguration = (userSettings: any) => { vscode.workspace.getConfiguration = jest.fn().mockImplementation(() => ({ diff --git a/tests/StatusBar.test.ts b/tests/StatusBar.test.ts index f3da1bdad..0e6f1507b 100644 --- a/tests/StatusBar.test.ts +++ b/tests/StatusBar.test.ts @@ -29,8 +29,6 @@ describe('StatusBar', () => { let statusBar: StatusBar; let updateSpy; let renderSpy; - // let mockActiveSBItem; - // let mockSummarySBItem; let createFolderItemSpy; let createSummaryItemSpy; let mockSummarySBItems; @@ -234,6 +232,14 @@ describe('StatusBar', () => { expect(mockActiveSBItems[0].tooltip).toContain('on-save'); expect(mockSummarySBItems[0].tooltip).toContain('success 1, fail 2, unknown 3'); }); + it('error background will be reset upon next successful run', () => { + statusBar.bind(makeWorkspaceFolder('testSource1')).update({ state: 'exec-error' }); + expect(mockActiveSBItems[0].backgroundColor.id).toEqual( + expect.stringContaining('statusBarItem.errorBackground') + ); + statusBar.bind(makeWorkspaceFolder('testSource1')).update({ state: 'running' }); + expect(mockActiveSBItems[0].backgroundColor).toEqual(undefined); + }); }); }); }); diff --git a/tests/extension-manager.test.ts b/tests/extension-manager.test.ts index cb6763bf9..38324c669 100644 --- a/tests/extension-manager.test.ts +++ b/tests/extension-manager.test.ts @@ -149,6 +149,10 @@ const setupVirtualFolders = (em: ExtensionManager) => { return { ws1, ws2, ws2_v1, ws2_v2 }; }; +jest.mock('../src/output-manager', () => ({ + outputManager: jest.fn(), +})); + describe('ExtensionManager', () => { const jestInstance = makeJestExt(makeWorkspaceFolder('workspaceFolder1')); let context; @@ -1276,13 +1280,13 @@ describe('ExtensionManager', () => { expect(ext2.onDidChangeActiveTextEditor).not.toHaveBeenCalled(); }); it.each` - case | version | showChoice | choice | showRN - ${1} | ${'4.6'} | ${false} | ${undefined} | ${false} - ${2} | ${'5.0.0'} | ${true} | ${undefined} | ${false} - ${3} | ${'5.0.0'} | ${true} | ${'See What Is Changed'} | ${true} - ${4} | ${'5.0.1'} | ${true} | ${undefined} | ${false} - ${5} | ${'6.0.0'} | ${true} | ${undefined} | ${false} - ${6} | ${'99.0.0'} | ${false} | ${undefined} | ${false} + case | version | showChoice | choice | showRN + ${1} | ${'4.6'} | ${false} | ${undefined} | ${false} + ${2} | ${'5.0.0'} | ${true} | ${undefined} | ${false} + ${3} | ${'5.0.0'} | ${true} | ${"See What's Changed"} | ${true} + ${4} | ${'5.0.1'} | ${true} | ${undefined} | ${false} + ${5} | ${'6.0.0'} | ${true} | ${undefined} | ${false} + ${6} | ${'99.0.0'} | ${false} | ${undefined} | ${false} `( 'show release note once for specific version: case $case', async ({ version, showChoice, choice, showRN }) => { diff --git a/tests/extension.test.ts b/tests/extension.test.ts index 2df939c07..ccba9863c 100644 --- a/tests/extension.test.ts +++ b/tests/extension.test.ts @@ -23,12 +23,19 @@ jest.mock('../src/Coverage', () => ({ jest.mock('../src/test-provider/test-item-context-manager', () => ({ tiContextManager: { registerCommands: jest.fn(() => []) }, })); +const mockOutputManager = { + register: jest.fn().mockReturnValue([]), +}; +jest.mock('../src/output-manager', () => ({ + outputManager: mockOutputManager, +})); const extensionManager = { unregisterAllWorkspaces: jest.fn(), activate: jest.fn(), register: jest.fn(() => []), deleteAllExtensions: jest.fn(), + getByName: jest.fn(), }; // tslint:disable-next-line: variable-name @@ -65,11 +72,18 @@ describe('Extension', () => { statusBar.register.mockClear(); activate(context); expect(statusBar.register).toHaveBeenCalled(); + const [f]: any[] = statusBar.register.mock.calls[0]; + f('whatever'); + expect(extensionManager.getByName).toHaveBeenCalledWith('whatever'); }); it('should register language provider', () => { activate(context); expect(languageProvider.register).toHaveBeenCalledTimes(1); }); + it('should register outputManager', () => { + activate(context); + expect(mockOutputManager.register).toHaveBeenCalled(); + }); }); describe('deactivate()', () => { diff --git a/tests/manual-mocks.ts b/tests/manual-mocks.ts new file mode 100644 index 000000000..fddf34e7d --- /dev/null +++ b/tests/manual-mocks.ts @@ -0,0 +1,30 @@ +// alternative to use __mocks__ under src + +/** + * Jest automock will not mock arrow functions, so we need to mock it manually. + */ + +/* istanbul ignore next */ +jest.mock('../src/output-manager', () => ({ + outputManager: { clearOutputOnRun: jest.fn() }, +})); + +jest.mock('../src/test-provider/jest-test-run', () => { + return { + JestTestRun: jest.fn().mockImplementation((name: string) => { + return { + name, + enqueued: jest.fn(), + started: jest.fn(), + errored: jest.fn(), + failed: jest.fn(), + passed: jest.fn(), + skipped: jest.fn(), + end: jest.fn(), + write: jest.fn(), + addProcess: jest.fn(), + isClosed: jest.fn(() => false), + }; + }), + }; +}); diff --git a/tests/output-manager.test.ts b/tests/output-manager.test.ts new file mode 100644 index 000000000..ec6c31a73 --- /dev/null +++ b/tests/output-manager.test.ts @@ -0,0 +1,391 @@ +import * as vscode from 'vscode'; +const mockConfig = { + get: jest.fn(), + update: jest.fn(), +}; +const mockWorkspace = { + getConfiguration: jest.fn().mockReturnValue(mockConfig), + onDidChangeConfiguration: jest.fn(), +}; +(vscode.workspace as jest.Mocked) = mockWorkspace; + +jest.dontMock('../src/output-manager'); + +import { OutputManager, DefaultJestOutputSetting } from '../src/output-manager'; + +describe('OutputManager', () => { + const getOutputConfig = (om: OutputManager) => { + mockConfig.update.mockClear(); + om.save(); + const config = mockConfig.update.mock.calls[0][1]; + return config; + }; + let showWarningMessageSpy: any; + + beforeEach(() => { + jest.clearAllMocks(); + showWarningMessageSpy = jest.spyOn(vscode.window, 'showWarningMessage'); + }); + + describe('constructor', () => { + describe('with outputConfig', () => { + describe('can resolve outputConfig settings', () => { + it.each` + case | outputConfig | expected + ${1} | ${undefined} | ${DefaultJestOutputSetting} + ${2} | ${'neutral'} | ${DefaultJestOutputSetting} + ${3} | ${'terminal-based'} | ${{ revealOn: 'run', revealWithFocus: 'terminal', clearOnRun: 'none' }} + ${4} | ${'test-results-based'} | ${{ revealOn: 'run', revealWithFocus: 'test-results', clearOnRun: 'none' }} + ${5} | ${{ revealOn: 'error' }} | ${{ revealOn: 'error', revealWithFocus: 'none', clearOnRun: 'none' }} + ${6} | ${{ revealWithFocus: 'terminal' }} | ${{ revealOn: 'run', revealWithFocus: 'terminal', clearOnRun: 'none' }} + ${7} | ${{ revealWithFocus: 'terminal', clearOnRun: 'terminal' }} | ${{ revealOn: 'run', revealWithFocus: 'terminal', clearOnRun: 'terminal' }} + ${8} | ${'wrong-type'} | ${DefaultJestOutputSetting} + `('case $case', ({ outputConfig, expected }) => { + mockConfig.get.mockImplementationOnce(() => outputConfig); + const om = new OutputManager(); + const config = getOutputConfig(om); + expect(config).toEqual(expected); + }); + }); + it('will ignore legacy settings', () => { + mockConfig.get.mockImplementation((key: string) => { + if (key === 'outputConfig') { + return 'terminal-based'; + } + if (key === 'openTesting') { + return 'openOnTestStart'; + } + return undefined; + }); + const om = new OutputManager(); + const config = getOutputConfig(om); + expect(config).toEqual({ + revealOn: 'run', + revealWithFocus: 'terminal', + clearOnRun: 'none', + }); + }); + }); + describe('without outputConfig', () => { + describe('create a backward compatible config based on the legacy settings', () => { + it.each` + case | openTesting | autoClearTerminal | autoRevealOutput | expected + ${1} | ${'openOnTestStart'} | ${undefined} | ${undefined} | ${{ revealOn: 'run', revealWithFocus: 'test-results', clearOnRun: 'none' }} + ${2} | ${'openOnTestStart'} | ${true} | ${undefined} | ${{ revealOn: 'run', revealWithFocus: 'test-results', clearOnRun: 'terminal' }} + ${3} | ${'openOnTestStart'} | ${true} | ${'off'} | ${{ revealOn: 'demand', revealWithFocus: 'none', clearOnRun: 'terminal' }} + ${4} | ${'neverOpen'} | ${undefined} | ${undefined} | ${DefaultJestOutputSetting} + ${5} | ${'neverOpen'} | ${true} | ${undefined} | ${{ revealOn: 'run', revealWithFocus: 'none', clearOnRun: 'terminal' }} + ${6} | ${'openOnTestFailure'} | ${undefined} | ${undefined} | ${{ revealOn: 'error', revealWithFocus: 'test-results', clearOnRun: 'none' }} + ${7} | ${'openOnTestFailure'} | ${undefined} | ${'on-run'} | ${{ revealOn: 'run', revealWithFocus: 'test-results', clearOnRun: 'none' }} + ${8} | ${'openOnTestFailure'} | ${undefined} | ${'on-exec-error'} | ${{ revealOn: 'run', revealWithFocus: 'test-results', clearOnRun: 'none' }} + ${9} | ${'openOnTestFailure'} | ${true} | ${'off'} | ${{ revealOn: 'demand', revealWithFocus: 'none', clearOnRun: 'terminal' }} + ${10} | ${'whatever'} | ${undefined} | ${undefined} | ${DefaultJestOutputSetting} + ${11} | ${'openOnTestStart'} | ${undefined} | ${'whatever'} | ${{ revealOn: 'run', revealWithFocus: 'test-results', clearOnRun: 'none' }} + `('case $case', ({ openTesting, autoClearTerminal, autoRevealOutput, expected }) => { + mockConfig.get.mockImplementation((key: string) => { + switch (key) { + case 'outputConfig': + return undefined; + case 'openTesting': + return openTesting; + case 'autoClearTerminal': + return autoClearTerminal; + case 'autoRevealOutput': + return autoRevealOutput; + default: + return undefined; + } + }); + const om = new OutputManager(); + const config = getOutputConfig(om); + expect(config).toEqual(expected); + }); + }); + }); + }); + + describe('showOutputOn', () => { + let mockTerminalOutput: any; + const showTestResultsCommand = 'workbench.panel.testResults.view.focus'; + + beforeEach(() => { + mockTerminalOutput = { + enable: jest.fn(), + show: jest.fn(), + }; + }); + it.each` + case | outputConfig | type | enableTerminal | showOutput + ${1} | ${undefined} | ${'run'} | ${true} | ${undefined} + ${2} | ${undefined} | ${'test-error'} | ${undefined} | ${undefined} + ${3} | ${undefined} | ${'exec-error'} | ${true} | ${undefined} + ${4} | ${{ revealOn: 'error' }} | ${'run'} | ${undefined} | ${undefined} + ${5} | ${{ revealOn: 'error' }} | ${'test-error'} | ${true} | ${undefined} + ${6} | ${{ revealOn: 'error' }} | ${'exec-error'} | ${true} | ${undefined} + ${7} | ${{ revealWithFocus: 'terminal' }} | ${'run'} | ${true} | ${'terminal'} + ${8} | ${{ revealWithFocus: 'terminal' }} | ${'test-error'} | ${undefined} | ${undefined} + ${9} | ${{ revealWithFocus: 'terminal' }} | ${'exec-error'} | ${true} | ${'terminal'} + ${10} | ${{ revealWithFocus: 'test-results' }} | ${'run'} | ${true} | ${'test-results'} + ${11} | ${{ revealWithFocus: 'test-results' }} | ${'test-error'} | ${undefined} | ${undefined} + ${12} | ${{ revealWithFocus: 'test-results' }} | ${'exec-error'} | ${true} | ${undefined} + ${13} | ${{ revealOn: 'error', revealWithFocus: 'terminal' }} | ${'run'} | ${undefined} | ${undefined} + ${14} | ${{ revealOn: 'error', revealWithFocus: 'terminal' }} | ${'test-error'} | ${true} | ${'terminal'} + ${15} | ${{ revealOn: 'error', revealWithFocus: 'test-results' }} | ${'test-error'} | ${true} | ${'test-results'} + ${16} | ${{ revealOn: 'demand', revealWithFocus: 'test-results' }} | ${'run'} | ${undefined} | ${undefined} + ${17} | ${{ revealOn: 'demand', revealWithFocus: 'test-results' }} | ${'test-error'} | ${undefined} | ${undefined} + ${18} | ${{ revealOn: 'demand', revealWithFocus: 'test-results' }} | ${'exec-error'} | ${undefined} | ${undefined} + `('case $case', ({ outputConfig, type, enableTerminal, showOutput }) => { + mockConfig.get.mockImplementation((key) => { + switch (key) { + case 'outputConfig': + return outputConfig; + case 'openTesting': + return 'neverOpen'; + } + }); + const om = new OutputManager(); + om.showOutputOn(type, mockTerminalOutput); + if (enableTerminal) { + expect(mockTerminalOutput.enable).toHaveBeenCalled(); + } else { + expect(mockTerminalOutput.enable).not.toHaveBeenCalled(); + } + if (showOutput) { + if (showOutput === 'terminal') { + expect(mockTerminalOutput.show).toHaveBeenCalled(); + expect(vscode.commands.executeCommand).not.toHaveBeenCalledWith(showTestResultsCommand); + } else { + expect(mockTerminalOutput.show).not.toHaveBeenCalled(); + expect(vscode.commands.executeCommand).toHaveBeenCalledWith(showTestResultsCommand); + } + } else { + expect(mockTerminalOutput.show).not.toHaveBeenCalled(); + expect(vscode.commands.executeCommand).not.toHaveBeenCalledWith(showTestResultsCommand); + } + }); + }); + + describe('clearOutputOnRun', () => { + let mockTerminalOutput: any; + const clearTestResultsCommand = 'testing.clearTestResults'; + + beforeEach(() => { + mockTerminalOutput = { + clear: jest.fn(), + }; + }); + it.each` + case | clearOnRun | clearTerminal | clearTestResults + ${1} | ${'none'} | ${false} | ${false} + ${2} | ${'terminal'} | ${true} | ${false} + ${3} | ${'test-results'} | ${false} | ${true} + ${4} | ${'both'} | ${true} | ${true} + `('case $case', ({ clearOnRun, clearTerminal, clearTestResults }) => { + mockConfig.get.mockImplementationOnce(() => ({ ...DefaultJestOutputSetting, clearOnRun })); + const om = new OutputManager(); + om.clearOutputOnRun(mockTerminalOutput); + if (clearTerminal) { + expect(mockTerminalOutput.clear).toHaveBeenCalled(); + } else { + expect(mockTerminalOutput.clear).not.toHaveBeenCalled(); + } + if (clearTestResults) { + expect(vscode.commands.executeCommand).toHaveBeenCalledWith(clearTestResultsCommand); + } else { + expect(vscode.commands.executeCommand).not.toHaveBeenCalledWith(clearTestResultsCommand); + } + }); + }); + + describe('register', () => { + it('will register onDidChangeConfiguration and a save command', async () => { + const om = new OutputManager(); + const disposables = om.register(); + expect(disposables).toHaveLength(2); + expect(mockWorkspace.onDidChangeConfiguration).toHaveBeenCalled(); + expect(vscode.commands.registerCommand).toHaveBeenCalledWith( + expect.stringContaining('save-output-config'), + expect.anything() + ); + const onDidChangeConfiguration = mockWorkspace.onDidChangeConfiguration.mock.calls[0][0]; + expect(onDidChangeConfiguration).not.toBeUndefined(); + + const saveCommand = (vscode.commands.registerCommand as jest.Mocked).mock.calls[0][1]; + const saveSpy = jest.spyOn(om, 'save'); + await saveCommand(); + expect(saveSpy).toHaveBeenCalled(); + }); + describe('onDidChangeConfiguration', () => { + let om: OutputManager; + let onDidChangeConfiguration: any; + let mockChangeEvent: any; + beforeEach(() => { + om = new OutputManager(); + om.register(); + onDidChangeConfiguration = mockWorkspace.onDidChangeConfiguration.mock.calls[0][0]; + mockChangeEvent = { affectsConfiguration: jest.fn() }; + }); + it('no-op if no outputConfig related changes detected', () => { + mockConfig.get.mockImplementationOnce(() => ({ revealOn: 'error' })); + mockChangeEvent.affectsConfiguration.mockReturnValue(false); + + onDidChangeConfiguration.call(om, mockChangeEvent); + const config = getOutputConfig(om); + expect(config.revealOn).not.toBe('error'); + }); + it('if outputConfig related changes detected, will load new config', () => { + mockConfig.get.mockImplementation((key: string) => { + if (key === 'openTesting') { + return 'neverOpen'; + } + if (key === 'outputConfig') { + return { revealOn: 'error' }; + } + }); + mockChangeEvent.affectsConfiguration.mockReturnValue(true); + + onDidChangeConfiguration.call(om, mockChangeEvent); + const config = getOutputConfig(om); + expect(config.revealOn).toBe('error'); + expect(showWarningMessageSpy).not.toHaveBeenCalled(); + }); + it('will show warning message if outputConfig related changes detected and config is not valid', () => { + mockConfig.get.mockImplementation((key: string) => { + if (key === 'openTesting') { + return 'openOnTestStart'; + } + if (key === 'outputConfig') { + return { revealOn: 'error' }; + } + }); + mockChangeEvent.affectsConfiguration.mockReturnValue(true); + + onDidChangeConfiguration.call(om, mockChangeEvent); + expect(showWarningMessageSpy).toHaveBeenCalled(); + }); + }); + }); + + describe('validation and fix', () => { + it('when no conflict, will return true', async () => { + mockConfig.get.mockImplementation((key: string) => { + if (key === 'openTesting') { + return 'neverOpen'; + } + if (key === 'outputConfig') { + return { revealOn: 'error' }; + } + }); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(true); + expect(showWarningMessageSpy).not.toHaveBeenCalled(); + }); + describe('when conflict detected', () => { + beforeEach(() => { + mockConfig.get.mockImplementation((key: string) => { + if (key === 'openTesting') { + return 'openOnTestStart'; + } + if (key === 'outputConfig') { + return { revealOn: 'error' }; + } + }); + }); + it('will show warning message', async () => { + showWarningMessageSpy.mockResolvedValue(undefined); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(false); + expect(showWarningMessageSpy).toHaveBeenCalled(); + }); + it('if user select "Help", will open a help page URL', async () => { + showWarningMessageSpy.mockResolvedValue('Help'); + vscode.Uri.parse = jest.fn().mockReturnValueOnce('help-url'); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(false); + expect(showWarningMessageSpy).toHaveBeenCalled(); + expect(vscode.commands.executeCommand).toHaveBeenCalledWith('vscode.open', 'help-url'); + }); + it('if user select "Cancel", nothing will happen', async () => { + showWarningMessageSpy.mockResolvedValue('Cancel'); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(false); + expect(showWarningMessageSpy).toHaveBeenCalled(); + }); + describe('"Fix it" QuickPick', () => { + let showQuickPickSpy: any; + const mockQuickPick = ( + choose: (items: readonly vscode.QuickPickItem[]) => vscode.QuickPickItem | undefined + ) => { + showQuickPickSpy.mockImplementationOnce((items: any) => { + return Promise.resolve(choose(items)); + }); + }; + beforeEach(() => { + showWarningMessageSpy.mockResolvedValue('Fix it'); + showQuickPickSpy = jest.spyOn(vscode.window, 'showQuickPick'); + }); + it('if user select "Fix it", will open a QuickPick', async () => { + mockQuickPick(() => undefined); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(false); + expect(showWarningMessageSpy).toHaveBeenCalled(); + expect(showQuickPickSpy).toHaveBeenCalled(); + }); + it('if user select "Edit Settings", will open workspace settings', async () => { + mockQuickPick((items) => { + const item = items.find((item) => item.label.includes('Edit Settings')); + return item; + }); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(false); + expect(showWarningMessageSpy).toHaveBeenCalled(); + expect(showQuickPickSpy).toHaveBeenCalled(); + expect(vscode.commands.executeCommand).toHaveBeenCalledWith( + 'workbench.action.openWorkspaceSettings' + ); + }); + it('if user select "Help", will open URL page', async () => { + mockQuickPick((items) => { + const item = items.find((item) => item.label.includes('Help')); + return item; + }); + vscode.Uri.parse = jest.fn().mockReturnValueOnce('help-url'); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(false); + expect(showWarningMessageSpy).toHaveBeenCalled(); + expect(showQuickPickSpy).toHaveBeenCalled(); + expect(vscode.commands.executeCommand).toHaveBeenCalledWith('vscode.open', 'help-url'); + }); + it('if user select "Fix test-results", testing setting will be fixed', async () => { + mockQuickPick((items) => { + const item = items.find((item) => item.label.includes('Fix test-results')); + return item; + }); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(true); + expect(showWarningMessageSpy).toHaveBeenCalled(); + expect(showQuickPickSpy).toHaveBeenCalled(); + expect(mockConfig.update).toHaveBeenCalledWith( + 'openTesting', + 'neverOpen', + vscode.ConfigurationTarget.Workspace + ); + }); + it('if user select "Fix outputConfig", revealWithFocus setting will be fixed', async () => { + mockQuickPick((items) => { + const item = items.find((item) => item.label.includes('Fix outputConfig')); + return item; + }); + const om = new OutputManager(); + await expect(om.validate()).resolves.toEqual(true); + expect(showWarningMessageSpy).toHaveBeenCalled(); + expect(showQuickPickSpy).toHaveBeenCalled(); + expect(mockConfig.update).toHaveBeenCalledWith( + 'outputConfig', + expect.objectContaining({ revealWithFocus: 'test-results' }) + ); + }); + }); + }); + }); +}); diff --git a/tests/reporter.test.ts b/tests/reporter.test.ts index 2fa76b183..cb528249d 100644 --- a/tests/reporter.test.ts +++ b/tests/reporter.test.ts @@ -28,6 +28,35 @@ describe('VSCodeJest Reporter', () => { expect(output).toContain('some error'); }); }); + describe('report test error status', () => { + let writeSpy: any; + beforeEach(() => { + writeSpy = jest.spyOn(process.stderr, 'write'); + }); + it('report error if numFailingTests > 0', () => { + const reporter = new VSCodeJestReporter(); + + let testResult: any = { numFailingTests: 0 }; + reporter.onTestFileResult({} as any, testResult, {} as any); + expect(writeSpy).not.toHaveBeenCalled(); + + testResult = { numFailingTests: 1 }; + reporter.onTestFileResult({} as any, testResult, {} as any); + expect(writeSpy).toHaveBeenCalledWith(expect.stringContaining('onTestFileResult')); + }); + it('report error if there is execError > 0', () => { + const reporter = new VSCodeJestReporter(); + + let testResult: any = {}; + reporter.onTestFileResult({} as any, testResult, {} as any); + expect(writeSpy).not.toHaveBeenCalled(); + + testResult = { testExecError: {} }; + reporter.onTestFileResult({} as any, testResult, {} as any); + expect(writeSpy).toHaveBeenCalledWith(expect.stringContaining('onTestFileResult')); + }); + }); + it('getLastError never returns error', () => { const reporter = new VSCodeJestReporter(); expect(reporter.getLastError()).toBeUndefined(); diff --git a/tests/setup-wizard/start-wizard.test.ts b/tests/setup-wizard/start-wizard.test.ts index 9c32192f1..aec2844be 100644 --- a/tests/setup-wizard/start-wizard.test.ts +++ b/tests/setup-wizard/start-wizard.test.ts @@ -19,6 +19,10 @@ const mockTasks = tasks as jest.Mocked; const mockHelper = helper as jest.Mocked; const { mockShowActionMenu, mockHelperSetup } = mockWizardHelper(mockHelper); +jest.mock('../../src/output-manager', () => ({ + outputManager: {}, +})); + describe('startWizard', () => { const mockDebugConfigProvider: any = {}; const vscodeContext: any = { diff --git a/tests/setup-wizard/tasks/setup-monorepo.test.ts b/tests/setup-wizard/tasks/setup-monorepo.test.ts index 622d82532..37351c2a8 100644 --- a/tests/setup-wizard/tasks/setup-monorepo.test.ts +++ b/tests/setup-wizard/tasks/setup-monorepo.test.ts @@ -22,6 +22,10 @@ import { setupJestCmdLine } from '../../../src/setup-wizard/tasks/setup-jest-cmd const mockHelper = helper as jest.Mocked; const { mockShowActionMenu, mockHelperSetup } = mockWizardHelper(mockHelper); +jest.mock('../../../src/output-manager', () => ({ + outputManager: {}, +})); + describe('setupMonorepo', () => { const mockSaveConfig = jest.fn(); const debugConfigProvider = {}; diff --git a/tests/test-provider/jest-test-runt.test.ts b/tests/test-provider/jest-test-runt.test.ts new file mode 100644 index 000000000..99cfb1d98 --- /dev/null +++ b/tests/test-provider/jest-test-runt.test.ts @@ -0,0 +1,335 @@ +import '../manual-mocks'; + +jest.dontMock('../../src/test-provider/jest-test-run'); +jest.unmock('./test-helper'); + +import * as vscode from 'vscode'; +import { JestTestRun } from '../../src/test-provider/jest-test-run'; + +jest.useFakeTimers(); +jest.spyOn(global, 'setTimeout'); + +describe('JestTestRun', () => { + let mockContext: any; + let jestRun: JestTestRun; + let mockCreateTestRun: any; + + beforeEach(() => { + mockContext = { + output: { + write: jest.fn((text) => text), + }, + ext: { + workspace: { name: 'testWorkspace' }, + settings: { + debugMode: false, + runMode: { config: { showInlineError: true } }, + }, + }, + }; + mockCreateTestRun = jest.fn().mockImplementation((name: string) => ({ + name, + appendOutput: jest.fn(), + enqueued: jest.fn(), + started: jest.fn(), + errored: jest.fn(), + failed: jest.fn(), + passed: jest.fn(), + skipped: jest.fn(), + end: jest.fn(), + })); + + jestRun = new JestTestRun('test', mockContext, mockCreateTestRun); + }); + + describe('constructor', () => { + it('should set the name property', () => { + expect(jestRun.name).toBe('testWorkspace:test:0'); + }); + it('does not create vscode TestRun until it is needed', () => { + expect(mockCreateTestRun).not.toHaveBeenCalled(); + }); + }); + + describe('write', () => { + it('does not create TestRun if it does not exist', () => { + const message = 'test message\r\n'; + jestRun.write(message); + expect(mockContext.output.write).toHaveBeenCalledWith(message, undefined); + expect(mockCreateTestRun).not.toHaveBeenCalled(); + }); + + it('if TestRun exists, the message will be written to both context.output and run', () => { + const message = 'test message'; + + // force the underlying TestRun to be created + jestRun.enqueued({} as any); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + + jestRun.write(message); + expect(mockContext.output.write).toHaveBeenCalledWith(message, undefined); + expect(run.appendOutput).toHaveBeenCalledWith(message); + }); + }); + + describe('isClosed', () => { + it('reflect if there is an active TestRun', () => { + expect(jestRun.isClosed()).toBe(true); + jestRun.enqueued({} as any); + expect(jestRun.isClosed()).toBe(false); + jestRun.end(); + expect(jestRun.isClosed()).toBe(true); + }); + }); + + describe('supports TestRunProtocol by forwarding to the underlying TestRun', () => { + let mockTestItem: any; + + beforeEach(() => { + mockTestItem = { + id: 'testId', + label: 'testLabel', + uri: vscode.Uri.parse('file:///path/to/test/file'), + }; + }); + + describe('enqueued', () => { + it('should call the enqueued method on the test run', () => { + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.enqueued(mockTestItem); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(run.enqueued).toHaveBeenCalledWith(mockTestItem); + }); + }); + + describe('started', () => { + it('should call the started method on the test run', () => { + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.started(mockTestItem); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(run.started).toHaveBeenCalledWith(mockTestItem); + }); + }); + + describe('errored', () => { + it('should call the errored method on the test run with the given test item and message', () => { + const message: any = 'test error message'; + const duration = 100; + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.errored(mockTestItem, message, duration); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(run.errored).toHaveBeenCalledWith(mockTestItem, message, duration); + }); + + it('should not send message if showInlineError is false', () => { + const message: any = 'test error message'; + const duration = 100; + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + + mockContext.ext.settings.runMode.config.showInlineError = false; + jestRun.errored(mockTestItem, message, duration); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + + expect(run.errored).toHaveBeenCalledWith(mockTestItem, [], duration); + }); + }); + + describe('failed', () => { + it('should call the failed method on the test run with the given test item and message', () => { + const message: any = 'test failure message'; + const duration = 100; + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.failed(mockTestItem, message, duration); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(run.failed).toHaveBeenCalledWith(mockTestItem, message, duration); + }); + + it('should use an empty message if showInlineError is false', () => { + const message: any = 'test failure message'; + const duration = 100; + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + + mockContext.ext.settings.runMode.config.showInlineError = false; + jestRun.failed(mockTestItem, message, duration); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(run.failed).toHaveBeenCalledWith(mockTestItem, [], duration); + }); + }); + + describe('passed', () => { + it('should call the passed method on the test run', () => { + const duration = 100; + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.passed(mockTestItem, duration); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(run.passed).toHaveBeenCalledWith(mockTestItem, duration); + }); + }); + + describe('skipped', () => { + it('should call the skipped method on the test run', () => { + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.skipped(mockTestItem); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(run.skipped).toHaveBeenCalledWith(mockTestItem); + }); + }); + + describe('end', () => { + it('should do nothing if there is no run', () => { + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.end(); + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + expect(jestRun.isClosed()).toBe(true); + }); + it('can close a no-process run immediately', () => { + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + jestRun.enqueued(mockTestItem); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(jestRun.isClosed()).toBe(false); + + jestRun.end(); + expect(jestRun.isClosed()).toBe(true); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + expect(run.end).toHaveBeenCalledTimes(1); + }); + it('can only close a run after all processes are done', () => { + jestRun.addProcess('p1'); + jestRun.addProcess('p2'); + jestRun.enqueued(mockTestItem); + + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + + jestRun.end(); + expect(jestRun.isClosed()).toBe(false); + expect(run.end).toHaveBeenCalledTimes(0); + + jestRun.end({ pid: 'p1' }); + expect(jestRun.isClosed()).toBe(false); + expect(run.end).toHaveBeenCalledTimes(0); + + // when the last process is closed, the whole run is then closed + jestRun.end({ pid: 'p2' }); + expect(jestRun.isClosed()).toBe(true); + expect(run.end).toHaveBeenCalledTimes(1); + }); + it('with verbose, more information will be logged', () => { + const pid = '123'; + const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); + mockContext.ext.settings.debugMode = true; + + jestRun = new JestTestRun('test', mockContext, mockCreateTestRun); + jestRun.addProcess(pid); + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + + jestRun.started(mockTestItem); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + + jestRun.end({ pid, reason: 'testReason' }); + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(pid)); + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('testReason')); + }); + describe('when close the process-run with delayed', () => { + it('will end the run after specified delay', () => { + jestRun.started(mockTestItem); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + expect(jestRun.isClosed()).toBe(false); + + // close with 1000 msec delay + jestRun.end({ pid: 'whatever', delay: 1000 }); + + expect(jestRun.isClosed()).toBe(false); + expect(run.end).not.toHaveBeenCalled(); + expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 1000); + + // forward timer + jest.runAllTimers(); + + expect(run.end).toHaveBeenCalled(); + expect(jestRun.isClosed()).toBe(true); + }); + + it('the subsequent end will cancel any running timer earlier', () => { + const pid = '123'; + jest.spyOn(global, 'clearTimeout'); + + jestRun.addProcess(pid); + jestRun.started(mockTestItem); + + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run = mockCreateTestRun.mock.results[0].value; + + jestRun.end({ pid, delay: 30000 }); + expect(jestRun.isClosed()).toBe(false); + + // advance timer by 1000 msec, the run is still not closed + jest.advanceTimersByTime(1000); + expect(jestRun.isClosed()).toBe(false); + + // another end with 1000 msec delay, will cancel the previous 30000 msec delay + jestRun.end({ pid, delay: 1000 }); + expect(global.clearTimeout).toHaveBeenCalledTimes(1); + expect(jestRun.isClosed()).toBe(false); + + // now advance timer by 1000 msec, the timer will finish and run will be closed + jest.advanceTimersByTime(1000); + expect(global.clearTimeout).toHaveBeenCalledTimes(1); + expect(jestRun.isClosed()).toBe(true); + expect(run.end).toHaveBeenCalledTimes(1); + }); + it('with verbose, more information will be logged', () => { + const pid = '123'; + const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); + mockContext.ext.settings.debugMode = true; + + jestRun = new JestTestRun('test', mockContext, mockCreateTestRun); + jestRun.addProcess(pid); + expect(mockCreateTestRun).toHaveBeenCalledTimes(0); + + jestRun.started(mockTestItem); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + + jestRun.end({ pid, delay: 1000, reason: 'testReason' }); + jest.runAllTimers(); + + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(pid)); + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('testReason')); + }); + }); + }); + }); + it('print warning for runs re-created after close: this means the test-run will be splitted into multiple TestRun', () => { + mockContext.ext.settings.debugMode = true; + + jestRun = new JestTestRun('test', mockContext, mockCreateTestRun); + + jestRun.started({} as any); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + const run1 = mockCreateTestRun.mock.results[0].value; + + // close this run + jestRun.end(); + expect(jestRun.isClosed()).toEqual(true); + expect(mockCreateTestRun).toHaveBeenCalledTimes(1); + + // calling error on a closed run will force it to open again + jestRun.errored({} as any, 'whatever' as any); + + expect(jestRun.isClosed()).toEqual(false); + expect(mockCreateTestRun).toHaveBeenCalledTimes(2); + const run2 = mockCreateTestRun.mock.results[1].value; + expect(run1).not.toBe(run2); + }); +}); diff --git a/tests/test-provider/test-item-data.test.ts b/tests/test-provider/test-item-data.test.ts index 0748a3c41..257acf625 100644 --- a/tests/test-provider/test-item-data.test.ts +++ b/tests/test-provider/test-item-data.test.ts @@ -1,5 +1,7 @@ +import '../manual-mocks'; + jest.unmock('../../src/test-provider/test-item-data'); -jest.unmock('../../src/test-provider/test-provider-helper'); +jest.unmock('../../src/test-provider/test-provider-context'); jest.unmock('../../src/appGlobals'); jest.unmock('../../src/TestResults/match-node'); jest.unmock('../../src/virtual-workspace-folder'); @@ -9,9 +11,11 @@ jest.unmock('./test-helper'); jest.unmock('../../src/errors'); jest.unmock('../../src/JestExt/run-mode'); -import { JestTestRun } from '../../src/test-provider/test-provider-helper'; +import { JestTestProviderContext } from '../../src/test-provider/test-provider-context'; +import { JestTestRun } from '../../src/test-provider/jest-test-run'; import { tiContextManager } from '../../src/test-provider/test-item-context-manager'; import { toAbsoluteRootPath } from '../../src/helpers'; +import { outputManager } from '../../src/output-manager'; jest.mock('path', () => { let sep = '/'; @@ -39,7 +43,6 @@ import { WorkspaceRoot, } from '../../src/test-provider/test-item-data'; import * as helper from '../test-helper'; -import { JestTestProviderContext } from '../../src/test-provider/test-provider-helper'; import { buildAssertionContainer, buildSourceContainer, @@ -66,8 +69,8 @@ const getChildItem = (item: vscode.TestItem, partialId: string): vscode.TestItem return found; }; -const mockScheduleProcess = (context) => { - const process: any = { id: 'whatever', request: { type: 'watch-tests' } }; +const mockScheduleProcess = (context, id = 'whatever') => { + const process: any = { id, request: { type: 'watch-tests' } }; context.ext.session.scheduleProcess.mockImplementation((request, userData) => { process.request = request; process.userData = userData; @@ -78,16 +81,13 @@ const mockScheduleProcess = (context) => { describe('test-item-data', () => { let context; - let jestRun; - let runEndSpy; let controllerMock; - let runMock; + let contextCreateTestRunSpy; + const mockedJestTestRun = JestTestRun as jest.MockedClass; - const createTestRun = (opt?: any): [any, jest.SpyInstance, any] => { + const createTestRun = (opt?: any): any => { const run = context.createTestRun(opt?.request ?? {}, opt); - const endSpy = jest.spyOn(run, 'end'); - const runMock = controllerMock.lastRunMock(); - return [run, endSpy, runMock]; + return run; }; const prepareTestResult = (): void => { const assertions = []; @@ -106,21 +106,24 @@ describe('test-item-data', () => { context.ext.testResultProvider.getTestSuiteResult.mockReturnValue(testSuiteResult); }; - const setupTestEnv = () => { + const setupTestEnv = (withAction = true) => { const file = '/ws-1/tests/a.test.ts'; context.ext.testResultProvider.getTestList.mockReturnValueOnce([file]); const wsRoot = new WorkspaceRoot(context); const onRunEvent = context.ext.sessionEvents.onRunEvent.event.mock.calls[0][0]; + const process = mockScheduleProcess(context); // build out the test item tree prepareTestResult(); - // triggers testSuiteChanged event listener - context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ - type: 'assertions-updated', - process: { id: 'whatever', request: { type: 'watch-tests' } }, - files: [file], - }); + if (withAction) { + // triggers testSuiteChanged event listener + context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ + type: 'assertions-updated', + process, + files: [file], + }); + } const folder = getChildItem(wsRoot.item, 'tests'); const testFile = getChildItem(folder, 'a.test.ts'); @@ -141,13 +144,14 @@ describe('test-item-data', () => { }; const item = getItem(); const data = context.getData(item); + const jestRun = createTestRun(); data.scheduleTest(jestRun); - controllerMock.createTestRun.mockClear(); + // mockedJestTestRun.mockClear(); return item; }; - return { wsRoot, folder, testFile, testBlock, onRunEvent, scheduleItem, file }; + return { wsRoot, folder, testFile, testBlock, onRunEvent, process, scheduleItem, file }; }; const createAllTestItems = () => { @@ -170,7 +174,9 @@ describe('test-item-data', () => { context = new JestTestProviderContext(mockExtExplorerContext('ws-1'), controllerMock, profiles); context.output.write = jest.fn((t) => t); context.output.show = jest.fn(); - [jestRun, runEndSpy, runMock] = createTestRun(); + + contextCreateTestRunSpy = jest.spyOn(context, 'createTestRun'); + mockedJestTestRun.mockClear(); vscode.Uri.joinPath = jest .fn() @@ -197,6 +203,7 @@ describe('test-item-data', () => { ]; context.ext.testResultProvider.getTestList.mockReturnValue(testFiles); const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); // verify tree structure @@ -230,29 +237,29 @@ describe('test-item-data', () => { it('if no testFiles yet, will still turn off canResolveChildren and close the run', () => { context.ext.testResultProvider.getTestList.mockReturnValue([]); const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); expect(wsRoot.item.children.size).toEqual(0); expect(wsRoot.item.canResolveChildren).toBe(false); - expect(runEndSpy).toHaveBeenCalledTimes(1); + expect(jestRun.end).toHaveBeenCalledTimes(1); }); it('will not wipe out existing test items', () => { // first time discover 1 file context.ext.testResultProvider.getTestList.mockReturnValue(['/ws-1/a.test.ts']); const wsRoot = new WorkspaceRoot(context); + let jestRun = createTestRun(); wsRoot.discoverTest(jestRun); - expect(jestRun.isClosed()).toBeTruthy(); expect(wsRoot.item.children.size).toEqual(1); expect(wsRoot.item.canResolveChildren).toBe(false); - expect(runEndSpy).toHaveBeenCalledTimes(1); + expect(jestRun.end).toHaveBeenCalledTimes(1); // 2nd time if no test-file: testItems will not change context.ext.testResultProvider.getTestList.mockReturnValue([]); - [jestRun, runEndSpy] = createTestRun(); + jestRun = createTestRun(); wsRoot.discoverTest(jestRun); - expect(jestRun.isClosed()).toBeTruthy(); expect(wsRoot.item.children.size).toEqual(1); expect(wsRoot.item.canResolveChildren).toBe(false); - expect(runEndSpy).toHaveBeenCalledTimes(1); + expect(jestRun.end).toHaveBeenCalledTimes(1); }); }); it('will only discover up to the test file level', () => { @@ -265,6 +272,7 @@ describe('test-item-data', () => { assertionContainer, }); const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); const docItem = wsRoot.item.children.get(testFiles[0]); expect(docItem.children.size).toEqual(0); @@ -282,6 +290,7 @@ describe('test-item-data', () => { const wsRoot = new WorkspaceRoot(context); // first discover all test files and build the tree + let jestRun = createTestRun(); wsRoot.discoverTest(jestRun); expect(wsRoot.item.children.size).toEqual(2); let folderItem = wsRoot.item.children.get('/ws-1/tests1'); @@ -293,7 +302,7 @@ describe('test-item-data', () => { // now remove '/ws-1/tests2/b.test.ts' and rediscover testFiles.length = 1; - [jestRun, runEndSpy] = createTestRun(); + jestRun = createTestRun(); wsRoot.discoverTest(jestRun); expect(wsRoot.item.children.size).toEqual(1); folderItem = wsRoot.item.children.get('/ws-1/tests2'); @@ -336,32 +345,36 @@ describe('test-item-data', () => { it('testListUpdated event will be fired', () => { const wsRoot = new WorkspaceRoot(context); context.ext.testResultProvider.getTestList.mockReturnValueOnce([]); + + const jestRun = context.createTestRun({}); wsRoot.discoverTest(jestRun); expect(wsRoot.item.children.size).toBe(0); + expect(jestRun.end).toHaveBeenCalledTimes(1); + // invoke testListUpdated event listener + mockedJestTestRun.mockClear(); context.ext.testResultProvider.events.testListUpdated.event.mock.calls[0][0]([ '/ws-1/a.test.ts', ]); - // should have created a new run - const runMock2 = controllerMock.lastRunMock(); - expect(runMock2).not.toBe(jestRun.vscodeRun); + // should have created a new JestTestRun but without the actual vscode.TestRun + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun2 = mockedJestTestRun.mock.results[0].value; expect(wsRoot.item.children.size).toBe(1); const docItem = getChildItem(wsRoot.item, 'a.test.ts'); expect(docItem).not.toBeUndefined(); - expect(runMock2.end).toHaveBeenCalled(); + expect(jestRun2.end).toHaveBeenCalled(); }); }); describe('when testSuiteChanged.assertions-updated event filed', () => { it('all item data will be updated accordingly', () => { context.ext.testResultProvider.getTestList.mockReturnValueOnce([]); - context.ext.settings = { - testExplorer: { enabled: true, showInlineError: true }, - runMode: new RunMode('watch'), - }; + const runMode = new RunMode({ type: 'watch', showInlineError: true }); + context.ext.settings = { runMode }; const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); expect(wsRoot.item.children.size).toBe(0); @@ -379,17 +392,21 @@ describe('test-item-data', () => { context.ext.testResultProvider.getTestSuiteResult.mockReturnValue(testSuiteResult); // triggers testSuiteChanged event listener + contextCreateTestRunSpy.mockClear(); + mockedJestTestRun.mockClear(); context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ type: 'assertions-updated', process: { id: 'whatever', request: { type: 'watch-tests' } }, files: ['/ws-1/a.test.ts'], }); - const runMock2 = controllerMock.lastRunMock(); - expect(runMock2).not.toBe(runMock); + const run = mockedJestTestRun.mock.results[0].value; + expect(run.failed).toHaveBeenCalledTimes(1); + expect(run.end).toHaveBeenCalledTimes(1); + expect(wsRoot.item.children.size).toBe(1); const docItem = getChildItem(wsRoot.item, 'a.test.ts'); expect(docItem).not.toBeUndefined(); - expect(runMock2.failed).not.toHaveBeenCalledWith( + expect(run.failed).not.toHaveBeenCalledWith( docItem, { message: testSuiteResult.message, @@ -400,10 +417,27 @@ describe('test-item-data', () => { expect(docItem.children.size).toEqual(1); const tItem = getChildItem(docItem, 'test-a'); expect(tItem).not.toBeUndefined(); - expect(runMock2.failed).toHaveBeenCalledWith(tItem, { message: a1.message }, undefined); + expect(run.failed).toHaveBeenCalledWith(tItem, { message: a1.message }); expect(tItem.range).toEqual({ args: [1, 0, 1, 0] }); + }); + it('if nothing is updated, output the message', () => { + const wsRoot = new WorkspaceRoot(context); + expect(wsRoot.item.children.size).toBe(0); + + const run = createTestRun(); + context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ + type: 'assertions-updated', + process: { id: 'whatever', request: { type: 'watch-tests' }, userData: { run } }, + files: [], + }); + // no tests items to be added + expect(wsRoot.item.children.size).toBe(0); - expect(runMock2.end).toHaveBeenCalled(); + expect(run.write).toHaveBeenCalledWith( + expect.stringContaining('No tests'), + expect.anything() + ); + expect(run.end).toHaveBeenCalled(); }); }); describe('when testSuiteChanged.result-matched event fired', () => { @@ -420,6 +454,7 @@ describe('test-item-data', () => { }); const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); expect(context.ext.testResultProvider.getTestSuiteResult).toHaveBeenCalledTimes(1); @@ -442,7 +477,7 @@ describe('test-item-data', () => { expect(bItem.range).toEqual({ args: [5, 0, 5, 0] }); expect(context.ext.testResultProvider.getTestSuiteResult).toHaveBeenCalled(); - controllerMock.createTestRun.mockClear(); + // controllerMock.createTestRun.mockClear(); context.ext.testResultProvider.getTestSuiteResult.mockClear(); // after match, the assertion nodes would have updated range @@ -474,7 +509,7 @@ describe('test-item-data', () => { }); // no run should be created as we are not changing any test item tree - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); + // expect(controllerMock.createTestRun).not.toHaveBeenCalled(); expect(context.ext.testResultProvider.getTestSuiteResult).not.toHaveBeenCalled(); // expect the item's range has picked up the updated nodes @@ -534,13 +569,14 @@ describe('test-item-data', () => { node2.attrs = { ...node2.attrs, snapshot: 'external', nonLiteralName: true }; const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); expect(context.ext.testResultProvider.getTestSuiteResult).toHaveBeenCalledTimes(1); expect(wsRoot.item.children.size).toBe(1); const docItem = getChildItem(wsRoot.item, 'a.test.ts'); expect(docItem.children.size).toEqual(0); - controllerMock.createTestRun.mockClear(); + // controllerMock.createTestRun.mockClear(); context.ext.testResultProvider.getTestSuiteResult.mockClear(); context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ @@ -555,7 +591,6 @@ describe('test-item-data', () => { expect(tItem2.range).toEqual({ args: [5, 0, 6, 0] }); expect(context.ext.testResultProvider.getTestSuiteResult).toHaveBeenCalledTimes(1); - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); // snapshot menu context is populated for "test-1" only expect(tiContextManager.setItemContext).toHaveBeenCalledTimes(2); @@ -596,6 +631,7 @@ describe('test-item-data', () => { '/ws-1/a.test.ts', '/ws-1/b.test.ts', ]); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); expect(wsRoot.item.children.size).toBe(2); // a.test.ts should still have 2 children @@ -618,23 +654,24 @@ describe('test-item-data', () => { }); const parentItem: any = controllerMock.createTestItem('ws-1', 'ws-1', uri); const docRoot = new TestDocumentRoot(context, uri, parentItem); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); expect(docRoot.item.children.size).toEqual(1); const tData = context.getData(getChildItem(docRoot.item, 'test-1')); expect(tData instanceof TestData).toBeTruthy(); - expect(runMock.passed).toHaveBeenCalledWith(tData.item, undefined); + expect(jestRun.passed).toHaveBeenCalledWith(tData.item); }); it('if no test suite result yet, children list is empty', () => { context.ext.testResultProvider.getTestSuiteResult.mockReturnValue(undefined); const uri: any = { fsPath: '/ws-1/a.test.ts' }; const parentItem: any = controllerMock.createTestItem('ws-1', 'ws-1', uri); const docRoot = new TestDocumentRoot(context, uri, parentItem); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); expect(docRoot.item.children.size).toEqual(0); }); }); it('FolderData do not support discoverTest', () => { - controllerMock.createTestRun.mockClear(); const parentItem: any = controllerMock.createTestItem('parent', 'parent', {}); const folder = new FolderData(context, 'whatever', parentItem); expect(folder.item.canResolveChildren).toBe(false); @@ -658,6 +695,7 @@ describe('test-item-data', () => { describe('run request', () => { it('WorkspaceRoot runs all tests in the workspace in blocking-2 queue', () => { const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.scheduleTest(jestRun); const r = context.ext.session.scheduleProcess.mock.calls[0][0]; expect(r.type).toEqual('all-tests'); @@ -667,6 +705,7 @@ describe('test-item-data', () => { it('FolderData runs all tests inside the folder', () => { const parent: any = controllerMock.createTestItem('ws-1', 'ws-1', { fsPath: '/ws-1' }); const folderData = new FolderData(context, 'folder', parent); + const jestRun = createTestRun(); folderData.scheduleTest(jestRun); expect(context.ext.session.scheduleProcess).toHaveBeenCalledWith( expect.objectContaining({ @@ -683,6 +722,7 @@ describe('test-item-data', () => { { fsPath: '/ws-1/a.test.ts' } as any, parent ); + const jestRun = createTestRun(); docRoot.scheduleTest(jestRun); expect(context.ext.session.scheduleProcess).toHaveBeenCalledWith( expect.objectContaining({ @@ -697,6 +737,7 @@ describe('test-item-data', () => { const node: any = { fullName: 'a test', attrs: {}, data: {} }; const parent: any = controllerMock.createTestItem('ws-1', 'ws-1', uri); const tData = new TestData(context, uri, node, parent); + const jestRun = createTestRun(); tData.scheduleTest(jestRun); expect(context.ext.session.scheduleProcess).toHaveBeenCalledWith( expect.objectContaining({ @@ -712,18 +753,19 @@ describe('test-item-data', () => { context.ext.session.scheduleProcess.mockReturnValue(undefined); const parent: any = controllerMock.createTestItem('ws-1', 'ws-1', { fsPath: '/ws-1' }); const docRoot = new TestDocumentRoot(context, { fsPath: '/ws-1/a.test.ts' } as any, parent); + const jestRun = createTestRun(); expect(docRoot.scheduleTest(jestRun)).toBeUndefined(); - expect(runMock.errored).toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); - expect(runMock.end).toHaveBeenCalled(); - expect(jestRun.isClosed()).toBeTruthy(); + expect(jestRun.errored).toHaveBeenCalledWith(docRoot.item, expect.anything()); + expect(jestRun.end).toHaveBeenCalled(); }); - it('schedule request will contain itemRun info', () => { + it('schedule request will contain jestTestRun', () => { const parent: any = controllerMock.createTestItem('ws-1', 'ws-1', { fsPath: '/ws-1' }); const folderData = new FolderData(context, 'folder', parent); + const jestRun = createTestRun(); folderData.scheduleTest(jestRun); expect(process.userData.run).toBe(jestRun); - expect(process.userData.run.item).toBe(folderData.item); + expect(process.userData.testItem).toBe(folderData.item); }); it('if test name is not resolved, it will execute the resolved parent test block', () => { const { doc } = createAllTestItems(); @@ -735,11 +777,12 @@ describe('test-item-data', () => { const testNode: any = { fullName: 'a test', attrs: { isGroup: 'yes' }, data: {} }; const descItem = new TestData(context, doc.uri, descNode, doc.item); const testItem = new TestData(context, doc.uri, testNode, descItem.item); + const jestRun = createTestRun(); testItem.scheduleTest(jestRun); // const process: any = context.ext.session.scheduleProcess.mock.results[0].value; expect(process.userData.run).toBe(jestRun); - expect(process.userData.run.item.id).toBe(doc.item.id); + expect(process.userData.testItem.id).toBe(doc.item.id); // try }); describe('can update snapshot based on runProfile', () => { @@ -749,6 +792,7 @@ describe('test-item-data', () => { }); it('with snapshot profile', () => { [wsRoot, folder, doc, testItem].forEach((testItem) => { + const jestRun = createTestRun(); testItem.scheduleTest(jestRun, ItemCommand.updateSnapshot); expect(context.ext.session.scheduleProcess).toHaveBeenCalledWith( expect.objectContaining({ @@ -764,11 +808,10 @@ describe('test-item-data', () => { describe('when test result is ready', () => { describe('WorkspaceRoot will receive testSuiteChanged event to update item status', () => { const file = '/ws-1/a.test.ts'; - let wsRoot; + let wsRoot, onRunEvent, process; beforeEach(() => { jest.clearAllMocks(); context.ext.testResultProvider.getTestList.mockReturnValueOnce([file]); - wsRoot = new WorkspaceRoot(context); // mocking test results const a1 = helper.makeAssertion('test-a', 'KnownSuccess', [], [1, 0]); @@ -778,14 +821,14 @@ describe('test-item-data', () => { status: 'KnownFail', assertionContainer, }); - controllerMock.createTestRun.mockClear(); + wsRoot = new WorkspaceRoot(context); + onRunEvent = context.ext.sessionEvents.onRunEvent.event.mock.calls[0][0]; + process = mockScheduleProcess(context); }); it('for extension-managed runs, the run will be closed after processing the result', () => { // simulate an external run has been scheduled - const process = { id: 'whatever', request: { type: 'all-tests' } }; - const onRunEvent = context.ext.sessionEvents.onRunEvent.event.mock.calls[0][0]; onRunEvent({ type: 'scheduled', process }); - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); // triggers testSuiteChanged event listener context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ @@ -795,30 +838,26 @@ describe('test-item-data', () => { }); // no new run should be created the previous scheduled run should be used to update state - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - const runMock = controllerMock.lastRunMock(); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; const dItem = getChildItem(wsRoot.item, 'a.test.ts'); expect(dItem.children.size).toBe(2); const aItem = getChildItem(dItem, 'test-a'); - expect(runMock.passed).toHaveBeenCalledWith(aItem, undefined); - expect(runMock.end).toHaveBeenCalledTimes(1); + expect(jestRun.passed).toHaveBeenCalledWith(aItem); + expect(jestRun.end).toHaveBeenCalledTimes(1); }); it('for explorer-triggered runs, only the resolve function will be invoked', () => { // simulate an internal run has been scheduled - const process = mockScheduleProcess(context); - - const customEnd = jest.fn(); - [jestRun, runEndSpy, runMock] = createTestRun({ end: customEnd }); - controllerMock.createTestRun.mockClear(); + const jestRun = createTestRun(); + mockedJestTestRun.mockClear(); wsRoot.scheduleTest(jestRun); - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); + expect(JestTestRun).not.toHaveBeenCalled(); - const onRunEvent = context.ext.sessionEvents.onRunEvent.event.mock.calls[0][0]; onRunEvent({ type: 'scheduled', process }); - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(0); + expect(JestTestRun).toHaveBeenCalledTimes(0); // triggers testSuiteChanged event listener context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ @@ -828,55 +867,14 @@ describe('test-item-data', () => { }); // no new run should be created the previous scheduled run should be used to update state - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(0); + expect(JestTestRun).toHaveBeenCalledTimes(0); const dItem = getChildItem(wsRoot.item, 'a.test.ts'); expect(dItem.children.size).toBe(2); const tItem = getChildItem(dItem, 'test-a'); - expect(runMock.passed).toHaveBeenCalledWith(tItem, undefined); - expect(runMock.end).not.toHaveBeenCalled(); - expect(runEndSpy).toHaveBeenCalled(); + expect(jestRun.passed).toHaveBeenCalledWith(tItem); + expect(jestRun.end).toHaveBeenCalled(); }); - it.each` - config | hasLocation - ${{ enabled: false }} | ${false} - ${{ enabled: true }} | ${false} - ${{ enabled: true, showInlineError: false }} | ${false} - ${{ enabled: true, showInlineError: true }} | ${true} - `( - 'testExplore config $config, will show inline error? $hasLocation', - ({ config, hasLocation }) => { - context.ext.settings = { testExplorer: config }; - const process = mockScheduleProcess(context); - - controllerMock.createTestRun.mockClear(); - - wsRoot.scheduleTest(jestRun); - - // triggers testSuiteChanged event listener - context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ - type: 'assertions-updated', - process, - files: [file], - }); - - // no new run should be created the previous scheduled run should be used to update state - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(0); - - const dItem = getChildItem(wsRoot.item, 'a.test.ts'); - const tItem = getChildItem(dItem, 'test-b'); - expect(vscode.TestMessage).toHaveBeenCalled(); - if (hasLocation) { - expect(runMock.failed).toHaveBeenCalledWith( - tItem, - expect.objectContaining({ location: {} }), - undefined - ); - } else { - expect(runMock.failed).toHaveBeenCalledWith(tItem, [], undefined); - } - } - ); }); }); }); @@ -902,6 +900,7 @@ describe('test-item-data', () => { ]; context.ext.testResultProvider.getTestList.mockReturnValue(testFiles); const wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); // verify tree structure @@ -937,6 +936,7 @@ describe('test-item-data', () => { testFiles = ['/ws-1/src/a.test.ts', '/ws-1/src/b.test.ts', '/ws-1/src/app/app.test.ts']; context.ext.testResultProvider.getTestList.mockReturnValue(testFiles); wsRoot = new WorkspaceRoot(context); + const jestRun = createTestRun(); wsRoot.discoverTest(jestRun); }); it('add', () => { @@ -1011,6 +1011,7 @@ describe('test-item-data', () => { assertionContainer, }); docRoot = new TestDocumentRoot(context, { fsPath: '/ws-1/a.test.ts' } as any, parent); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); }); it('add', () => { @@ -1023,29 +1024,30 @@ describe('test-item-data', () => { status: 'KnownFail', assertionContainer, }); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); expect(docRoot.item.children.size).toEqual(2); - expect(runMock.failed).not.toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); + expect(jestRun.failed).not.toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); const desc1 = getChildItem(docRoot.item, 'desc-1'); expect(desc1.children.size).toEqual(2); const t1 = getChildItem(desc1, 'desc-1 test-1'); expect(t1).not.toBeUndefined(); - expect(runMock.passed).toHaveBeenCalledWith(t1, undefined); + expect(jestRun.passed).toHaveBeenCalledWith(t1); const t2 = getChildItem(desc1, 'desc-1 test-2'); expect(t2).not.toBeUndefined(); - expect(runMock.failed).toHaveBeenCalledWith(t2, expect.anything(), undefined); + expect(jestRun.failed).toHaveBeenCalledWith(t2, expect.anything()); const desc2 = getChildItem(docRoot.item, 'desc-2'); const t3 = getChildItem(desc2, 'desc-2 test-3'); expect(t3).not.toBeUndefined(); - expect(runMock.passed).toHaveBeenCalledWith(t3, undefined); + expect(jestRun.passed).toHaveBeenCalledWith(t3); const t4 = getChildItem(desc2, 'desc-2 test-4'); expect(t4).not.toBeUndefined(); - expect(runMock.skipped).toHaveBeenCalledWith(t4); + expect(jestRun.skipped).toHaveBeenCalledWith(t4); }); it('delete', () => { // delete the only test -1 @@ -1054,6 +1056,7 @@ describe('test-item-data', () => { status: 'Unknown', assertionContainer, }); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); expect(docRoot.item.children.size).toEqual(0); }); @@ -1065,12 +1068,13 @@ describe('test-item-data', () => { assertionContainer, }); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); expect(docRoot.item.children.size).toEqual(1); - expect(runMock.failed).not.toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); + expect(jestRun.failed).not.toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); const t2 = getChildItem(docRoot.item, 'test-2'); expect(t2).not.toBeUndefined(); - expect(runMock.failed).toHaveBeenCalledWith(t2, expect.anything(), undefined); + expect(jestRun.failed).toHaveBeenCalledWith(t2, expect.anything()); }); it('with syntax error', () => { const assertionContainer = buildAssertionContainer([]); @@ -1078,15 +1082,13 @@ describe('test-item-data', () => { status: 'KnownFail', assertionContainer, }); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); expect(docRoot.item.children.size).toEqual(0); - expect(runMock.failed).toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); + expect(jestRun.failed).toHaveBeenCalledWith(docRoot.item, expect.anything()); }); describe('duplicate test names', () => { const setup = (assertions) => { - runMock.passed.mockClear(); - runMock.failed.mockClear(); - const assertionContainer = buildAssertionContainer(assertions); context.ext.testResultProvider.getTestSuiteResult.mockReturnValue({ status: 'KnownFail', @@ -1097,31 +1099,34 @@ describe('test-item-data', () => { const a2 = helper.makeAssertion('test-1', 'KnownFail', [], [1, 0]); const a3 = helper.makeAssertion('test-1', 'KnownSuccess', [], [1, 0]); setup([a2, a3]); + const jestRun = createTestRun(); docRoot.discoverTest(jestRun); expect(docRoot.item.children.size).toEqual(2); - expect(runMock.failed).not.toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); + expect(jestRun.failed).not.toHaveBeenCalledWith(docRoot.item, expect.anything(), undefined); const items = []; docRoot.item.children.forEach((item) => items.push(item)); expect(items[0].id).not.toEqual(items[1].id); items.forEach((item) => expect(item.id).toEqual(expect.stringContaining('test-1'))); - expect(runMock.failed).toHaveBeenCalledTimes(1); - expect(runMock.passed).toHaveBeenCalledTimes(1); + expect(jestRun.failed).toHaveBeenCalledTimes(1); + expect(jestRun.passed).toHaveBeenCalledTimes(1); }); it('can still sync with test results', () => { const a2 = helper.makeAssertion('test-1', 'KnownFail', [], [1, 0]); const a3 = helper.makeAssertion('test-1', 'KnownSuccess', [], [1, 0]); setup([a2, a3]); + let jestRun = createTestRun(); docRoot.discoverTest(jestRun); - expect(runMock.failed).toHaveBeenCalledTimes(1); - expect(runMock.passed).toHaveBeenCalledTimes(1); + expect(jestRun.failed).toHaveBeenCalledTimes(1); + expect(jestRun.passed).toHaveBeenCalledTimes(1); //update a2 status a2.status = 'KnownSuccess'; setup([a2, a3]); + jestRun = createTestRun(); docRoot.discoverTest(jestRun); - expect(runMock.failed).toHaveBeenCalledTimes(0); - expect(runMock.passed).toHaveBeenCalledTimes(2); + expect(jestRun.failed).toHaveBeenCalledTimes(0); + expect(jestRun.passed).toHaveBeenCalledTimes(2); }); }); }); @@ -1173,37 +1178,24 @@ describe('test-item-data', () => { const listener = context.ext.sessionEvents.onRunEvent.event.mock.results[0].value; expect(listener.dispose).toHaveBeenCalled(); }); - it('can adapt raw output to terminal output', () => { - // cSpell: ignore myarn - const coloredText = '[2Kyarn run v1.22.5\n'; - jestRun.write(coloredText); - expect(jestRun.vscodeRun.appendOutput).toHaveBeenCalledWith( - expect.stringContaining(coloredText) - ); - }); - describe('optionally clear terminal on start & schedule', () => { + describe('optionally clear terminal on start', () => { let env; beforeEach(() => { env = setupTestEnv(); }); - it.each([{ type: 'scheduled' }, { type: 'start' }])( - '$type: clear when autoClearTerminal is true', - ({ type }) => { - context.ext.settings = { autoClearTerminal: true }; - const process = mockScheduleProcess(context); - env.onRunEvent({ type, process }); - expect(context.output.clear).toHaveBeenCalled(); - } - ); - it.each([{ type: 'scheduled' }, { type: 'start' }])( - '$type: do not clear when when autoClearTerminal is false', - ({ type }) => { - context.ext.settings = { autoClearTerminal: false }; - const process = mockScheduleProcess(context); - env.onRunEvent({ type, process }); - expect(context.output.clear).not.toHaveBeenCalled(); + it.each` + type | clearOutput + ${'schedule'} | ${false} + ${'start'} | ${true} + `('runEvent $type will clear output ? $clearOutput', ({ type, clearOutput }) => { + const process = mockScheduleProcess(context); + env.onRunEvent({ type, process }); + if (clearOutput) { + expect(outputManager.clearOutputOnRun).toHaveBeenCalled(); + } else { + expect(outputManager.clearOutputOnRun).not.toHaveBeenCalled(); } - ); + }); }); describe('handle run event to set item status and show output', () => { let env; @@ -1214,7 +1206,6 @@ describe('test-item-data', () => { let process; beforeEach(() => { process = mockScheduleProcess(context); - [jestRun, runEndSpy, runMock] = createTestRun({ end: jest.fn() }); }); describe.each` itemType @@ -1225,24 +1216,24 @@ describe('test-item-data', () => { `('will use run passed from explorer throughout for $targetItem item', ({ itemType }) => { it('item will be enqueued after schedule', () => { const item = env.scheduleItem(itemType); - expect(process.userData.run.vscodeRun.enqueued).toHaveBeenCalledWith(item); + expect(process.userData.run.enqueued).toHaveBeenCalledWith(item); + expect(process.userData.testItem).toEqual(item); }); it('item will show started when jest run started', () => { const item = env.scheduleItem(itemType); - process.userData.run.vscodeRun.enqueued.mockClear(); + mockedJestTestRun.mockClear(); - // scheduled event has no effect env.onRunEvent({ type: 'scheduled', process }); - expect(process.userData.run.vscodeRun.enqueued).not.toHaveBeenCalled(); + expect(process.userData.run.enqueued).toHaveBeenCalled(); // starting the process env.onRunEvent({ type: 'start', process }); - expect(process.userData.run.item).toBe(item); - expect(process.userData.run.vscodeRun.started).toHaveBeenCalledWith(item); + expect(process.userData.testItem).toBe(item); + expect(process.userData.run.started).toHaveBeenCalledWith(item); //will not create new run - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); + expect(mockedJestTestRun).not.toHaveBeenCalled(); }); it.each` case | text | raw | newLine | isError | outputText | outputOptions @@ -1255,12 +1246,13 @@ describe('test-item-data', () => { 'can output process data: case $case', ({ text, raw, newLine, isError, outputText, outputOptions }) => { env.scheduleItem(itemType); + mockedJestTestRun.mockClear(); env.onRunEvent({ type: 'start', process }); env.onRunEvent({ type: 'data', process, text, raw, newLine, isError }); - - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); - expect(context.output.write).toHaveBeenCalledWith(outputText, outputOptions); + // no new run should be created + expect(mockedJestTestRun).not.toHaveBeenCalled(); + expect(process.userData.run.write).toHaveBeenCalledWith(outputText, outputOptions); } ); it.each([ @@ -1268,42 +1260,45 @@ describe('test-item-data', () => { { type: 'exit', error: 'something is wrong' }, { type: 'exit', error: 'something is wrong', code: 127 }, { type: 'exit', error: 'something is wrong', code: 1 }, - ])("will only resolve the promise and not close the run for event '%s'", (event) => { + ])("will always close the run for event '%s'", (event) => { env.scheduleItem(itemType); + mockedJestTestRun.mockClear(); + env.onRunEvent({ type: 'start', process }); - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); - expect(process.userData.run.vscodeRun.started).toHaveBeenCalled(); + expect(mockedJestTestRun).not.toHaveBeenCalled(); + expect(process.userData.run.started).toHaveBeenCalled(); env.onRunEvent({ ...event, process }); - expect(process.userData.run.vscodeRun.end).not.toHaveBeenCalled(); - - expect(runEndSpy).toHaveBeenCalled(); + expect(process.userData.run.end).toHaveBeenCalled(); }); - it('can report exit error even if run is ended', () => { + it('can report exit error even if run is ended earlier', () => { env.scheduleItem(itemType); + mockedJestTestRun.mockClear(); env.onRunEvent({ type: 'start', process }); env.onRunEvent({ type: 'end', process }); - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); - expect(process.userData.run.vscodeRun.end).not.toHaveBeenCalled(); - expect(runEndSpy).toHaveBeenCalled(); + expect(mockedJestTestRun).not.toHaveBeenCalled(); + expect(process.userData.run.end).toHaveBeenCalledTimes(1); const error = 'something is wrong'; env.onRunEvent({ type: 'exit', error, process }); // no new run need to be created - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); - expect(process.userData.run.vscodeRun.appendOutput).toHaveBeenCalledWith( - expect.stringContaining(error) + expect(mockedJestTestRun).not.toHaveBeenCalled(); + expect(process.userData.run.write).toHaveBeenCalledWith( + expect.stringContaining(error), + expect.anything() ); + // end will be called again + expect(process.userData.run.end).toHaveBeenCalledTimes(2); }); }); }); describe('extension-managed runs', () => { const file = '/ws-1/tests/a.test.ts'; beforeEach(() => { - controllerMock.createTestRun.mockClear(); + mockedJestTestRun.mockClear(); }); describe.each` request | withFile @@ -1314,39 +1309,48 @@ describe('test-item-data', () => { ${{ type: 'by-file', testFileName: 'source.ts', notTestFile: true }} | ${false} ${{ type: 'by-file-pattern', testFileNamePattern: file }} | ${true} `('will create a new run and use it throughout: $request', ({ request, withFile }) => { - it('if run starts before schedule returns: no enqueue', () => { - const process = { id: 'whatever', request }; + it('if only reports assertion-update, everything should still work', () => { + const process: any = { id: 'whatever', request }; const item = withFile ? env.testFile : env.wsRoot.item; - // starting the process - env.onRunEvent({ type: 'start', process }); - const runMock = controllerMock.lastRunMock(); - expect(runMock.started).toHaveBeenCalledWith(item); + expect(mockedJestTestRun).toHaveBeenCalledTimes(0); - //followed by scheduled - env.onRunEvent({ type: 'scheduled', process }); - // run has already started, do nothing, - expect(runMock.enqueued).not.toHaveBeenCalled(); + // triggers testSuiteChanged event listener when process has no run or item info + context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ + type: 'assertions-updated', + process, + files: [env.file], + }); - //will create 1 new run - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); + // a run should have been created + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + + // and the process.userData should be updated + expect(process.userData.run).toBe(jestRun); + expect(process.userData.testItem).toBe(item); + + // will close run afterwards + expect(jestRun.end).toHaveBeenCalled(); }); it('if run starts after schedule: show enqueue then start', () => { - const process = { id: 'whatever', request }; + const process: any = { id: 'whatever', request }; const item = withFile ? env.testFile : env.wsRoot.item; //scheduled env.onRunEvent({ type: 'scheduled', process }); - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - const runMock = controllerMock.lastRunMock(); - expect(runMock.enqueued).toHaveBeenCalledWith(item); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(jestRun.enqueued).toHaveBeenCalledWith(item); + // the run should be injected to the process.userData + expect(process.userData.run).toBe(jestRun); // followed by starting process env.onRunEvent({ type: 'start', process }); - expect(runMock.started).toHaveBeenCalledWith(item); + expect(jestRun.started).toHaveBeenCalledWith(item); //will create 1 new run - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); }); it.each` case | text | raw | newLine | isError | outputText | outputOptions @@ -1358,60 +1362,50 @@ describe('test-item-data', () => { `( 'can output process data: case $case', ({ text, raw, newLine, isError, outputText, outputOptions }) => { - const process = { id: 'whatever', request }; + const process: any = { id: 'whatever', request }; env.onRunEvent({ type: 'start', process }); env.onRunEvent({ type: 'data', process, text, raw, newLine, isError }); - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - expect(context.output.write).toHaveBeenCalledWith(outputText, outputOptions); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + expect(process.userData.run.write).toHaveBeenCalledWith(outputText, outputOptions); } ); it.each([['end'], ['exit']])("close the run on event '%s'", (eventType) => { const process = { id: 'whatever', request: { type: 'all-tests' } }; env.onRunEvent({ type: 'start', process }); - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - const runMock = controllerMock.lastRunMock(); - expect(runMock.started).toHaveBeenCalled(); - expect(runMock.end).not.toHaveBeenCalled(); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(jestRun.started).toHaveBeenCalled(); + expect(jestRun.end).not.toHaveBeenCalled(); env.onRunEvent({ type: eventType, process }); - expect(runMock.end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); }); it('can report exit error even if run is ended', () => { - const process = { id: 'whatever', request: { type: 'all-tests' } }; + const process: any = { id: 'whatever', request: { type: 'all-tests' } }; env.onRunEvent({ type: 'start', process }); env.onRunEvent({ type: 'end', process }); - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - const runMock = controllerMock.lastRunMock(); - expect(runMock.end).toHaveBeenCalled(); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(jestRun.end).toHaveBeenCalled(); const error = 'something is wrong'; env.onRunEvent({ type: 'exit', error, process }); - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(2); - const runMock2 = controllerMock.lastRunMock(); + // no new run need to be created + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); - expect(context.output.write).toHaveBeenCalledWith(error, expect.anything()); - expect(runMock2.errored).toHaveBeenCalled(); - expect(runMock2.end).toHaveBeenCalled(); + expect(jestRun.write).toHaveBeenCalledWith(error, expect.anything()); + expect(jestRun.errored).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); }); it('can report end error', () => { - const process = { id: 'whatever', request: { type: 'all-tests' } }; + const process: any = { id: 'whatever', request: { type: 'all-tests' } }; env.onRunEvent({ type: 'start', process }); env.onRunEvent({ type: 'end', process, error: 'whatever' }); - expect(context.output.write).toHaveBeenCalledWith('whatever', 'error'); - }); - it('if WorkspaceRoot is disposed before process end, all pending run will be closed', () => { - const process = { id: 'whatever', request: { type: 'all-tests' } }; - env.onRunEvent({ type: 'start', process }); - - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - const runMock = controllerMock.lastRunMock(); - - env.wsRoot.dispose(); - expect(runMock.end).toHaveBeenCalled(); + expect(process.userData.run.write).toHaveBeenCalledWith('whatever', 'error'); }); }); describe('request not supported', () => { @@ -1425,11 +1419,7 @@ describe('test-item-data', () => { // starting the process env.onRunEvent({ type: 'start', process }); - const runMock = controllerMock.lastRunMock(); - expect(runMock.started).not.toHaveBeenCalled(); - - //will not create any run - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); + expect(mockedJestTestRun).not.toHaveBeenCalled(); }); }); }); @@ -1437,24 +1427,29 @@ describe('test-item-data', () => { const process = mockScheduleProcess(context); const testFileData = context.getData(env.testFile); + const jestRun = createTestRun(); testFileData.scheduleTest(jestRun); - expect(jestRun.vscodeRun.enqueued).toHaveBeenCalledTimes(2); + expect(jestRun.enqueued).toHaveBeenCalledTimes(2); [env.testFile, env.testBlock].forEach((t) => - expect(jestRun.vscodeRun.enqueued).toHaveBeenCalledWith(t) + expect(jestRun.enqueued).toHaveBeenCalledWith(t) ); env.onRunEvent({ type: 'start', process }); - expect(jestRun.vscodeRun.started).toHaveBeenCalledTimes(2); + expect(jestRun.started).toHaveBeenCalledTimes(2); [env.testFile, env.testBlock].forEach((t) => - expect(jestRun.vscodeRun.started).toHaveBeenCalledWith(t) + expect(jestRun.started).toHaveBeenCalledWith(t) ); }); it('log long-run event', () => { const process = mockScheduleProcess(context); + mockedJestTestRun.mockClear(); env.onRunEvent({ type: 'long-run', threshold: 60000, process }); - expect(context.output.write).toHaveBeenCalledTimes(1); - expect(context.output.write).toHaveBeenCalledWith( + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + + expect(jestRun.write).toHaveBeenCalledTimes(1); + expect(jestRun.write).toHaveBeenCalledWith( expect.stringContaining('60000'), errors.LONG_RUNNING_TESTS ); @@ -1500,159 +1495,126 @@ describe('test-item-data', () => { }); }); - describe('simulate complete run flow', () => { + describe('test run management', () => { let env; beforeEach(() => { env = setupTestEnv(); + mockedJestTestRun.mockClear(); + contextCreateTestRunSpy.mockClear(); }); - describe('testExplorer managed run', () => { - let pRun, runRequest, notifyProvider, createTestRunSpy; - beforeEach(() => { - notifyProvider = jest.fn(); - runRequest = {}; - [pRun] = createTestRun({ request: runRequest }); - jestRun = new JestTestRun(context, pRun, { end: notifyProvider }); - createTestRunSpy = jest.spyOn(context, 'createTestRun'); - }); - it('run explicit test block', () => { - const process: any = mockScheduleProcess(context); + describe('for process related events', () => { + it('one run per process', () => { + // schedule a test run for a specific testBlock const item = env.scheduleItem('testBlock'); - expect(process.userData.run).toBe(jestRun); - expect(process.userData.run.vscodeRun.enqueued).toHaveBeenCalledWith(item); - expect(process.userData.run.item).toBe(item); - - //end the process: will not actually end the run but to only notify the provider - env.onRunEvent({ type: 'end', process }); - expect(process.userData.run.isClosed()).toBeFalsy(); - expect(notifyProvider).toHaveBeenCalled(); - - //the run ends before results come in, the process's run should reflect it - pRun.end(); - expect(jestRun.isClosed()).toBeTruthy(); - expect(process.userData.run.isClosed()).toBeTruthy(); - - // prepare for result processing - controllerMock.createTestRun.mockClear(); - createTestRunSpy.mockClear(); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + expect(env.process.userData.testItem).toBe(item); + expect(env.process.userData.run).not.toBeUndefined(); + const jestRun = env.process.userData.run; + + // reset mocks + mockedJestTestRun.mockClear(); + contextCreateTestRunSpy.mockClear(); + + // go through the full events flow + // start + env.onRunEvent({ type: 'start', process: env.process }); + expect(mockedJestTestRun).toHaveBeenCalledTimes(0); + expect(jestRun.end).toHaveBeenCalledTimes(0); + + // data + env.onRunEvent({ type: 'data', process: env.process, raw: 'whatever', text: 'whatever' }); + expect(mockedJestTestRun).toHaveBeenCalledTimes(0); + expect(jestRun.end).toHaveBeenCalledTimes(0); + + //end + env.onRunEvent({ type: 'end', process: env.process }); + expect(mockedJestTestRun).toHaveBeenCalledTimes(0); + expect(jestRun.end).toHaveBeenCalledTimes(1); + const endOption1 = jestRun.end.mock.calls[0][0]; + expect(endOption1).toEqual( + expect.objectContaining({ + pid: env.process.id, + delay: expect.anything(), + reason: expect.anything(), + }) + ); - // triggers testSuiteChanged event listener + // test result updated context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ type: 'assertions-updated', - process, + process: env.process, files: [env.file], }); - - // expect the item status to be updated in a new run since the previous one is closed - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - expect(controllerMock.createTestRun).toHaveBeenCalledWith(runRequest, expect.anything()); - runMock = controllerMock.lastRunMock(); - expect(runMock.failed).toHaveBeenCalledWith(item, expect.anything(), undefined); - expect(runMock.failed).not.toHaveBeenCalledWith(env.testFile, expect.anything(), undefined); - - // the new testRun should still have the same item and request - expect(createTestRunSpy).toHaveBeenCalledTimes(1); - const aRequest = createTestRunSpy.mock.calls[0][0]; - const option = createTestRunSpy.mock.calls[0][1]; - expect(aRequest).not.toBe(runRequest); - expect(option.item.id).toEqual(item.id); + expect(mockedJestTestRun).toHaveBeenCalledTimes(0); + expect(jestRun.end).toHaveBeenCalledTimes(2); + const endOption2 = jestRun.end.mock.calls[1][0]; + expect(endOption2).toEqual( + expect.objectContaining({ + pid: env.process.id, + delay: expect.anything(), + reason: expect.anything(), + }) + ); + expect(endOption1.delay).toBeGreaterThan(endOption2.delay); + + // test exit + env.onRunEvent({ type: 'exit', process: env.process, error: 'some error' }); + expect(mockedJestTestRun).toHaveBeenCalledTimes(0); + expect(jestRun.end).toHaveBeenCalledTimes(3); + const endOption3 = jestRun.end.mock.calls[2][0]; + expect(endOption3).toEqual( + expect.objectContaining({ + pid: env.process.id, + delay: expect.anything(), + reason: expect.anything(), + }) + ); + expect(endOption1.delay).toBeGreaterThan(endOption3.delay); + expect(endOption2.delay).toBeGreaterThanOrEqual(endOption3.delay); }); - it('run explicit test block will not hang run with or without result', () => { - const process: any = mockScheduleProcess(context); - const item = env.scheduleItem('testBlock'); - createTestRunSpy.mockClear(); + it('multiple process can share a run', () => { + const { testBlock, testFile } = env; + const jestRun = createTestRun(); - expect(process.userData.run).toBe(jestRun); - expect(process.userData.run.vscodeRun.enqueued).toHaveBeenCalledWith(item); - expect(process.userData.run.item).toBe(item); - - //end the process: will not actually end the run but to only notify the provider - env.onRunEvent({ type: 'end', process }); - expect(process.userData.run.isClosed()).toBeFalsy(); - expect(notifyProvider).toHaveBeenCalled(); + const p1 = mockScheduleProcess(context, 'p1'); + context.getData(testBlock).scheduleTest(jestRun); - //the parent run ends before test process completes - pRun.end(); - expect(jestRun.isClosed()).toBeTruthy(); - expect(process.userData.run.isClosed()).toBeTruthy(); + const p2 = mockScheduleProcess(context, 'p2'); + context.getData(testFile).scheduleTest(jestRun); - //received more data event: will not create new run - env.onRunEvent({ type: 'data', process, raw: 'whatever', text: 'whatever' }); - expect(createTestRunSpy).not.toHaveBeenCalled(); + expect(JestTestRun).toHaveBeenCalledTimes(1); + expect(p1.userData.run).toBe(jestRun); + expect(p2.userData.run).toBe(jestRun); + expect(p1).not.toEqual(p2); - // prepare for result processing - controllerMock.createTestRun.mockClear(); - createTestRunSpy.mockClear(); - - // triggers testSuiteChanged event listener - context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ - type: 'assertions-updated', - process, - files: [env.file], - }); - - // expect the item status to be updated with a new run - expect(controllerMock.createTestRun).toHaveBeenCalledTimes(1); - runMock = controllerMock.lastRunMock(); - // and the run should be closed - expect(runMock.end).toHaveBeenCalled(); - }); - }); - describe('extension managed background runs', () => { - let createTestRunSpy; - beforeEach(() => { - createTestRunSpy = jest.spyOn(context, 'createTestRun'); + env.onRunEvent({ type: 'end', process: p1 }); + env.onRunEvent({ type: 'end', process: p2 }); + expect(JestTestRun).toHaveBeenCalledTimes(1); + expect(jestRun.end).toHaveBeenCalledTimes(2); }); - it('watch-test run', () => { - const request: any = { type: 'watch-tests' }; - const process: any = { id: 'whatever', request }; - const item = env.wsRoot.item; - - // starting the process - env.onRunEvent({ type: 'start', process }); - - expect(createTestRunSpy).toHaveBeenCalledTimes(1); - let opt = createTestRunSpy.mock.calls[0][1]; - expect(opt.item.id).toEqual(item.id); - - runMock = controllerMock.lastRunMock(); - expect(runMock.started).toHaveBeenCalledWith(item); - expect(process.userData?.run).toBeUndefined(); - - createTestRunSpy.mockClear(); - - //received output: no new run should be created - const text = 'some data'; - env.onRunEvent({ type: 'data', process, text, raw: text }); - expect(createTestRunSpy).not.toHaveBeenCalled(); - expect(context.output.write).toHaveBeenCalledWith(text, undefined); - - createTestRunSpy.mockClear(); - - //end the run - env.onRunEvent({ type: 'end', process }); - expect(runMock.end).toHaveBeenCalled(); - - // prepare for result processing - createTestRunSpy.mockClear(); + it('if process has no run but with testItem, will create a new run', () => { + // schedule a test run for a specific testBlock + const item = env.scheduleItem('testBlock'); + expect(mockedJestTestRun).toHaveBeenCalledTimes(1); + expect(env.process.userData.testItem).toBe(item); + expect(env.process.userData.run).not.toBeUndefined(); + const jestRun = env.process.userData.run; - // process test results - context.ext.testResultProvider.events.testSuiteChanged.event.mock.calls[0][0]({ - type: 'assertions-updated', - process, - files: [env.file], - }); + // remove run from process.userData + env.process.userData.run = undefined; - // expect the item status to be updated in a new run since the previous one is closed - expect(createTestRunSpy).toHaveBeenCalledTimes(1); - opt = createTestRunSpy.mock.calls[0][1]; - expect(opt.item.id).toEqual(item.id); + // start + env.onRunEvent({ type: 'start', process: env.process }); - runMock = controllerMock.lastRunMock(); - expect(runMock.failed).toHaveBeenCalledWith(env.testBlock, expect.anything(), undefined); - expect(runMock.failed).not.toHaveBeenCalledWith(env.testFile, expect.anything(), undefined); + // a new run should be created + expect(mockedJestTestRun).toHaveBeenCalledTimes(2); + expect(env.process.userData.run).not.toBeUndefined(); + expect(env.process.userData.run).not.toBe(jestRun); }); }); + describe('non-process related event', () => {}); }); + describe('runItemCommand', () => { let wsRoot, folder, doc, testItem; beforeEach(() => { @@ -1663,13 +1625,12 @@ describe('test-item-data', () => { expect(context.ext.output.show).toHaveBeenCalledTimes(1); }); it('can update-snapshot for every TestItemData', () => { - const createTestRunSpy = jest.spyOn(context, 'createTestRun'); [wsRoot, folder, doc, testItem].forEach((itemData) => { - createTestRunSpy.mockClear(); + contextCreateTestRunSpy.mockClear(); context.ext.session.scheduleProcess.mockClear(); itemData.runItemCommand(ItemCommand.updateSnapshot); - expect(createTestRunSpy).toHaveBeenCalledTimes(1); + expect(contextCreateTestRunSpy).toHaveBeenCalledTimes(1); expect(context.ext.session.scheduleProcess).toHaveBeenCalledWith( expect.objectContaining({ updateSnapshot: true }), expect.anything() diff --git a/tests/test-provider/test-provider-helper.test.ts b/tests/test-provider/test-provider-context.test.ts similarity index 65% rename from tests/test-provider/test-provider-helper.test.ts rename to tests/test-provider/test-provider-context.test.ts index 8a0533067..99b7e1c0f 100644 --- a/tests/test-provider/test-provider-helper.test.ts +++ b/tests/test-provider/test-provider-context.test.ts @@ -1,59 +1,12 @@ -jest.unmock('../../src/test-provider/test-provider-helper'); -jest.unmock('../../src/test-provider/test-provider-helper'); +import '../manual-mocks'; + +jest.unmock('../../src/test-provider/test-provider-context'); jest.unmock('./test-helper'); import * as vscode from 'vscode'; -import { JestTestRun } from '../../src/test-provider/test-provider-helper'; -import { JestTestProviderContext } from '../../src/test-provider/test-provider-helper'; -import { mockController, mockExtExplorerContext } from './test-helper'; - -describe('JestTestRun', () => { - let context, controllerMock, vRun, item; - beforeEach(() => { - jest.resetAllMocks(); - controllerMock = mockController(); - const profiles: any = [{ tag: { id: 'run' } }, { tag: { id: 'debug' } }]; - context = new JestTestProviderContext(mockExtExplorerContext('ws-1'), controllerMock, profiles); - vRun = controllerMock.createTestRun({}, 'whatever'); - item = {}; - }); - it('can detect status update after run is closed', () => { - const jestRun = new JestTestRun(context, vRun); - jestRun.enqueued(item); - expect(vRun.enqueued).toHaveBeenCalled(); - - jestRun.passed(item); - expect(vRun.passed).toHaveBeenCalled(); - - // end the run - jestRun.end(); - expect(jestRun.isClosed()).toBeTruthy(); - expect(vRun.end).toHaveBeenCalled(); - - //update state now should throw exception - expect(() => jestRun.passed(item)).toThrow(); - }); - describe('can chain JestTestRun backed by a single vscode Run', () => { - let jestRun1, jestRun2; - beforeEach(() => { - jestRun1 = new JestTestRun(context, vRun); - jestRun2 = new JestTestRun(context, jestRun1); - }); - - it('both are backed by the same vscode.TestRun', () => { - expect(jestRun1.vscodeRun).toBe(jestRun2.vscodeRun); - }); +import { JestTestProviderContext } from '../../src/test-provider/test-provider-context'; +import { JestTestRun } from '../../src/test-provider/jest-test-run'; - it('close the top of the chain will close the underlying vscodeRun and mark isClose() state', () => { - jestRun2.end(); - - expect(jestRun2.isClosed()).toBeTruthy(); - expect(jestRun1.isClosed()).toBeTruthy(); - expect(jestRun2.vscodeRun).toBeUndefined(); - expect(jestRun1.vscodeRun).toBeUndefined(); - }); - }); -}); describe('JestTestProviderContext', () => { it('when try to getTag not in any profiles, throw error', () => { const whatever: any = {}; @@ -62,6 +15,30 @@ describe('JestTestProviderContext', () => { expect(context.getTag('run')).toEqual(profile.tag); expect(() => context.getTag('debug')).toThrow(); }); + it('createTestRun should create a JIT JestTestRun', () => { + const extContext: any = {}; + const mockRun: any = { appendOutput: jest.fn() }; + const mockController: any = { createTestRun: jest.fn().mockReturnValue(mockRun) }; + const profile: any = { tag: { id: 'run' } }; + const context = new JestTestProviderContext(extContext, mockController, [profile]); + const request: any = {}; + + const mockJestRun: any = {}; + (JestTestRun as jest.Mocked) = jest.fn().mockReturnValue(mockJestRun); + const jestRun = context.createTestRun(request, { name: 'test-run' }); + + expect(jestRun).toBe(mockJestRun); + expect(JestTestRun).toHaveBeenCalledWith('test-run', context, expect.anything()); + // no vscode run should be created yet + expect(mockController.createTestRun).not.toHaveBeenCalled(); + + // vscode run will be created through the factory function + const factory = (JestTestRun as jest.Mocked).mock.calls[0][2]; + const run = factory('new-test-run'); + + expect(mockController.createTestRun).toHaveBeenCalledWith(request, 'new-test-run'); + expect(run).toBe(mockRun); + }); describe('requestFrom', () => { let context: JestTestProviderContext; let mockCollection; diff --git a/tests/test-provider/test-provider.test.ts b/tests/test-provider/test-provider.test.ts index 3a9d2e6d8..519de8244 100644 --- a/tests/test-provider/test-provider.test.ts +++ b/tests/test-provider/test-provider.test.ts @@ -1,5 +1,7 @@ +import '../manual-mocks'; + jest.unmock('../../src/test-provider/test-provider'); -jest.unmock('../../src/test-provider/test-provider-helper'); +jest.unmock('../../src/test-provider/test-provider-context'); jest.unmock('../../src/JestExt/run-mode'); jest.unmock('./test-helper'); jest.unmock('../../src/appGlobals'); @@ -7,12 +9,13 @@ jest.unmock('../../src/appGlobals'); import * as vscode from 'vscode'; import { JestTestProvider } from '../../src/test-provider/test-provider'; import { WorkspaceRoot } from '../../src/test-provider/test-item-data'; -import { JestTestProviderContext, JestTestRun } from '../../src/test-provider/test-provider-helper'; +import { JestTestProviderContext } from '../../src/test-provider/test-provider-context'; import { extensionId } from '../../src/appGlobals'; import { mockController, mockExtExplorerContext } from './test-helper'; import { tiContextManager } from '../../src/test-provider/test-item-context-manager'; import { ItemCommand } from '../../src/test-provider/types'; import { RunMode } from '../../src/JestExt/run-mode'; +import { JestTestRun } from '../../src/test-provider/jest-test-run'; const throwError = () => { throw new Error('debug error'); @@ -46,9 +49,11 @@ describe('JestTestProvider', () => { let extExplorerContextMock; let workspaceRootMock; let mockTestTag; + const mockedJestTestRun = JestTestRun as jest.MockedClass; beforeEach(() => { - jest.resetAllMocks(); + // jest.resetAllMocks(); + jest.clearAllMocks(); extExplorerContextMock = mockExtExplorerContext(); @@ -109,32 +114,36 @@ describe('JestTestProvider', () => { }); describe('can discover tests', () => { + it('test mockedJestTestRun', () => { + const jestRun = new JestTestRun('jest-run', {} as any, (() => {}) as any); + expect(jestRun.name).toBe('jest-run'); + }); it('should only discover items with canResolveChildren = true', () => { new JestTestProvider(extExplorerContextMock); const data = setupTestItemData('whatever', true, workspaceRootMock.context); data.item.canResolveChildren = true; controllerMock.resolveHandler(data.item); - expect(controllerMock.createTestRun).toHaveBeenCalled(); - controllerMock.createTestRun.mockClear(); + expect(JestTestRun).toHaveBeenCalled(); + mockedJestTestRun.mockClear(); data.item.canResolveChildren = false; controllerMock.resolveHandler(data.item); - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); + expect(mockedJestTestRun).not.toHaveBeenCalled(); }); describe('when no test item is requested', () => { it('will resolve the whole workspace via workspaceRoot', () => { new JestTestProvider(extExplorerContextMock); workspaceRootMock.item.canResolveChildren = true; controllerMock.resolveHandler(); - expect(controllerMock.createTestRun).toHaveBeenCalled(); expect(workspaceRootMock.discoverTest).toHaveBeenCalledTimes(1); // run will be created with the controller's id - expect(controllerMock.lastRunMock().name).toEqual( - expect.stringContaining(controllerMock.id) - ); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(jestRun.name).toEqual(expect.stringContaining(controllerMock.id)); + // run will be closed - expect(controllerMock.lastRunMock().end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); }); }); describe('when specific item is requested', () => { @@ -143,28 +152,29 @@ describe('JestTestProvider', () => { const data = setupTestItemData('whatever', true, workspaceRootMock.context); data.item.canResolveChildren = true; controllerMock.resolveHandler(data.item); - expect(controllerMock.createTestRun).toHaveBeenCalled(); // run will be created with the controller's id - expect(controllerMock.lastRunMock().name).toEqual( - expect.stringContaining(controllerMock.id) - ); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(jestRun.name).toEqual(expect.stringContaining(controllerMock.id)); + // run will be closed - expect(controllerMock.lastRunMock().end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); }); it('should not crash if item not found in the item-data map', () => { new JestTestProvider(extExplorerContextMock); const data = makeItemData(true); controllerMock.resolveHandler({ canResolveChildren: true }); - expect(controllerMock.createTestRun).toHaveBeenCalled(); expect(data.discoverTest).not.toHaveBeenCalled(); expect(workspaceRootMock.discoverTest).not.toHaveBeenCalled(); + // run will be created with the controller's id - expect(controllerMock.lastRunMock().name).toEqual( - expect.stringContaining(controllerMock.id) - ); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(jestRun.name).toEqual(expect.stringContaining(controllerMock.id)); + // run will be closed - expect(controllerMock.lastRunMock().end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); }); }); describe('if discover failed', () => { @@ -178,11 +188,12 @@ describe('JestTestProvider', () => { expect(workspaceRootMock.item.error).toEqual(expect.stringContaining('discoverTest error')); // run will be created with the controller's id - expect(controllerMock.lastRunMock().name).toEqual( - expect.stringContaining(controllerMock.id) - ); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(jestRun.name).toEqual(expect.stringContaining(controllerMock.id)); + // run will be closed - expect(controllerMock.lastRunMock().end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); }); }); }); @@ -255,12 +266,12 @@ describe('JestTestProvider', () => { await expect(testProvider.runTests(request, cancelToken)).resolves.toBe(undefined); + // run will be created + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + if (hasError) { - expect(controllerMock.lastRunMock().errored).toHaveBeenCalledWith( - itemDataList[0].item, - expect.anything(), - undefined - ); + expect(jestRun.errored).toHaveBeenCalledWith(itemDataList[0].item, expect.anything()); expect(vscode.TestMessage).toHaveBeenCalledTimes(1); } else { if (testNamePattern) { @@ -289,7 +300,8 @@ describe('JestTestProvider', () => { const p = testProvider.runTests(request, cancelToken); // a run is created - expect(controllerMock.createTestRun).toHaveBeenCalled(); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; // verify serial execution expect(extExplorerContextMock.debugTests).toHaveBeenCalledTimes(1); @@ -305,7 +317,7 @@ describe('JestTestProvider', () => { expect(extExplorerContextMock.debugTests).toHaveBeenCalledTimes(3); // the run will be closed - expect(controllerMock.lastRunMock().end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); }); it('cancellation means skip the rest of tests', async () => { expect.hasAssertions(); @@ -322,10 +334,11 @@ describe('JestTestProvider', () => { const p = testProvider.runTests(request, cancelToken); // a run is created - expect(controllerMock.createTestRun).toHaveBeenCalled(); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; + expect(extExplorerContextMock.debugTests).toHaveBeenCalledTimes(1); - const runMock = controllerMock.lastRunMock(); await finishDebug(); expect(extExplorerContextMock.debugTests).toHaveBeenCalledTimes(2); @@ -337,10 +350,10 @@ describe('JestTestProvider', () => { await p; expect(extExplorerContextMock.debugTests).toHaveBeenCalledTimes(2); - expect(runMock.skipped).toHaveBeenCalledWith(request.include[2]); + expect(jestRun.skipped).toHaveBeenCalledWith(request.include[2]); // the run will be closed - expect(runMock.end).toHaveBeenCalledTimes(1); + expect(jestRun.end).toHaveBeenCalledTimes(1); }); it('can handle exception', async () => { expect.hasAssertions(); @@ -358,21 +371,15 @@ describe('JestTestProvider', () => { }; await testProvider.runTests(request, cancelToken); - const runMock = controllerMock.lastRunMock(); + + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; expect(extExplorerContextMock.debugTests).toHaveBeenCalledTimes(3); - expect(runMock.errored).toHaveBeenCalledTimes(2); - expect(runMock.errored).toHaveBeenCalledWith( - request.include[1], - expect.anything(), - undefined - ); - expect(runMock.errored).toHaveBeenCalledWith( - request.include[2], - expect.anything(), - undefined - ); - expect(runMock.end).toHaveBeenCalled(); + expect(jestRun.errored).toHaveBeenCalledTimes(2); + expect(jestRun.errored).toHaveBeenCalledWith(request.include[1], expect.anything()); + expect(jestRun.errored).toHaveBeenCalledWith(request.include[2], expect.anything()); + expect(jestRun.end).toHaveBeenCalled(); }); }); describe('run tests', () => { @@ -402,7 +409,8 @@ describe('JestTestProvider', () => { cancelToken.isCancellationRequested = isCancelled; const p = testProvider.runTests(request, cancelToken); - const runMock = controllerMock.lastRunMock(); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; if (isCancelled) { expect(tData.scheduleTest).not.toHaveBeenCalled(); @@ -411,19 +419,15 @@ describe('JestTestProvider', () => { } await expect(p).resolves.toBe(undefined); - expect(runMock.end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalled(); switch (state) { case 'errored': - expect(runMock.errored).toHaveBeenCalledWith( - tData.item, - expect.anything(), - undefined - ); + expect(jestRun.errored).toHaveBeenCalledWith(tData.item, expect.anything()); expect(vscode.TestMessage).toHaveBeenCalledTimes(1); break; case 'skipped': - expect(runMock.skipped).toHaveBeenCalledWith(tData.item); + expect(jestRun.skipped).toHaveBeenCalledWith(tData.item); expect(vscode.TestMessage).not.toHaveBeenCalled(); break; case undefined: @@ -449,19 +453,19 @@ describe('JestTestProvider', () => { const p = testProvider.runTests(request, cancelToken); // a run is created - expect(controllerMock.createTestRun).toHaveBeenCalled(); - const runMock = controllerMock.lastRunMock(); + expect(JestTestRun).toHaveBeenCalled(); + const jestRun = mockedJestTestRun.mock.results[0].value; itemDataList.forEach((d) => { expect(d.scheduleTest).toHaveBeenCalled(); const [run] = d.scheduleTest.mock.calls[0]; - expect(run).toEqual(expect.objectContaining({ vscodeRun: runMock })); + expect(run).toEqual(jestRun); // simulate each item is done the run run.end(); }); await p; - expect(runMock.end).toHaveBeenCalledTimes(1); + expect(jestRun.end).toHaveBeenCalledTimes(itemDataList.length + 1); }); it('cancellation is passed to the itemData to handle', async () => { @@ -477,23 +481,23 @@ describe('JestTestProvider', () => { }; const p = testProvider.runTests(request, cancelToken); - const runMock = controllerMock.lastRunMock(); // cancel after run cancelToken.isCancellationRequested = true; // a run is already created - expect(controllerMock.createTestRun).toHaveBeenCalled(); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; itemDataList.forEach((d) => { expect(d.scheduleTest).toHaveBeenCalled(); const [run] = d.scheduleTest.mock.calls[0]; - expect(run).toEqual(expect.objectContaining({ vscodeRun: controllerMock.lastRunMock() })); + expect(run).toBe(jestRun); // close the schedule run.end(); }); await p; - expect(runMock.end).toHaveBeenCalledTimes(1); + expect(jestRun.end).toHaveBeenCalledTimes(itemDataList.length + 1); }); describe('can handle exception', () => { it('when schedule test failed', async () => { @@ -520,53 +524,25 @@ describe('JestTestProvider', () => { cancelToken.isCancellationRequested = true; // a run is already created - expect(controllerMock.createTestRun).toHaveBeenCalled(); - const runMock = controllerMock.lastRunMock(); + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; itemDataList.forEach((d, idx) => { expect(d.scheduleTest).toHaveBeenCalled(); const [run] = d.scheduleTest.mock.calls[0]; - expect(run).toEqual( - expect.objectContaining({ vscodeRun: controllerMock.lastRunMock() }) - ); + expect(run).toEqual(jestRun); if (idx === 1) { - expect(run.vscodeRun.errored).toHaveBeenCalledWith( - d.item, - expect.anything(), - undefined - ); + expect(run.errored).toHaveBeenCalledWith(d.item, expect.anything()); } else { - expect(run.vscodeRun.errored).not.toHaveBeenCalledWith( - d.item, - expect.anything(), - undefined - ); - // close the schedule - run.end(); + expect(run.errored).not.toHaveBeenCalledWith(d.item, expect.anything()); } + // close the schedule + run.end(); }); await p; - expect(runMock.end).toHaveBeenCalled(); - }); - it('when debug failed', async () => { - expect.hasAssertions(); - - const testProvider = new JestTestProvider(extExplorerContextMock); - const debugSpy = jest.spyOn(testProvider, 'debugTest'); - debugSpy.mockImplementation(() => { - throw new Error('force an error'); - }); - const writeSpy = jest.spyOn(JestTestRun.prototype, 'write'); - const itemDataList = setupItemData(workspaceRootMock.context); - const request: any = { - include: itemDataList.map((d) => d.item), - profile: { kind: vscode.TestRunProfileKind.Debug, label: 'debug' }, - }; - await testProvider.runTests(request, cancelToken); - expect(debugSpy).toHaveBeenCalled(); - expect(writeSpy).toHaveBeenCalledWith(expect.stringContaining('debug'), 'error'); + expect(jestRun.end).toHaveBeenCalledTimes(itemDataList.length + 1); }); }); it('if no item in request, will run test for the whole workplace', async () => { @@ -579,14 +555,15 @@ describe('JestTestProvider', () => { }; const p = testProvider.runTests(request, cancelToken); - const runMock = controllerMock.lastRunMock(); + + expect(JestTestRun).toHaveBeenCalledTimes(1); + const jestRun = mockedJestTestRun.mock.results[0].value; expect(workspaceRootMock.scheduleTest).toHaveBeenCalledTimes(1); const [run] = workspaceRootMock.scheduleTest.mock.calls[0]; - expect(run).toEqual(expect.objectContaining({ vscodeRun: controllerMock.lastRunMock() })); - run.end(); + expect(run).toBe(jestRun); await p; - expect(runMock.end).toHaveBeenCalled(); + expect(jestRun.end).toHaveBeenCalledTimes(1); }); it('will reject run request without profile', async () => { expect.hasAssertions(); @@ -596,7 +573,7 @@ describe('JestTestProvider', () => { await expect(testProvider.runTests(request, cancelToken)).rejects.not.toThrow(); expect(workspaceRootMock.scheduleTest).toHaveBeenCalledTimes(0); - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); + expect(JestTestRun).not.toHaveBeenCalled(); }); }); }); @@ -641,6 +618,6 @@ describe('JestTestProvider', () => { extExplorerContextMock.workspace, expect.objectContaining({ request }) ); - expect(controllerMock.createTestRun).not.toHaveBeenCalled(); + expect(JestTestRun).not.toHaveBeenCalled(); }); }); diff --git a/yarn.lock b/yarn.lock index bbdb5ff68..63eaaacbd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,164 +2,168 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" -"@babel/compat-data@^7.20.5": - version "7.20.10" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" - integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== +"@babel/compat-data@^7.22.9": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" + integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== "@babel/core@^7.1.0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.7.2": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" - integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helpers" "^7.20.7" - "@babel/parser" "^7.20.7" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.12" - "@babel/types" "^7.20.7" - convert-source-map "^1.7.0" + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" + integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helpers" "^7.23.2" + "@babel/parser" "^7.23.0" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" + json5 "^2.2.3" + semver "^6.3.1" -"@babel/generator@^7.20.7", "@babel/generator@^7.7.2": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" - integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== +"@babel/generator@^7.23.0", "@babel/generator@^7.7.2": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== dependencies: - "@babel/types" "^7.20.7" + "@babel/types" "^7.23.0" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-compilation-targets@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" - integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== +"@babel/helper-compilation-targets@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" lru-cache "^5.1.1" - semver "^6.3.0" - -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-transforms@^7.20.11": - version "7.20.11" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0" - integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.10" - "@babel/types" "^7.20.7" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== - -"@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== - dependencies: - "@babel/types" "^7.20.2" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helpers@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce" - integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA== - dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" + integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + +"@babel/helpers@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" + integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" - integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -197,11 +201,11 @@ "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-jsx@^7.7.2": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -253,67 +257,51 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" - integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/runtime@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" - integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/traverse@7.20.10": - version "7.20.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.10.tgz#2bf98239597fcec12f842756f186a9dde6d09230" - integrity sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.7", "@babel/traverse@^7.7.2": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.12.tgz#7f0f787b3a67ca4475adef1f56cb94f6abd4a4b5" - integrity sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" + integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.15", "@babel/template@^7.3.3": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@7.23.2", "@babel/traverse@^7.23.2", "@babel/traverse@^7.7.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" - integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.3.3": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -342,14 +330,26 @@ esquery "^1.4.0" jsdoc-type-pratt-parser "~3.1.0" -"@eslint/eslintrc@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e" - integrity sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.4.0" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -357,12 +357,17 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== +"@eslint/js@8.52.0": + version "8.52.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.52.0.tgz#78fe5f117840f69dc4a353adf9b9cd926353378c" + integrity sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA== + +"@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== dependencies: - "@humanwhocodes/object-schema" "^1.2.1" + "@humanwhocodes/object-schema" "^2.0.1" debug "^4.1.1" minimatch "^3.0.5" @@ -371,10 +376,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" @@ -392,110 +397,110 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.3.1.tgz#3e3f876e4e47616ea3b1464b9fbda981872e9583" - integrity sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg== +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== dependencies: - "@jest/types" "^29.3.1" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.3.1" - jest-util "^29.3.1" + jest-message-util "^29.7.0" + jest-util "^29.7.0" slash "^3.0.0" -"@jest/core@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.3.1.tgz#bff00f413ff0128f4debec1099ba7dcd649774a1" - integrity sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw== +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== dependencies: - "@jest/console" "^29.3.1" - "@jest/reporters" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^29.2.0" - jest-config "^29.3.1" - jest-haste-map "^29.3.1" - jest-message-util "^29.3.1" - jest-regex-util "^29.2.0" - jest-resolve "^29.3.1" - jest-resolve-dependencies "^29.3.1" - jest-runner "^29.3.1" - jest-runtime "^29.3.1" - jest-snapshot "^29.3.1" - jest-util "^29.3.1" - jest-validate "^29.3.1" - jest-watcher "^29.3.1" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" micromatch "^4.0.4" - pretty-format "^29.3.1" + pretty-format "^29.7.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.3.1.tgz#eb039f726d5fcd14698acd072ac6576d41cfcaa6" - integrity sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag== +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== dependencies: - "@jest/fake-timers" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.3.1" + jest-mock "^29.7.0" -"@jest/expect-utils@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.3.1.tgz#531f737039e9b9e27c42449798acb5bba01935b6" - integrity sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g== +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== dependencies: - jest-get-type "^29.2.0" + jest-get-type "^29.6.3" -"@jest/expect@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.3.1.tgz#456385b62894349c1d196f2d183e3716d4c6a6cd" - integrity sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg== +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== dependencies: - expect "^29.3.1" - jest-snapshot "^29.3.1" + expect "^29.7.0" + jest-snapshot "^29.7.0" -"@jest/fake-timers@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.3.1.tgz#b140625095b60a44de820876d4c14da1aa963f67" - integrity sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A== +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: - "@jest/types" "^29.3.1" - "@sinonjs/fake-timers" "^9.1.2" + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.3.1" - jest-mock "^29.3.1" - jest-util "^29.3.1" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" -"@jest/globals@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.3.1.tgz#92be078228e82d629df40c3656d45328f134a0c6" - integrity sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q== +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== dependencies: - "@jest/environment" "^29.3.1" - "@jest/expect" "^29.3.1" - "@jest/types" "^29.3.1" - jest-mock "^29.3.1" + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" -"@jest/reporters@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.3.1.tgz#9a6d78c109608e677c25ddb34f907b90e07b4310" - integrity sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA== +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" - "@jridgewell/trace-mapping" "^0.3.15" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" @@ -503,52 +508,52 @@ glob "^7.1.3" graceful-fs "^4.2.9" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" + istanbul-lib-instrument "^6.0.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.3.1" - jest-util "^29.3.1" - jest-worker "^29.3.1" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^29.0.0": - version "29.0.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" - integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: - "@sinclair/typebox" "^0.24.1" + "@sinclair/typebox" "^0.27.8" -"@jest/source-map@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" - integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== dependencies: - "@jridgewell/trace-mapping" "^0.3.15" + "@jridgewell/trace-mapping" "^0.3.18" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.3.1.tgz#92cd5099aa94be947560a24610aa76606de78f50" - integrity sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw== +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== dependencies: - "@jest/console" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz#fa24b3b050f7a59d48f7ef9e0b782ab65123090d" - integrity sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA== +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== dependencies: - "@jest/test-result" "^29.3.1" + "@jest/test-result" "^29.7.0" graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" + jest-haste-map "^29.7.0" slash "^3.0.0" "@jest/transform@^27.5.1": @@ -572,26 +577,26 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/transform@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.3.1.tgz#1e6bd3da4af50b5c82a539b7b1f3770568d6e36d" - integrity sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug== +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.3.1" - "@jridgewell/trace-mapping" "^0.3.15" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" - jest-regex-util "^29.2.0" - jest-util "^29.3.1" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" - write-file-atomic "^4.0.1" + write-file-atomic "^4.0.2" "@jest/types@^27.5.1": version "27.5.1" @@ -604,62 +609,49 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jest/types@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.3.1.tgz#7c5a80777cb13e703aeec6788d044150341147e3" - integrity sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA== +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: - "@jest/schemas" "^29.0.0" + "@jest/schemas" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": +"@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@0.3.9": version "0.3.9" @@ -669,13 +661,13 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -698,24 +690,24 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@sinclair/typebox@^0.24.1": - version "0.24.51" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" - integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@sinonjs/commons@^1.7.0": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" - integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== dependencies: - "@sinonjs/commons" "^1.7.0" + "@sinonjs/commons" "^3.0.0" "@tootallnate/once@1": version "1.1.2" @@ -743,393 +735,403 @@ integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@types/babel__core@^7.1.14": - version "7.1.20" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359" - integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== + version "7.20.3" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.3.tgz#d5625a50b6f18244425a1359a858c73d70340778" + integrity sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + version "7.6.6" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.6.tgz#676f89f67dc8ddaae923f70ebc5f1fa800c031a8" + integrity sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + version "7.4.3" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.3.tgz#db9ac539a2fe05cfe9e168b24f360701bde41f5f" + integrity sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.18.3" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.3.tgz#dfc508a85781e5698d5b33443416b6268c4b3e8d" - integrity sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w== + version "7.20.3" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.3.tgz#a971aa47441b28ef17884ff945d0551265a2d058" + integrity sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.20.7" "@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + version "3.7.6" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26" + integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.4.10" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" - integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== + version "8.44.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603" + integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa" + integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw== "@types/fs-extra@^11.0.2": - version "11.0.2" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.2.tgz#23dc1ed7b2eba8ccd75568ac34e7a4e48aa2d087" - integrity sha512-c0hrgAOVYr21EX8J0jBMXGLMgJqVf/v6yxi0dLaJboW9aQPh16Id+z6w2Tx1hm+piJOLv8xPfVKZCLfjPw/IMQ== + version "11.0.3" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.3.tgz#72c3a247c8dd5703c93d900c584e006476146866" + integrity sha512-sF59BlXtUdzEAL1u0MSvuzWd7PdZvZEtnaVkzX5mjpdWTJ8brG0jUqve3jPCzSzvAKKMHTG8F8o/WMQLtleZdQ== dependencies: "@types/jsonfile" "*" "@types/node" "*" "@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" - integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== + version "4.1.8" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.8.tgz#417e461e4dc79d957dc3107f45fe4973b09c2915" + integrity sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw== dependencies: "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1", "@types/istanbul-lib-coverage@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068" + integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ== "@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1" + integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-source-maps@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#8acb1f6230bf9d732e9fc30590e5ccaabbefec7b" - integrity sha512-WH6e5naLXI3vB2Px3whNeYxzDgm6S6sk3Ht8e3/BiWwEnzZi72wja3bWzWwcgbFTFp8hBLB7NT2p3lNJgxCxvA== + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.3.tgz#890a632d738d092555874286402103580af7c97b" + integrity sha512-QbnnstlXTwvHIykU3+jph84eL9x0RPfnfpawmJ8yrCMhhdYHsZSKbP08jOYJ/ABiTSSBSrIH1A5dKWReVyOiMw== dependencies: "@types/istanbul-lib-coverage" "*" source-map "^0.6.1" "@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7" + integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg== dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^29.2.5": - version "29.2.5" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.5.tgz#c27f41a9d6253f288d1910d3c5f09484a56b73c0" - integrity sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw== +"@types/jest@^29.5.6": + version "29.5.7" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.7.tgz#2c0dafe2715dd958a455bc10e2ec3e1ec47b5036" + integrity sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g== dependencies: expect "^29.0.0" pretty-format "^29.0.0" "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + version "7.0.14" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" + integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== "@types/jsonfile@*": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.2.tgz#d3b8a3536c5bb272ebee0f784180e456b7691c8f" - integrity sha512-8t92P+oeW4d/CRQfJaSqEwXujrhH4OEeHRjGU3v1Q8mUS8GPF3yiX26sw4svv6faL2HfBtGTe2xWIoVgN3dy9w== + version "6.1.3" + resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.3.tgz#683d447b413119393e913ecd414a2bc0e5d0f4b9" + integrity sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA== dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^18.11.18": - version "18.11.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" - integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== +"@types/node@*": + version "20.8.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.9.tgz#646390b4fab269abce59c308fc286dcd818a2b08" + integrity sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg== + dependencies: + undici-types "~5.26.4" + +"@types/node@^18.11.18": + version "18.18.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.8.tgz#2b285361f2357c8c8578ec86b5d097c7f464cfd6" + integrity sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ== + dependencies: + undici-types "~5.26.4" "@types/prettier@^2.1.5": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" - integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/semver@^7.3.12": - version "7.3.13" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" - integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== + version "7.5.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" + integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== "@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b" + integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw== "@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + version "21.0.2" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b" + integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw== "@types/yargs@^16.0.0": - version "16.0.5" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" - integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== + version "16.0.7" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.7.tgz#b0d0502cb5f6c17994df72a600049f10bbf17203" + integrity sha512-lQcYmxWuOfJq4IncK88/nwud9rwr1F04CFc5xzk0k4oKVyz/AI35TfsXmhjf6t8zp8mpCOi17BfvuNWx+zrYkg== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.19" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.19.tgz#8dbecdc9ab48bee0cb74f6e3327de3fa0d0c98ae" - integrity sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ== + version "17.0.29" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf" + integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz#deee67e399f2cb6b4608c935777110e509d8018c" - integrity sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ== - dependencies: - "@typescript-eslint/scope-manager" "5.48.1" - "@typescript-eslint/type-utils" "5.48.1" - "@typescript-eslint/utils" "5.48.1" + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" + graphemer "^1.4.0" ignore "^5.2.0" natural-compare-lite "^1.4.0" - regexpp "^3.2.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/parser@^5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.48.1.tgz#d0125792dab7e232035434ab8ef0658154db2f10" - integrity sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== dependencies: - "@typescript-eslint/scope-manager" "5.48.1" - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/typescript-estree" "5.48.1" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz#39c71e4de639f5fe08b988005beaaf6d79f9d64d" - integrity sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/visitor-keys" "5.48.1" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/type-utils@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz#5d94ac0c269a81a91ad77c03407cea2caf481412" - integrity sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ== +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== dependencies: - "@typescript-eslint/typescript-estree" "5.48.1" - "@typescript-eslint/utils" "5.48.1" + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.1.tgz#efd1913a9aaf67caf8a6e6779fd53e14e8587e14" - integrity sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/typescript-estree@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz#9efa8ee2aa471c6ab62e649f6e64d8d121bc2056" - integrity sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA== +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/visitor-keys" "5.48.1" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.48.1", "@typescript-eslint/utils@^5.10.0": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.1.tgz#20f2f4e88e9e2a0961cbebcb47a1f0f7da7ba7f9" - integrity sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA== +"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== dependencies: + "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.48.1" - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/typescript-estree" "5.48.1" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" eslint-scope "^5.1.1" - eslint-utils "^3.0.0" semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz#79fd4fb9996023ef86849bf6f904f33eb6c8fccb" - integrity sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA== +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: - "@typescript-eslint/types" "5.48.1" + "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + "@vscode/test-electron@^2.2.2": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@vscode/test-electron/-/test-electron-2.2.2.tgz#2ec559ad6b879bc4024ffc0c5e192e4c5d0ff704" - integrity sha512-s5d2VtMySvff0UgqkJ0BMCr1es+qREE194EAodGIefq518W53ifvv69e80l9e2MrYJEqUUKwukE/w3H9o15YEw== + version "2.3.6" + resolved "https://registry.yarnpkg.com/@vscode/test-electron/-/test-electron-2.3.6.tgz#61a6ec1b4bdc9a2a694a9d7d86b9cb8b82c5a116" + integrity sha512-M31xGH0RgqNU6CZ4/9g39oUMJ99nLzfjA+4UbtIQ6TcXQ6+2qkjOOxedmPBDDCg26/3Al5ubjY80hIoaMwKYSw== dependencies: http-proxy-agent "^4.0.1" https-proxy-agent "^5.0.0" - rimraf "^3.0.2" - unzipper "^0.10.11" - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + jszip "^3.10.1" + semver "^7.5.2" + +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.0.1.tgz#a69720f6c9bad6aef54a8fa6ba9c3533e7ef4c7f" - integrity sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A== +"@webpack-cli/configtest@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" + integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== -"@webpack-cli/info@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.1.tgz#eed745799c910d20081e06e5177c2b2569f166c0" - integrity sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA== +"@webpack-cli/info@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" + integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== -"@webpack-cli/serve@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.1.tgz#34bdc31727a1889198855913db2f270ace6d7bf8" - integrity sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw== +"@webpack-cli/serve@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" + integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -1141,10 +1143,10 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== acorn-jsx@^5.3.2: version "5.3.2" @@ -1152,19 +1154,14 @@ acorn-jsx@^5.3.2: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + version "8.3.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" + integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== -acorn@^8.4.1: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - -acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== agent-base@6: version "6.0.2" @@ -1178,7 +1175,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1249,15 +1246,15 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -babel-jest@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.3.1.tgz#05c83e0d128cd48c453eea851482a38782249f44" - integrity sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA== +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== dependencies: - "@jest/transform" "^29.3.1" + "@jest/transform" "^29.7.0" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.2.0" + babel-preset-jest "^29.6.3" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" @@ -1273,10 +1270,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094" - integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA== +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -1301,12 +1298,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc" - integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA== +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== dependencies: - babel-plugin-jest-hoist "^29.2.0" + babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -1314,29 +1311,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -big-integer@^1.6.17: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -binary@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" - integrity sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg== - dependencies: - buffers "~0.1.1" - chainsaw "~0.1.0" - -bluebird@~3.4.1: - version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" - integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA== - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1352,15 +1331,15 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.14.5, browserslist@^4.21.3: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== +browserslist@^4.14.5, browserslist@^4.21.9: + version "4.22.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" + integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" + caniuse-lite "^1.0.30001541" + electron-to-chromium "^1.4.535" + node-releases "^2.0.13" + update-browserslist-db "^1.0.13" bs-logger@0.x: version "0.2.6" @@ -1381,16 +1360,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-indexof-polyfill@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" - integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== - -buffers@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" - integrity sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ== - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1406,19 +1375,12 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001400: - version "1.0.30001442" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz#40337f1cf3be7c637b061e2f78582dc1daec0614" - integrity sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow== +caniuse-lite@^1.0.30001541: + version "1.0.30001558" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001558.tgz#d2c6e21fdbfe83817f70feab902421a19b7983ee" + integrity sha512-/Et7DwLqpjS47JPEcz6VnxU9PwcIdVi0ciLXRWBQdj1XFye68pSQYpV0QtPTfUKWuOaEig+/Vez2l74eDc1tPQ== -chainsaw@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" - integrity sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ== - dependencies: - traverse ">=0.3.0 <0.4" - -chalk@^2.0.0: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1446,14 +1408,14 @@ chrome-trace-event@^1.0.2: integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^3.2.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.7.1.tgz#708a6cdae38915d597afdf3b145f2f8e1ff55f3f" - integrity sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w== + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== cliui@^8.0.1: version "8.0.1" @@ -1479,9 +1441,9 @@ co@^4.6.0: integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" @@ -1508,20 +1470,20 @@ color-name@~1.1.4: integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^2.0.14: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^9.4.1: - version "9.5.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" - integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== - comment-parser@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b" @@ -1532,7 +1494,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.4.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== @@ -1543,15 +1505,28 @@ convert-source-map@^2.0.0: integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== core-js@^3.17.3: - version "3.27.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.27.1.tgz#23cc909b315a6bb4e418bf40a52758af2103ba46" - integrity sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww== + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb" + integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ== core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -1573,10 +1548,10 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +dedent@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" + integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== deep-is@^0.1.3: version "0.1.4" @@ -1584,9 +1559,9 @@ deep-is@^0.1.3: integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== detect-newline@^3.0.0: version "3.1.0" @@ -1598,10 +1573,10 @@ diff-sequences@^27.5.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== -diff-sequences@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" - integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diff@^4.0.1: version "4.0.2" @@ -1622,17 +1597,10 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -duplexer2@~0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" - integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA== - dependencies: - readable-stream "^2.0.2" - -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== +electron-to-chromium@^1.4.535: + version "1.4.571" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.571.tgz#8aa71539eb82db98740c3ec861256cc34e0356fd" + integrity sha512-Sc+VtKwKCDj3f/kLBjdyjMpNzoZsU6WuL/wFb6EH8USmHEcebxRXcRrVpOpayxd52tuey4RUDpUsw5OS5LhJqg== emittery@^0.13.1: version "0.13.1" @@ -1649,18 +1617,18 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== -enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== +enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" envinfo@^7.7.3: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + version "7.10.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" + integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== error-ex@^1.3.1: version "1.3.2" @@ -1669,10 +1637,10 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1" + integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== escalade@^3.1.1: version "3.1.1" @@ -1695,21 +1663,21 @@ escape-string-regexp@^4.0.0: integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eslint-config-prettier@^8.6.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz#dec1d29ab728f4fa63061774e1672ac4e363d207" - integrity sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA== + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== eslint-plugin-jest@^27.2.1: - version "27.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz#b85b4adf41c682ea29f1f01c8b11ccc39b5c672c" - integrity sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg== + version "27.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.6.0.tgz#e5c0cf735b3c8cad0ef9db5b565b2fc99f5e55ed" + integrity sha512-MTlusnnDMChbElsszJvrwD1dN3x6nZl//s4JD23BxB6MgR66TZlL064su24xEIS3VACfAoHV1vgyMgPw8nkdng== dependencies: "@typescript-eslint/utils" "^5.10.0" eslint-plugin-jsdoc@^39.6.4: - version "39.6.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.4.tgz#b940aebd3eea26884a0d341785d2dc3aba6a38a7" - integrity sha512-fskvdLCfwmPjHb6e+xNGDtGgbF8X7cDwMtVLAP2WwSf9Htrx68OAx31BESBM1FAwsN2HTQyYQq7m4aW4Q4Nlag== + version "39.9.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.9.1.tgz#e9ce1723411fd7ea0933b3ef0dd02156ae3068e2" + integrity sha512-Rq2QY6BZP2meNIs48aZ3GlIlJgBqFCmR55+UBvaDkA3ZNQ0SvQXOs2QKkubakEijV8UbIVbVZKsOVN8G3MuqZw== dependencies: "@es-joy/jsdoccomment" "~0.36.1" comment-parser "1.3.1" @@ -1739,94 +1707,81 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.31.0: - version "8.31.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.31.0.tgz#75028e77cbcff102a9feae1d718135931532d524" - integrity sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA== - dependencies: - "@eslint/eslintrc" "^1.4.1" - "@humanwhocodes/config-array" "^0.11.8" + version "8.52.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.52.0.tgz#d0cd4a1fac06427a61ef9242b9353f36ea7062fc" + integrity sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "8.52.0" + "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.4.0" - esquery "^1.4.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" find-up "^5.0.0" glob-parent "^6.0.2" globals "^13.19.0" - grapheme-splitter "^1.0.4" + graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" - js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.4.0: - version "9.4.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" - integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.0, esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -1887,16 +1842,16 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" -expect@^29.0.0, expect@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.3.1.tgz#92877aad3f7deefc2e3f6430dd195b92295554a6" - integrity sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA== +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== dependencies: - "@jest/expect-utils" "^29.3.1" - jest-get-type "^29.2.0" - jest-matcher-utils "^29.3.1" - jest-message-util "^29.3.1" - jest-util "^29.3.1" + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" @@ -1904,14 +1859,14 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -1979,17 +1934,23 @@ find-up@^5.0.0: path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" + integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== fs-extra@^11.1.1: version "11.1.1" @@ -2006,24 +1967,14 @@ fs.realpath@^1.0.0: integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" @@ -2082,9 +2033,9 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.19.0: - version "13.19.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" - integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== dependencies: type-fest "^0.20.2" @@ -2100,20 +2051,15 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graceful-fs@^4.1.6, graceful-fs@^4.2.0: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== has-flag@^3.0.0: version "3.0.0" @@ -2125,12 +2071,12 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== dependencies: - function-bind "^1.1.1" + function-bind "^1.1.2" html-escaper@^2.0.0: version "2.0.2" @@ -2164,7 +2110,12 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2193,7 +2144,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@~2.0.0, inherits@~2.0.3: +inherits@2, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2208,12 +2159,12 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - has "^1.0.3" + hasown "^2.0.0" is-extglob@^2.1.1: version "2.1.1" @@ -2284,7 +2235,7 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: +istanbul-lib-instrument@^5.0.4: version "5.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== @@ -2295,13 +2246,24 @@ istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" +istanbul-lib-instrument@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz#71e87707e8041428732518c6fb5211761753fbdf" + integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0, istanbul-lib-source-maps@^4.0.1: @@ -2314,89 +2276,90 @@ istanbul-lib-source-maps@^4.0.0, istanbul-lib-source-maps@^4.0.1: source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289" - integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA== +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== dependencies: execa "^5.0.0" + jest-util "^29.7.0" p-limit "^3.1.0" -jest-circus@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.3.1.tgz#177d07c5c0beae8ef2937a67de68f1e17bbf1b4a" - integrity sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg== +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== dependencies: - "@jest/environment" "^29.3.1" - "@jest/expect" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - dedent "^0.7.0" + dedent "^1.0.0" is-generator-fn "^2.0.0" - jest-each "^29.3.1" - jest-matcher-utils "^29.3.1" - jest-message-util "^29.3.1" - jest-runtime "^29.3.1" - jest-snapshot "^29.3.1" - jest-util "^29.3.1" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" p-limit "^3.1.0" - pretty-format "^29.3.1" + pretty-format "^29.7.0" + pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.3.1.tgz#e89dff427db3b1df50cea9a393ebd8640790416d" - integrity sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ== +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== dependencies: - "@jest/core" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" chalk "^4.0.0" + create-jest "^29.7.0" exit "^0.1.2" - graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.3.1" - jest-util "^29.3.1" - jest-validate "^29.3.1" - prompts "^2.0.1" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" yargs "^17.3.1" -jest-config@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.3.1.tgz#0bc3dcb0959ff8662957f1259947aedaefb7f3c6" - integrity sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg== +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.3.1" - "@jest/types" "^29.3.1" - babel-jest "^29.3.1" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.3.1" - jest-environment-node "^29.3.1" - jest-get-type "^29.2.0" - jest-regex-util "^29.2.0" - jest-resolve "^29.3.1" - jest-runner "^29.3.1" - jest-util "^29.3.1" - jest-validate "^29.3.1" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.3.1" + pretty-format "^29.7.0" slash "^3.0.0" strip-json-comments "^3.1.1" @@ -2410,67 +2373,67 @@ jest-diff@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-diff@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.3.1.tgz#d8215b72fed8f1e647aed2cae6c752a89e757527" - integrity sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw== +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== dependencies: chalk "^4.0.0" - diff-sequences "^29.3.1" - jest-get-type "^29.2.0" - pretty-format "^29.3.1" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" -jest-docblock@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" - integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== dependencies: detect-newline "^3.0.0" -jest-each@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.3.1.tgz#bc375c8734f1bb96625d83d1ca03ef508379e132" - integrity sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA== +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== dependencies: - "@jest/types" "^29.3.1" + "@jest/types" "^29.6.3" chalk "^4.0.0" - jest-get-type "^29.2.0" - jest-util "^29.3.1" - pretty-format "^29.3.1" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" -jest-editor-support@^31.1.1: - version "31.1.1" - resolved "https://registry.yarnpkg.com/jest-editor-support/-/jest-editor-support-31.1.1.tgz#46fa8280e6484a2695a6c7c882852e3821100181" - integrity sha512-bCKpKWAMLhjK7QDX9geBDzfyvZacl937hnT3Z+yfERBx8bB7yZg2uhvCBErqO51Ie+wgg42Ffo8rn+Nhdr2hHQ== +jest-editor-support@^31.1.2: + version "31.1.2" + resolved "https://registry.yarnpkg.com/jest-editor-support/-/jest-editor-support-31.1.2.tgz#d88f043b8c9cf9adecffb7a6b29e3f1090f6bd52" + integrity sha512-QlCN8dWVxMcmvzbkH2G1gSNjMPFM+69+Lx9WZcpYiHEaqrb1QKuVJrVNfbjHrlv0PhgCvzf1EdYKh8qqrQ3Rhw== dependencies: "@babel/parser" "^7.20.7" "@babel/runtime" "^7.20.7" - "@babel/traverse" "7.20.10" + "@babel/traverse" "7.23.2" "@babel/types" "^7.20.7" core-js "^3.17.3" jest-snapshot "^27.2.0" -jest-environment-node@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.3.1.tgz#5023b32472b3fba91db5c799a0d5624ad4803e74" - integrity sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag== +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== dependencies: - "@jest/environment" "^29.3.1" - "@jest/fake-timers" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.3.1" - jest-util "^29.3.1" + jest-mock "^29.7.0" + jest-util "^29.7.0" jest-get-type@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== -jest-get-type@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" - integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== jest-haste-map@^27.5.1: version "27.5.1" @@ -2492,32 +2455,32 @@ jest-haste-map@^27.5.1: optionalDependencies: fsevents "^2.3.2" -jest-haste-map@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.3.1.tgz#af83b4347f1dae5ee8c2fb57368dc0bb3e5af843" - integrity sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A== +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== dependencies: - "@jest/types" "^29.3.1" + "@jest/types" "^29.6.3" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^29.2.0" - jest-util "^29.3.1" - jest-worker "^29.3.1" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz#95336d020170671db0ee166b75cd8ef647265518" - integrity sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA== +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== dependencies: - jest-get-type "^29.2.0" - pretty-format "^29.3.1" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" jest-matcher-utils@^27.5.1: version "27.5.1" @@ -2529,15 +2492,15 @@ jest-matcher-utils@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-matcher-utils@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz#6e7f53512f80e817dfa148672bd2d5d04914a572" - integrity sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ== +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== dependencies: chalk "^4.0.0" - jest-diff "^29.3.1" - jest-get-type "^29.2.0" - pretty-format "^29.3.1" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" jest-message-util@^27.5.1: version "27.5.1" @@ -2554,29 +2517,29 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" -jest-message-util@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.3.1.tgz#37bc5c468dfe5120712053dd03faf0f053bd6adb" - integrity sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA== +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.3.1" + "@jest/types" "^29.6.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.3.1" + pretty-format "^29.7.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.3.1.tgz#60287d92e5010979d01f218c6b215b688e0f313e" - integrity sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA== +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== dependencies: - "@jest/types" "^29.3.1" + "@jest/types" "^29.6.3" "@types/node" "*" - jest-util "^29.3.1" + jest-util "^29.7.0" jest-pnp-resolver@^1.2.2: version "1.2.3" @@ -2588,86 +2551,86 @@ jest-regex-util@^27.5.1: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== -jest-regex-util@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" - integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== -jest-resolve-dependencies@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz#a6a329708a128e68d67c49f38678a4a4a914c3bf" - integrity sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA== +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== dependencies: - jest-regex-util "^29.2.0" - jest-snapshot "^29.3.1" + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" -jest-resolve@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.3.1.tgz#9a4b6b65387a3141e4a40815535c7f196f1a68a7" - integrity sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw== +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" + jest-haste-map "^29.7.0" jest-pnp-resolver "^1.2.2" - jest-util "^29.3.1" - jest-validate "^29.3.1" + jest-util "^29.7.0" + jest-validate "^29.7.0" resolve "^1.20.0" - resolve.exports "^1.1.0" + resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.3.1.tgz#a92a879a47dd096fea46bb1517b0a99418ee9e2d" - integrity sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA== +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== dependencies: - "@jest/console" "^29.3.1" - "@jest/environment" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^29.2.0" - jest-environment-node "^29.3.1" - jest-haste-map "^29.3.1" - jest-leak-detector "^29.3.1" - jest-message-util "^29.3.1" - jest-resolve "^29.3.1" - jest-runtime "^29.3.1" - jest-util "^29.3.1" - jest-watcher "^29.3.1" - jest-worker "^29.3.1" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.3.1.tgz#21efccb1a66911d6d8591276a6182f520b86737a" - integrity sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A== - dependencies: - "@jest/environment" "^29.3.1" - "@jest/fake-timers" "^29.3.1" - "@jest/globals" "^29.3.1" - "@jest/source-map" "^29.2.0" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" - jest-message-util "^29.3.1" - jest-mock "^29.3.1" - jest-regex-util "^29.2.0" - jest-resolve "^29.3.1" - jest-snapshot "^29.3.1" - jest-util "^29.3.1" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" slash "^3.0.0" strip-bom "^4.0.0" @@ -2707,35 +2670,31 @@ jest-snapshot@^27.2.0: pretty-format "^27.5.1" semver "^7.3.2" -jest-snapshot@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.3.1.tgz#17bcef71a453adc059a18a32ccbd594b8cc4e45e" - integrity sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA== +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/babel__traverse" "^7.0.6" - "@types/prettier" "^2.1.5" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.3.1" + expect "^29.7.0" graceful-fs "^4.2.9" - jest-diff "^29.3.1" - jest-get-type "^29.2.0" - jest-haste-map "^29.3.1" - jest-matcher-utils "^29.3.1" - jest-message-util "^29.3.1" - jest-util "^29.3.1" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" natural-compare "^1.4.0" - pretty-format "^29.3.1" - semver "^7.3.5" + pretty-format "^29.7.0" + semver "^7.5.3" jest-util@^27.5.1: version "27.5.1" @@ -2749,42 +2708,42 @@ jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-util@^29.0.0, jest-util@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.3.1.tgz#1dda51e378bbcb7e3bc9d8ab651445591ed373e1" - integrity sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ== +jest-util@^29.0.0, jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: - "@jest/types" "^29.3.1" + "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.3.1.tgz#d56fefaa2e7d1fde3ecdc973c7f7f8f25eea704a" - integrity sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g== +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: - "@jest/types" "^29.3.1" + "@jest/types" "^29.6.3" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.2.0" + jest-get-type "^29.6.3" leven "^3.1.0" - pretty-format "^29.3.1" + pretty-format "^29.7.0" -jest-watcher@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.3.1.tgz#3341547e14fe3c0f79f9c3a4c62dbc3fc977fd4a" - integrity sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg== +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== dependencies: - "@jest/test-result" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.13.1" - jest-util "^29.3.1" + jest-util "^29.7.0" string-length "^4.0.1" jest-worker@^27.4.5, jest-worker@^27.5.1: @@ -2796,30 +2755,25 @@ jest-worker@^27.4.5, jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" -jest-worker@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.3.1.tgz#e9462161017a9bb176380d721cab022661da3d6b" - integrity sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw== +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: "@types/node" "*" - jest-util "^29.3.1" + jest-util "^29.7.0" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.3.1.tgz#c130c0d551ae6b5459b8963747fed392ddbde122" - integrity sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA== +jest@^29.7: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== dependencies: - "@jest/core" "^29.3.1" - "@jest/types" "^29.3.1" + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" import-local "^3.0.2" - jest-cli "^29.3.1" - -js-sdsl@^4.1.4: - version "4.2.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" - integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== + jest-cli "^29.7.0" js-tokens@^4.0.0: version "4.0.0" @@ -2851,6 +2805,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -2866,7 +2825,7 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@^2.1.2, json5@^2.2.1, json5@^2.2.2: +json5@^2.1.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -2880,6 +2839,23 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jszip@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -2903,16 +2879,18 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -listenercount@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" - integrity sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ== - loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -2965,12 +2943,12 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== dependencies: - semver "^6.0.0" + semver "^7.5.3" make-error@1.x, make-error@^1.1.1: version "1.3.6" @@ -3026,18 +3004,6 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== - -"mkdirp@>=0.5 0": - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -3063,10 +3029,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.6: - version "2.0.8" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae" - integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== normalize-path@^3.0.0: version "3.0.0" @@ -3094,17 +3060,17 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" p-limit@^2.2.0: version "2.3.0" @@ -3139,6 +3105,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -3192,9 +3163,9 @@ picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pirates@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^4.2.0: version "4.2.0" @@ -3216,9 +3187,9 @@ prettier-linter-helpers@^1.0.0: fast-diff "^1.1.2" prettier@^2.8.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.2.tgz#c4ea1b5b454d7c4b59966db2e06ed7eec5dfd160" - integrity sha512-BtRV9BcncDyI2tsuS19zzhzoxD8Dh8LiCx7j7tHzrkz8GFXAexeWFdi22mjE1d16dftH2qNaytVxqiRTGlMfpw== + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== pretty-format@^27.5.1: version "27.5.1" @@ -3229,12 +3200,12 @@ pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^29.0.0, pretty-format@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.3.1.tgz#1841cac822b02b4da8971dacb03e8a871b4722da" - integrity sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg== +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: - "@jest/schemas" "^29.0.0" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -3252,9 +3223,14 @@ prompts@^2.0.1: sisteransi "^1.0.5" punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-rand@^6.0.0: + version "6.0.4" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.4.tgz#50b737f6a925468679bff00ad20eade53f37d5c7" + integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== queue-microtask@^1.2.2: version "1.2.3" @@ -3286,10 +3262,10 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -readable-stream@^2.0.2, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== +readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -3306,15 +3282,10 @@ rechoir@^0.8.0: dependencies: resolve "^1.20.0" -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== require-directory@^2.1.1: version "2.1.1" @@ -3338,17 +3309,17 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== resolve@^1.20.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -3357,13 +3328,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -3388,35 +3352,35 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" -semver@7.x, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.2, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.3.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== dependencies: randombytes "^2.1.0" -setimmediate@~1.0.4: +setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== @@ -3476,6 +3440,11 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + spdx-exceptions@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" @@ -3490,9 +3459,9 @@ spdx-expression-parse@^3.0.1: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.12" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" - integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== sprintf-js@~1.0.2: version "1.0.3" @@ -3547,7 +3516,7 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -3583,24 +3552,24 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.1.3: - version "5.3.6" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" - integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== +terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== dependencies: - "@jridgewell/trace-mapping" "^0.3.14" + "@jridgewell/trace-mapping" "^0.3.17" jest-worker "^27.4.5" schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" -terser@^5.14.1: - version "5.16.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.1.tgz#5af3bc3d0f24241c7fb2024199d5c461a1075880" - integrity sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw== +terser@^5.16.8: + version "5.23.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.23.0.tgz#a9c02bc3087d0f5b1cc63bbfb4fe0f7e5dbbde82" + integrity sha512-Iyy83LN0uX9ZZLCX4Qbu5JiHiWjOCTwrmM9InWOzVeM++KNWEsqV4YgN9U9E8AlohQ6Gs42ztczlWOG/lwDAMA== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" @@ -3635,34 +3604,30 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -"traverse@>=0.3.0 <0.4": - version "0.3.9" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" - integrity sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ== - ts-jest@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.3.tgz#63ea93c5401ab73595440733cefdba31fcf9cb77" - integrity sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ== + version "29.1.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" + integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" jest-util "^29.0.0" - json5 "^2.2.1" + json5 "^2.2.3" lodash.memoize "4.x" make-error "1.x" - semver "7.x" + semver "^7.5.3" yargs-parser "^21.0.1" ts-loader@^9.4.2: - version "9.4.2" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.2.tgz#80a45eee92dd5170b900b3d00abcfa14949aeb78" - integrity sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA== + version "9.5.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.0.tgz#f0a51dda37cc4d8e43e6cb14edebbc599b0c3aa2" + integrity sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" micromatch "^4.0.0" semver "^7.3.4" + source-map "^0.7.4" ts-node@^10.9.1: version "10.9.1" @@ -3725,35 +3690,24 @@ typedarray-to-buffer@^3.1.5: is-typedarray "^1.0.0" typescript@^4.9.4: - version "4.9.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unzipper@^0.10.11: - version "0.10.11" - resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.10.11.tgz#0b4991446472cbdb92ee7403909f26c2419c782e" - integrity sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw== - dependencies: - big-integer "^1.6.17" - binary "~0.3.0" - bluebird "~3.4.1" - buffer-indexof-polyfill "~1.0.0" - duplexer2 "~0.1.4" - fstream "^1.0.12" - graceful-fs "^4.2.2" - listenercount "~1.0.1" - readable-stream "~2.3.6" - setimmediate "~1.0.4" - -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -3776,13 +3730,13 @@ v8-compile-cache-lib@^3.0.1: integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== v8-to-istanbul@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" - integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + version "9.1.3" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" + integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" + convert-source-map "^2.0.0" walker@^1.0.7, walker@^1.0.8: version "1.0.8" @@ -3800,16 +3754,16 @@ watchpack@^2.4.0: graceful-fs "^4.1.2" webpack-cli@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.0.1.tgz#95fc0495ac4065e9423a722dec9175560b6f2d9a" - integrity sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A== + version "5.1.4" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b" + integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^2.0.1" - "@webpack-cli/info" "^2.0.1" - "@webpack-cli/serve" "^2.0.1" + "@webpack-cli/configtest" "^2.1.1" + "@webpack-cli/info" "^2.0.2" + "@webpack-cli/serve" "^2.0.5" colorette "^2.0.14" - commander "^9.4.1" + commander "^10.0.1" cross-spawn "^7.0.3" envinfo "^7.7.3" fastest-levenshtein "^1.0.12" @@ -3819,11 +3773,12 @@ webpack-cli@^5.0.1: webpack-merge "^5.7.3" webpack-merge@^5.7.3: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + version "5.10.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== dependencies: clone-deep "^4.0.1" + flat "^5.0.2" wildcard "^2.0.0" webpack-sources@^3.2.3: @@ -3832,21 +3787,21 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.75.0: - version "5.76.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" - integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== + version "5.89.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" + integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" + acorn-import-assertions "^1.9.0" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.15.0" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" @@ -3855,9 +3810,9 @@ webpack@^5.75.0: loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" + terser-webpack-plugin "^5.3.7" watchpack "^2.4.0" webpack-sources "^3.2.3" @@ -3869,14 +3824,9 @@ which@^2.0.1: isexe "^2.0.0" wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -word-wrap@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" - integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== wrap-ansi@^7.0.0: version "7.0.0" @@ -3902,7 +3852,7 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write-file-atomic@^4.0.1: +write-file-atomic@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== @@ -3931,9 +3881,9 @@ yargs-parser@^21.0.1, yargs-parser@^21.1.1: integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.3.1: - version "17.6.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" - integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" escalade "^3.1.1"