syntropylog
Version:
An instance manager with observability for Node.js applications
124 lines (118 loc) ⢠4.39 kB
JavaScript
/**
* MockSerializerRegistry - Framework Agnostic Mock
*
* This mock provides a testing-agnostic version of SerializerRegistry
* that can be used with both Vitest and Jest without conflicts.
*/
/**
* Creates a simple agnostic mock function without spy capabilities
*/
function createAgnosticMockFn(implementation) {
const mockFn = (...args) => {
if (implementation) {
return implementation(...args);
}
return undefined;
};
// Basic mock properties
mockFn.mockClear = () => { };
mockFn.mockReset = () => { };
mockFn.mockImplementation = (impl) => {
return createAgnosticMockFn(impl);
};
mockFn.mockReturnValue = (value) => {
return createAgnosticMockFn(() => value);
};
mockFn.mockResolvedValue = (value) => {
return createAgnosticMockFn(() => Promise.resolve(value));
};
mockFn.mockRejectedValue = (value) => {
return createAgnosticMockFn(() => Promise.reject(value));
};
return mockFn;
}
export class MockSerializerRegistry {
// Internal state to track configured serializers
serializers = new Map();
errorKeys = new Set();
timeoutMs = null;
spyFn = null;
// Core methods - will be initialized in constructor
process;
setSerializer;
setError;
setTimeout;
reset;
constructor(spyFn) {
this.spyFn = spyFn || null;
// Initialize mocks after spyFn is set
this.process = this.createMock().mockImplementation(async (meta, logger) => {
// Check for timeout first
if (this.timeoutMs !== null) {
await new Promise((resolve) => setTimeout(resolve, this.timeoutMs + 10));
throw new Error(`Mock serializer timed out after ${this.timeoutMs}ms.`);
}
const processedMeta = { ...meta };
// Process each field with its configured serializer
for (const [key, value] of Object.entries(processedMeta)) {
// Check for error simulation
if (this.errorKeys.has(key)) {
throw new Error(`Mock error for key '${key}'`);
}
// Check for serializer
const serializer = this.serializers.get(key);
if (serializer) {
try {
processedMeta[key] = serializer(value);
}
catch (error) {
logger.warn(`Mock serializer for key "${key}" failed.`, {
error: error instanceof Error ? error.message : String(error),
});
processedMeta[key] =
`[MOCK_SERIALIZER_ERROR: Failed to process key '${key}']`;
}
}
}
return processedMeta;
});
this.setSerializer = this.createMock().mockImplementation((key, serializer) => {
this.serializers.set(key, serializer);
});
this.setError = this.createMock().mockImplementation((key, error) => {
this.errorKeys.add(key);
});
this.setTimeout = this.createMock().mockImplementation((timeoutMs) => {
this.timeoutMs = timeoutMs;
});
this.reset = this.createMock().mockImplementation(() => {
this.serializers.clear();
this.errorKeys.clear();
this.timeoutMs = null;
this.process.mockReset();
this.process.mockImplementation(async (meta, logger) => {
return { ...meta };
});
});
}
createMock(implementation) {
if (!this.spyFn) {
throw new Error(`
šØ SPY FUNCTION NOT INJECTED! š”
To use spy functions like toHaveBeenCalled(), toHaveBeenCalledWith(), etc.
YOU MUST inject your spy function in the constructor:
// For Vitest:
const mockSerializer = new MockSerializerRegistry(vi.fn);
// For Jest:
const mockSerializer = new MockSerializerRegistry(jest.fn);
// For Jasmine:
const mockSerializer = new MockSerializerRegistry(jasmine.createSpy);
// Without spy (basic functionality only):
const mockSerializer = new MockSerializerRegistry();
DON'T FORGET AGAIN! š¤
`);
}
return this.spyFn(implementation);
}
}
//# sourceMappingURL=MockSerializerRegistry.js.map