diff --git a/package.json b/package.json index b034ec6b..f3efc4f6 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "@testing-library/user-event": "^14.5.1", "@types/content-type": "^1.1.5", "@types/grecaptcha": "^3.0.9", + "@types/jest": "^30.0.0", "@types/jsdom": "^21.1.7", "@types/lodash-es": "^4.17.12", "@types/node": "^24.0.0", diff --git a/src/livekit/NoiseSuppressionTransformer.test.ts b/src/livekit/NoiseSuppressionTransformer.test.ts index 5cbb0db5..62edfa4a 100644 --- a/src/livekit/NoiseSuppressionTransformer.test.ts +++ b/src/livekit/NoiseSuppressionTransformer.test.ts @@ -6,12 +6,7 @@ Please see LICENSE in the repository root for full details. */ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { - DeepFilterNoiseFilterProcessor, - __setEnabledSpy as mockSetEnabled, - __setSuppressionLevelSpy as mockSetSuppressionLevel, - __destroySpy as mockDestroy, -} from "deepfilternet3-noise-filter"; +import { DeepFilterNoiseFilterProcessor } from "deepfilternet3-noise-filter"; import { NoiseSuppressionTransformer } from "./NoiseSuppressionTransformer"; @@ -23,41 +18,48 @@ type DeepFilterNoiseFilterProcessorContext = { destroy?: unknown; }; -vi.mock("deepfilternet3-noise-filter", () => { - const setEnabled = vi.fn(); - const setSuppressionLevel = vi.fn(); - const destroy = vi.fn(); +type NoiseFilterProcessorMock = ReturnType & { + mockSetEnabled: ReturnType; + mockSetSuppressionLevel: ReturnType; + mockDestroy: ReturnType; +}; - function DeepFilterNoiseFilterProcessor( - this: DeepFilterNoiseFilterProcessorContext, - options: DeepFilterNoiseFilterProcessorOptions, - ): void { - Object.assign(this, options); - this.setEnabled = setEnabled; - this.setSuppressionLevel = setSuppressionLevel; - this.destroy = destroy; - } +vi.mock("deepfilternet3-noise-filter", () => { + const mockSetEnabled = vi.fn(); + const mockSetSuppressionLevel = vi.fn(); + const mockDestroy = vi.fn(); + + const mockDeepFilterNoiseFilterProcessor = vi + .fn() + .mockImplementation(function DeepFilterNoiseFilterProcessor( + this: DeepFilterNoiseFilterProcessorContext, + options: DeepFilterNoiseFilterProcessorOptions, + ): void { + Object.assign(this, options); + this.setEnabled = mockSetEnabled; + this.setSuppressionLevel = mockSetSuppressionLevel; + this.destroy = mockDestroy; + }); + + Object.assign(mockDeepFilterNoiseFilterProcessor, { + mockSetEnabled, + mockSetSuppressionLevel, + mockDestroy, + }); return { __esModule: true, - DeepFilterNoiseFilterProcessor: vi - .fn() - .mockImplementation(DeepFilterNoiseFilterProcessor), - __setEnabledSpy: setEnabled, - __setSuppressionLevelSpy: setSuppressionLevel, - __destroySpy: destroy, + DeepFilterNoiseFilterProcessor: mockDeepFilterNoiseFilterProcessor, }; }); -const mockDeepFilterNoiseFilterProcessor = vi.mocked( - DeepFilterNoiseFilterProcessor, -); +const mockDeepFilterNoiseFilterProcessor = DeepFilterNoiseFilterProcessor as unknown as NoiseFilterProcessorMock; describe("NoiseSuppressionTransformer", () => { beforeEach((): void => { - mockSetEnabled.mockClear(); - mockSetSuppressionLevel.mockClear(); - mockDestroy.mockClear(); + mockDeepFilterNoiseFilterProcessor.mockSetEnabled.mockClear(); + mockDeepFilterNoiseFilterProcessor.mockSetSuppressionLevel.mockClear(); + mockDeepFilterNoiseFilterProcessor.mockDestroy.mockClear(); mockDeepFilterNoiseFilterProcessor.mockClear(); }); @@ -98,8 +100,8 @@ describe("NoiseSuppressionTransformer", () => { transformer.setSuppressionLevel(1.5); transformer.setSuppressionLevel(-0.2); - expect(mockSetSuppressionLevel).toHaveBeenNthCalledWith(1, 100); - expect(mockSetSuppressionLevel).toHaveBeenNthCalledWith(2, 0); + expect(mockDeepFilterNoiseFilterProcessor.mockSetSuppressionLevel).toHaveBeenNthCalledWith(1, 100); + expect(mockDeepFilterNoiseFilterProcessor.mockSetSuppressionLevel).toHaveBeenNthCalledWith(2, 0); }); it("forwards enabled state changes to the underlying processor", (): void => { @@ -109,8 +111,8 @@ describe("NoiseSuppressionTransformer", () => { transformer.setEnabled(false); transformer.setEnabled(true); - expect(mockSetEnabled).toHaveBeenNthCalledWith(1, false); - expect(mockSetEnabled).toHaveBeenNthCalledWith(2, true); + expect(mockDeepFilterNoiseFilterProcessor.mockSetEnabled).toHaveBeenNthCalledWith(1, false); + expect(mockDeepFilterNoiseFilterProcessor.mockSetEnabled).toHaveBeenNthCalledWith(2, true); }); it("destroys the processor and resets internal state", (): void => { @@ -119,7 +121,7 @@ describe("NoiseSuppressionTransformer", () => { transformer.destroy(); - expect(mockDestroy).toHaveBeenCalledTimes(1); + expect(mockDeepFilterNoiseFilterProcessor.mockDestroy).toHaveBeenCalledTimes(1); expect(transformer.getProcessor()).toBeNull(); }); }); diff --git a/src/livekit/audioTrackNoiseSuppressionSync.test.ts b/src/livekit/audioTrackNoiseSuppressionSync.test.ts index 1f638e2a..23b71771 100644 --- a/src/livekit/audioTrackNoiseSuppressionSync.test.ts +++ b/src/livekit/audioTrackNoiseSuppressionSync.test.ts @@ -7,11 +7,7 @@ Please see LICENSE in the repository root for full details. import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { BehaviorSubject } from "rxjs"; -import { - __setEnabledSpy as mockSetEnabled, - __setSuppressionLevelSpy as mockSetSuppressionLevel, - __destroySpy as mockDestroy, -} from "deepfilternet3-noise-filter"; +import { DeepFilterNoiseFilterProcessor } from "deepfilternet3-noise-filter"; import { ObservableScope } from "../state/ObservableScope"; import type { LocalAudioTrack } from "livekit-client"; @@ -31,6 +27,12 @@ type DeepFilterNoiseFilterProcessorContext = { destroy?: unknown; }; +type NoiseFilterProcessorMock = ReturnType & { + mockSetEnabled: ReturnType; + mockSetSuppressionLevel: ReturnType; + mockDestroy: ReturnType; +}; + const localStorageMock = { getItem: vi.fn(() => null), setItem: vi.fn(() => {}), @@ -45,31 +47,36 @@ Object.defineProperty(globalThis, "localStorage", { }); vi.mock("deepfilternet3-noise-filter", () => { - const setEnabled = vi.fn(); - const setSuppressionLevel = vi.fn(); - const destroy = vi.fn(); + const mockSetEnabled = vi.fn(); + const mockSetSuppressionLevel = vi.fn(); + const mockDestroy = vi.fn(); - function DeepFilterNoiseFilterProcessor( - this: DeepFilterNoiseFilterProcessorContext, - options: DeepFilterNoiseFilterProcessorOptions, - ): void { - Object.assign(this, options); - this.setEnabled = setEnabled; - this.setSuppressionLevel = setSuppressionLevel; - this.destroy = destroy; - } + const mockDeepFilterNoiseFilterProcessor = vi + .fn() + .mockImplementation(function DeepFilterNoiseFilterProcessor( + this: DeepFilterNoiseFilterProcessorContext, + options: DeepFilterNoiseFilterProcessorOptions, + ): void { + Object.assign(this, options); + this.setEnabled = mockSetEnabled; + this.setSuppressionLevel = mockSetSuppressionLevel; + this.destroy = mockDestroy; + }); + + Object.assign(mockDeepFilterNoiseFilterProcessor, { + mockSetEnabled, + mockSetSuppressionLevel, + mockDestroy, + }); return { __esModule: true, - DeepFilterNoiseFilterProcessor: vi - .fn() - .mockImplementation(DeepFilterNoiseFilterProcessor), - __setEnabledSpy: setEnabled, - __setSuppressionLevelSpy: setSuppressionLevel, - __destroySpy: destroy, + DeepFilterNoiseFilterProcessor: mockDeepFilterNoiseFilterProcessor, }; }); +const mockDeepFilterNoiseFilterProcessor = DeepFilterNoiseFilterProcessor as unknown as NoiseFilterProcessorMock; + let audioTrackNoiseSuppressionSync: AudioTrackNoiseSuppressionSync; let noiseSuppressionEnabled: Setting; let noiseSuppressionLevel: Setting; @@ -87,13 +94,13 @@ class MockLocalAudioTrack { describe("audioTrackNoiseSuppressionSync", () => { let scope: ObservableScope; - let audioTrack$: Behavior; + let audioTrack$: BehaviorSubject; let track: MockLocalAudioTrack; beforeEach(async (): Promise => { - mockSetEnabled.mockClear(); - mockSetSuppressionLevel.mockClear(); - mockDestroy.mockClear(); + mockDeepFilterNoiseFilterProcessor.mockSetEnabled.mockClear(); + mockDeepFilterNoiseFilterProcessor.mockSetSuppressionLevel.mockClear(); + mockDeepFilterNoiseFilterProcessor.mockDestroy.mockClear(); track = new MockLocalAudioTrack(); audioTrack$ = new BehaviorSubject( track as unknown as LocalAudioTrack, @@ -119,8 +126,8 @@ describe("audioTrackNoiseSuppressionSync", () => { expect(track.setProcessor).toHaveBeenCalledTimes(1); expect(track.getProcessor()).not.toBeUndefined(); - expect(mockSetEnabled).toHaveBeenCalledWith(false); - expect(mockSetSuppressionLevel).toHaveBeenCalledWith(75); + expect(mockDeepFilterNoiseFilterProcessor.mockSetEnabled).toHaveBeenCalledWith(false); + expect(mockDeepFilterNoiseFilterProcessor.mockSetSuppressionLevel).toHaveBeenCalledWith(75); }); it("reapplies processor when audio track becomes available", async (): Promise => { @@ -143,6 +150,6 @@ describe("audioTrackNoiseSuppressionSync", () => { scope.end(); await Promise.resolve(); - expect(mockDestroy).toHaveBeenCalledTimes(1); + expect(mockDeepFilterNoiseFilterProcessor.mockDestroy).toHaveBeenCalledTimes(1); }); }); diff --git a/src/settings/SettingsModal.test.tsx b/src/settings/SettingsModal.test.tsx index ebc1cd8c..31be7f60 100644 --- a/src/settings/SettingsModal.test.tsx +++ b/src/settings/SettingsModal.test.tsx @@ -6,6 +6,7 @@ Please see LICENSE in the repository root for full details. */ import { test, expect, vi } from "vitest"; +import "@testing-library/jest-dom/vitest"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { type ChangeEvent, type ReactNode, useState } from "react"; @@ -158,23 +159,23 @@ vi.mock("../MediaDevicesContext", () => ({ } => ({ audioInput: { selectedId: "mic1", - available$: new BehaviorSubject([ + available$: new BehaviorSubject([ { deviceId: "mic1", label: "Microphone 1" }, - ]), + ] as const), selected$: new BehaviorSubject({ id: "mic1", label: "Microphone 1" }), }, audioOutput: { selectedId: "speaker1", - available$: new BehaviorSubject([ + available$: new BehaviorSubject([ { deviceId: "speaker1", label: "Speaker 1" }, - ]), + ] as const), selected$: new BehaviorSubject({ id: "speaker1", label: "Speaker 1" }), }, videoInput: { selectedId: "cam1", - available$: new BehaviorSubject([ + available$: new BehaviorSubject([ { deviceId: "cam1", label: "Camera 1" }, - ]), + ] as const), selected$: new BehaviorSubject({ id: "cam1", label: "Camera 1" }), }, requestDeviceNames: vi.fn(), diff --git a/yarn.lock b/yarn.lock index ef1d4fc0..2e48059b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3171,6 +3171,63 @@ __metadata: languageName: node linkType: hard +"@jest/diff-sequences@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/diff-sequences@npm:30.3.0" + checksum: 10c0/8922c16a869b839b6c05f677023b3e5a9aa1610ad78a9c5ec8bd6654e35e8136ea1c7b60ad561910e2ad964bfdb0b09b0254ff8dcfacd4562095766f60c63d76 + languageName: node + linkType: hard + +"@jest/expect-utils@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/expect-utils@npm:30.3.0" + dependencies: + "@jest/get-type": "npm:30.1.0" + checksum: 10c0/4bb60fb434cb8ed325735bd39171b61621e110502ecc502089805d203ecb17b9fc5a400aeffb83b41fabcc819628a9c38c955f90a716d6aaff193d10926fc854 + languageName: node + linkType: hard + +"@jest/get-type@npm:30.1.0": + version: 30.1.0 + resolution: "@jest/get-type@npm:30.1.0" + checksum: 10c0/3e65fd5015f551c51ec68fca31bbd25b466be0e8ee8075d9610fa1c686ea1e70a942a0effc7b10f4ea9a338c24337e1ad97ff69d3ebacc4681b7e3e80d1b24ac + languageName: node + linkType: hard + +"@jest/pattern@npm:30.0.1": + version: 30.0.1 + resolution: "@jest/pattern@npm:30.0.1" + dependencies: + "@types/node": "npm:*" + jest-regex-util: "npm:30.0.1" + checksum: 10c0/32c5a7bfb6c591f004dac0ed36d645002ed168971e4c89bd915d1577031672870032594767557b855c5bc330aa1e39a2f54bf150d2ee88a7a0886e9cb65318bc + languageName: node + linkType: hard + +"@jest/schemas@npm:30.0.5": + version: 30.0.5 + resolution: "@jest/schemas@npm:30.0.5" + dependencies: + "@sinclair/typebox": "npm:^0.34.0" + checksum: 10c0/449dcd7ec5c6505e9ac3169d1143937e67044ae3e66a729ce4baf31812dfd30535f2b3b2934393c97cfdf5984ff581120e6b38f62b8560c8b5b7cc07f4175f65 + languageName: node + linkType: hard + +"@jest/types@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/types@npm:30.3.0" + dependencies: + "@jest/pattern": "npm:30.0.1" + "@jest/schemas": "npm:30.0.5" + "@types/istanbul-lib-coverage": "npm:^2.0.6" + "@types/istanbul-reports": "npm:^3.0.4" + "@types/node": "npm:*" + "@types/yargs": "npm:^17.0.33" + chalk: "npm:^4.1.2" + checksum: 10c0/c3e3f4de0b77a7ced345f47d3687b1094c1b6c1521529a7ca66a76f9a80194f79179a1dbc32d6761a5b67914a8f78be1e65d1408107efcb1f252c4a63b5ddd92 + languageName: node + linkType: hard + "@jridgewell/gen-mapping@npm:^0.3.12": version: 0.3.12 resolution: "@jridgewell/gen-mapping@npm:0.3.12" @@ -5453,6 +5510,13 @@ __metadata: languageName: node linkType: hard +"@sinclair/typebox@npm:^0.34.0": + version: 0.34.49 + resolution: "@sinclair/typebox@npm:0.34.49" + checksum: 10c0/16b7d87f039a49b68c10bb4cdcae2ce5242b2472228851fd6483731616aba4ef977690aa517b230a8d20da8185bb416eb34e326f30568b3963c1cf26b05d1ad8 + languageName: node + linkType: hard + "@sindresorhus/base62@npm:^1.0.0": version: 1.0.0 resolution: "@sindresorhus/base62@npm:1.0.0" @@ -5783,6 +5847,41 @@ __metadata: languageName: node linkType: hard +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.6": + version: 2.0.6 + resolution: "@types/istanbul-lib-coverage@npm:2.0.6" + checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7 + languageName: node + linkType: hard + +"@types/istanbul-lib-report@npm:*": + version: 3.0.3 + resolution: "@types/istanbul-lib-report@npm:3.0.3" + dependencies: + "@types/istanbul-lib-coverage": "npm:*" + checksum: 10c0/247e477bbc1a77248f3c6de5dadaae85ff86ac2d76c5fc6ab1776f54512a745ff2a5f791d22b942e3990ddbd40f3ef5289317c4fca5741bedfaa4f01df89051c + languageName: node + linkType: hard + +"@types/istanbul-reports@npm:^3.0.4": + version: 3.0.4 + resolution: "@types/istanbul-reports@npm:3.0.4" + dependencies: + "@types/istanbul-lib-report": "npm:*" + checksum: 10c0/1647fd402aced5b6edac87274af14ebd6b3a85447ef9ad11853a70fd92a98d35f81a5d3ea9fcb5dbb5834e800c6e35b64475e33fcae6bfa9acc70d61497c54ee + languageName: node + linkType: hard + +"@types/jest@npm:^30.0.0": + version: 30.0.0 + resolution: "@types/jest@npm:30.0.0" + dependencies: + expect: "npm:^30.0.0" + pretty-format: "npm:^30.0.0" + checksum: 10c0/20c6ce574154bc16f8dd6a97afacca4b8c4921a819496a3970382031c509ebe87a1b37b152a1b8475089b82d8ca951a9e95beb4b9bf78fbf579b1536f0b65969 + languageName: node + linkType: hard + "@types/jsdom@npm:^21.1.7": version: 21.1.7 resolution: "@types/jsdom@npm:21.1.7" @@ -5904,6 +6003,13 @@ __metadata: languageName: node linkType: hard +"@types/stack-utils@npm:^2.0.3": + version: 2.0.3 + resolution: "@types/stack-utils@npm:2.0.3" + checksum: 10c0/1f4658385ae936330581bcb8aa3a066df03867d90281cdf89cc356d404bd6579be0f11902304e1f775d92df22c6dd761d4451c804b0a4fba973e06211e9bd77c + languageName: node + linkType: hard + "@types/symlink-or-copy@npm:^1.2.0": version: 1.2.2 resolution: "@types/symlink-or-copy@npm:1.2.2" @@ -5941,6 +6047,15 @@ __metadata: languageName: node linkType: hard +"@types/yargs@npm:^17.0.33": + version: 17.0.35 + resolution: "@types/yargs@npm:17.0.35" + dependencies: + "@types/yargs-parser": "npm:*" + checksum: 10c0/609557826a6b85e73ccf587923f6429850d6dc70e420b455bab4601b670bfadf684b09ae288bccedab042c48ba65f1666133cf375814204b544009f57d6eef63 + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^8.31.0": version: 8.56.1 resolution: "@typescript-eslint/eslint-plugin@npm:8.56.1" @@ -6515,7 +6630,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^5.0.0": +"ansi-styles@npm:^5.0.0, ansi-styles@npm:^5.2.0": version: 5.2.0 resolution: "ansi-styles@npm:5.2.0" checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df @@ -7326,7 +7441,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:~4.1.0": +"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.2, chalk@npm:~4.1.0": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -7429,6 +7544,13 @@ __metadata: languageName: node linkType: hard +"ci-info@npm:^4.2.0": + version: 4.4.0 + resolution: "ci-info@npm:4.4.0" + checksum: 10c0/44156201545b8dde01aa8a09ee2fe9fc7a73b1bef9adbd4606c9f61c8caeeb73fb7a575c88b0443f7b4edb5ee45debaa59ed54ba5f99698339393ca01349eb3a + languageName: node + linkType: hard + "cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": version: 1.0.7 resolution: "cipher-base@npm:1.0.7" @@ -8321,6 +8443,7 @@ __metadata: "@testing-library/user-event": "npm:^14.5.1" "@types/content-type": "npm:^1.1.5" "@types/grecaptcha": "npm:^3.0.9" + "@types/jest": "npm:^30.0.0" "@types/jsdom": "npm:^21.1.7" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^24.0.0" @@ -8909,6 +9032,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507 + languageName: node + linkType: hard + "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -9380,6 +9510,20 @@ __metadata: languageName: node linkType: hard +"expect@npm:^30.0.0": + version: 30.3.0 + resolution: "expect@npm:30.3.0" + dependencies: + "@jest/expect-utils": "npm:30.3.0" + "@jest/get-type": "npm:30.1.0" + jest-matcher-utils: "npm:30.3.0" + jest-message-util: "npm:30.3.0" + jest-mock: "npm:30.3.0" + jest-util: "npm:30.3.0" + checksum: 10c0/a07a157a0c8b3f1e29bfe5ccbf03a3add2c69fe60d1af8a0980053bb6403d721d5f5e4616f1ea5833b747913f8c880c79ce4d98c23a71a2f0c27cf7273892576 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.2 resolution: "exponential-backoff@npm:3.1.2" @@ -10861,6 +11005,79 @@ __metadata: languageName: node linkType: hard +"jest-diff@npm:30.3.0": + version: 30.3.0 + resolution: "jest-diff@npm:30.3.0" + dependencies: + "@jest/diff-sequences": "npm:30.3.0" + "@jest/get-type": "npm:30.1.0" + chalk: "npm:^4.1.2" + pretty-format: "npm:30.3.0" + checksum: 10c0/573a2a1a155b95fbde547d8ee33a5375179a8d03d4586025478dac16d695e4614aef075c3afa57e0f3a96cea8f638fa68a55c1e625f6e86b4f5b9e5850311ffb + languageName: node + linkType: hard + +"jest-matcher-utils@npm:30.3.0": + version: 30.3.0 + resolution: "jest-matcher-utils@npm:30.3.0" + dependencies: + "@jest/get-type": "npm:30.1.0" + chalk: "npm:^4.1.2" + jest-diff: "npm:30.3.0" + pretty-format: "npm:30.3.0" + checksum: 10c0/4c5f4b6435964110e64c4b5b42e3553fffe303ecdd68021147a7bcc72914aec3a899867c50db22b250c72aded53e3f7a9f64d83c9dca2e65ce27f36d23c6ca78 + languageName: node + linkType: hard + +"jest-message-util@npm:30.3.0": + version: 30.3.0 + resolution: "jest-message-util@npm:30.3.0" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@jest/types": "npm:30.3.0" + "@types/stack-utils": "npm:^2.0.3" + chalk: "npm:^4.1.2" + graceful-fs: "npm:^4.2.11" + picomatch: "npm:^4.0.3" + pretty-format: "npm:30.3.0" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.6" + checksum: 10c0/6ce611caef76394872b23a111286b48e56f42655d14a5fbd0629d9b7437ed892e85ad96b15864bc22185c24ef670afb6665c57b9729458a36d50ffe8310f0926 + languageName: node + linkType: hard + +"jest-mock@npm:30.3.0": + version: 30.3.0 + resolution: "jest-mock@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + jest-util: "npm:30.3.0" + checksum: 10c0/9d95d550c6c998a85887c48ff5ee26de4bca18be91462ea8a8135d6023d591132465756f74981ca39b60f8708dfe38213a55bd4b619798a7b9438ca10d718099 + languageName: node + linkType: hard + +"jest-regex-util@npm:30.0.1": + version: 30.0.1 + resolution: "jest-regex-util@npm:30.0.1" + checksum: 10c0/f30c70524ebde2d1012afe5ffa5691d5d00f7d5ba9e43d588f6460ac6fe96f9e620f2f9b36a02d0d3e7e77bc8efb8b3450ae3b80ac53c8be5099e01bf54f6728 + languageName: node + linkType: hard + +"jest-util@npm:30.3.0": + version: 30.3.0 + resolution: "jest-util@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + ci-info: "npm:^4.2.0" + graceful-fs: "npm:^4.2.11" + picomatch: "npm:^4.0.3" + checksum: 10c0/eea6f39e52a8cb2b1a28bb315a90dc6a8e450fffed73bb5ef4489d02d86f7d91be600d83f1dcba22956b8ac5fefa8f1b250e636c8402d3e8b50a5eec8b5963b2 + languageName: node + linkType: hard + "jiti@npm:^2.6.0": version: 2.6.1 resolution: "jiti@npm:2.6.1" @@ -12816,6 +13033,17 @@ __metadata: languageName: node linkType: hard +"pretty-format@npm:30.3.0, pretty-format@npm:^30.0.0": + version: 30.3.0 + resolution: "pretty-format@npm:30.3.0" + dependencies: + "@jest/schemas": "npm:30.0.5" + ansi-styles: "npm:^5.2.0" + react-is: "npm:^18.3.1" + checksum: 10c0/719b27d70cd8b01013485054c5d094e1fe85e093b09ee73553e3b19302da3cf54fbd6a7ea9577d6471aeff8d372200e56979ffc4c831e2133520bd18060895fb + languageName: node + linkType: hard + "pretty-format@npm:^27.0.2": version: 27.5.1 resolution: "pretty-format@npm:27.5.1" @@ -13041,6 +13269,13 @@ __metadata: languageName: node linkType: hard +"react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 + languageName: node + linkType: hard + "react-refresh@npm:^0.17.0": version: 0.17.0 resolution: "react-refresh@npm:0.17.0" @@ -14199,6 +14434,15 @@ __metadata: languageName: node linkType: hard +"stack-utils@npm:^2.0.6": + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" + dependencies: + escape-string-regexp: "npm:^2.0.0" + checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a + languageName: node + linkType: hard + "stackback@npm:0.0.2": version: 0.0.2 resolution: "stackback@npm:0.0.2"