fix(testing): preserve mock restore export identity
This commit is contained in:
@@ -4,8 +4,9 @@ import { describe, expect, mock, test } from "bun:test"
|
|||||||
import { installModuleMockLifecycle } from "./module-mock-lifecycle"
|
import { installModuleMockLifecycle } from "./module-mock-lifecycle"
|
||||||
|
|
||||||
describe("installModuleMockLifecycle", () => {
|
describe("installModuleMockLifecycle", () => {
|
||||||
test("restores the original module exports on mock.restore", () => {
|
test("restores the original module export object instead of a cloned snapshot", () => {
|
||||||
// given
|
// given
|
||||||
|
const originalExports = { named: "original" }
|
||||||
const moduleCalls: Array<{ specifier: string; value: Record<string, unknown> }> = []
|
const moduleCalls: Array<{ specifier: string; value: Record<string, unknown> }> = []
|
||||||
const mockApi = {
|
const mockApi = {
|
||||||
module: (specifier: string, factory: () => Record<string, unknown>) => {
|
module: (specifier: string, factory: () => Record<string, unknown>) => {
|
||||||
@@ -17,7 +18,7 @@ describe("installModuleMockLifecycle", () => {
|
|||||||
installModuleMockLifecycle(mockApi, {
|
installModuleMockLifecycle(mockApi, {
|
||||||
getCallerUrl: () => "file:///repo/tests/example.test.ts",
|
getCallerUrl: () => "file:///repo/tests/example.test.ts",
|
||||||
resolveSpecifier: (specifier) => `resolved:${specifier}`,
|
resolveSpecifier: (specifier) => `resolved:${specifier}`,
|
||||||
loadOriginalModule: () => ({ ok: true, value: { named: "original" } }),
|
loadOriginalModule: () => ({ ok: true, value: originalExports }),
|
||||||
})
|
})
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@@ -25,13 +26,12 @@ describe("installModuleMockLifecycle", () => {
|
|||||||
mockApi.restore()
|
mockApi.restore()
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(moduleCalls).toEqual([
|
expect(moduleCalls.map((call) => call.specifier)).toEqual(["./dependency", "resolved:./dependency"])
|
||||||
{ specifier: "./dependency", value: { named: "mocked" } },
|
const restoreCall = moduleCalls.find((call) => call.specifier === "resolved:./dependency")
|
||||||
{ specifier: "resolved:./dependency", value: { named: "original" } },
|
expect(restoreCall?.value).toBe(originalExports)
|
||||||
])
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test("restores original exports after the delegate restore runs", () => {
|
test("clears tracked snapshots after the delegate restore runs", () => {
|
||||||
// given
|
// given
|
||||||
const events: string[] = []
|
const events: string[] = []
|
||||||
const mockApi = {
|
const mockApi = {
|
||||||
@@ -43,7 +43,7 @@ describe("installModuleMockLifecycle", () => {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
installModuleMockLifecycle(mockApi, {
|
const { restoreModuleMocks } = installModuleMockLifecycle(mockApi, {
|
||||||
getCallerUrl: () => "file:///repo/tests/example.test.ts",
|
getCallerUrl: () => "file:///repo/tests/example.test.ts",
|
||||||
resolveSpecifier: (specifier) => `resolved:${specifier}`,
|
resolveSpecifier: (specifier) => `resolved:${specifier}`,
|
||||||
loadOriginalModule: () => ({ ok: true, value: { named: "original" } }),
|
loadOriginalModule: () => ({ ok: true, value: { named: "original" } }),
|
||||||
@@ -52,6 +52,7 @@ describe("installModuleMockLifecycle", () => {
|
|||||||
// when
|
// when
|
||||||
mockApi.module("./dependency", () => ({ named: "mocked" }))
|
mockApi.module("./dependency", () => ({ named: "mocked" }))
|
||||||
mockApi.restore()
|
mockApi.restore()
|
||||||
|
restoreModuleMocks()
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(events).toEqual([
|
expect(events).toEqual([
|
||||||
@@ -65,7 +66,7 @@ describe("installModuleMockLifecycle", () => {
|
|||||||
// given
|
// given
|
||||||
let loadCount = 0
|
let loadCount = 0
|
||||||
const mockApi = {
|
const mockApi = {
|
||||||
module: mock(() => {}),
|
module: mock((_specifier: string, _factory: () => Record<string, unknown>) => {}),
|
||||||
restore: mock(() => {}),
|
restore: mock(() => {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ function toError(error: unknown): Error {
|
|||||||
return new Error(String(error))
|
return new Error(String(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneModuleExports(moduleValue: unknown): Record<string, unknown> {
|
function isModuleExports(moduleValue: unknown): moduleValue is Record<string, unknown> {
|
||||||
|
return moduleValue !== null && typeof moduleValue === "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRestoreExports(moduleValue: unknown): Record<string, unknown> {
|
||||||
if (typeof moduleValue === "function") {
|
if (typeof moduleValue === "function") {
|
||||||
const functionExports = Object.assign({}, moduleValue)
|
const functionExports = Object.assign({}, moduleValue)
|
||||||
return {
|
return {
|
||||||
@@ -40,8 +44,8 @@ function cloneModuleExports(moduleValue: unknown): Record<string, unknown> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moduleValue && typeof moduleValue === "object") {
|
if (isModuleExports(moduleValue)) {
|
||||||
return { ...(moduleValue as Record<string, unknown>) }
|
return moduleValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return { default: moduleValue }
|
return { default: moduleValue }
|
||||||
@@ -123,10 +127,10 @@ export function installModuleMockLifecycle(
|
|||||||
const originalModule = loadOriginalModule(specifier, callerUrl)
|
const originalModule = loadOriginalModule(specifier, callerUrl)
|
||||||
|
|
||||||
if (originalModule.ok) {
|
if (originalModule.ok) {
|
||||||
const clonedExports = cloneModuleExports(originalModule.value)
|
const restoreExports = createRestoreExports(originalModule.value)
|
||||||
snapshots.set(restoreSpecifier, {
|
snapshots.set(restoreSpecifier, {
|
||||||
restoreSpecifier,
|
restoreSpecifier,
|
||||||
restoreFactory: () => ({ ...clonedExports }),
|
restoreFactory: () => restoreExports,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user