@notjustcoders/ioc-arise
Version:
Arise type-safe IoC containers from your code. Zero overhead, zero coupling.
98 lines • 4.02 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockClassResolver = void 0;
const minimatch_1 = require("minimatch");
/**
* Utility class for resolving mock classes based on configuration
*/
class MockClassResolver {
constructor(mockConfig, availableClasses) {
this.mockConfig = mockConfig;
this.availableClasses = availableClasses;
}
/**
* Resolves a mock class for the given target class name
* @param targetClassName - The name of the class to find a mock for
* @returns The mock class info if found, undefined otherwise
*/
resolveMockClass(targetClassName) {
// First check explicit mocks
if (this.mockConfig.explicitMocks) {
const explicitMock = this.mockConfig.explicitMocks[targetClassName];
if (explicitMock) {
const mockClass = this.availableClasses.find(cls => cls.name === explicitMock);
if (mockClass) {
return mockClass;
}
}
}
// Then check glob patterns
if (this.mockConfig.mockClassGlobs && this.mockConfig.mockClassGlobs.length > 0) {
for (const mockClass of this.availableClasses) {
if (this.isMatchingGlobPattern(mockClass.name) && this.isMockForTarget(mockClass.name, targetClassName)) {
return mockClass;
}
}
}
return undefined;
}
/**
* Checks if a class name matches any of the configured glob patterns
* @param className - The class name to check
* @returns True if the class name matches any glob pattern
*/
isMatchingGlobPattern(className) {
if (!this.mockConfig.mockClassGlobs) {
return false;
}
return this.mockConfig.mockClassGlobs.some(pattern => (0, minimatch_1.minimatch)(className, pattern, { nocase: true }));
}
/**
* Determines if a mock class is intended for a specific target class
* Uses fuzzy matching to handle various naming conventions
* @param mockClassName - The name of the mock class
* @param targetClassName - The name of the target class
* @returns True if the mock class is intended for the target class
*/
isMockForTarget(mockClassName, targetClassName) {
const mockLower = mockClassName.toLowerCase();
const targetLower = targetClassName.toLowerCase();
// Remove common mock prefixes/suffixes for comparison
const cleanMockName = mockLower
.replace(/^mock/, '')
.replace(/mock$/, '')
.replace(/^fake/, '')
.replace(/fake$/, '')
.replace(/^stub/, '')
.replace(/stub$/, '');
// Check if the cleaned mock name contains the target name
return cleanMockName.includes(targetLower) || targetLower.includes(cleanMockName);
}
/**
* Gets all available mock classes based on the configuration
* @returns Array of mock class info objects
*/
getAllMockClasses() {
const mockClasses = [];
// Add explicit mocks
if (this.mockConfig.explicitMocks) {
Object.values(this.mockConfig.explicitMocks).forEach(mockClassName => {
const mockClass = this.availableClasses.find(cls => cls.name === mockClassName);
if (mockClass && !mockClasses.includes(mockClass)) {
mockClasses.push(mockClass);
}
});
}
// Add glob pattern matches
if (this.mockConfig.mockClassGlobs && this.mockConfig.mockClassGlobs.length > 0) {
this.availableClasses.forEach(cls => {
if (this.isMatchingGlobPattern(cls.name) && !mockClasses.includes(cls)) {
mockClasses.push(cls);
}
});
}
return mockClasses;
}
}
exports.MockClassResolver = MockClassResolver;
//# sourceMappingURL=mock-class-resolver.js.map