@notjustcoders/ioc-arise 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/analyser/project-analyzer.test.d.ts +2 -0
- package/dist/__tests__/analyser/project-analyzer.test.d.ts.map +1 -0
- package/dist/__tests__/analyser/project-analyzer.test.js +191 -0
- package/dist/__tests__/analyser/project-analyzer.test.js.map +1 -0
- package/dist/analyser/project-analyzer.d.ts +1 -0
- package/dist/analyser/project-analyzer.d.ts.map +1 -1
- package/dist/analyser/project-analyzer.js +29 -0
- package/dist/analyser/project-analyzer.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-analyzer.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/analyser/project-analyzer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const project_analyzer_1 = require("../../analyser/project-analyzer");
|
|
5
|
+
const class_analyzer_1 = require("../../analyser/class-analyzer");
|
|
6
|
+
const file_discovery_1 = require("../../analyser/file-discovery");
|
|
7
|
+
// Mock the dependencies
|
|
8
|
+
vitest_1.vi.mock('../../analyser/class-analyzer');
|
|
9
|
+
vitest_1.vi.mock('../../analyser/file-discovery');
|
|
10
|
+
const MockedClassAnalyzer = vitest_1.vi.mocked(class_analyzer_1.ClassAnalyzer);
|
|
11
|
+
const MockedFileDiscovery = vitest_1.vi.mocked(file_discovery_1.FileDiscovery);
|
|
12
|
+
(0, vitest_1.describe)('ProjectAnalyzer', () => {
|
|
13
|
+
let projectAnalyzer;
|
|
14
|
+
let mockClassAnalyzer;
|
|
15
|
+
let mockFileDiscovery;
|
|
16
|
+
let options;
|
|
17
|
+
(0, vitest_1.beforeEach)(() => {
|
|
18
|
+
vitest_1.vi.clearAllMocks();
|
|
19
|
+
options = {
|
|
20
|
+
sourceDir: '/test/src',
|
|
21
|
+
interfacePattern: 'I*',
|
|
22
|
+
excludePatterns: ['**/*.spec.ts']
|
|
23
|
+
};
|
|
24
|
+
mockFileDiscovery = {
|
|
25
|
+
findTypeScriptFiles: vitest_1.vi.fn()
|
|
26
|
+
};
|
|
27
|
+
mockClassAnalyzer = {
|
|
28
|
+
analyzeFile: vitest_1.vi.fn()
|
|
29
|
+
};
|
|
30
|
+
MockedFileDiscovery.mockImplementation(() => mockFileDiscovery);
|
|
31
|
+
MockedClassAnalyzer.mockImplementation(() => mockClassAnalyzer);
|
|
32
|
+
projectAnalyzer = new project_analyzer_1.ProjectAnalyzer(options);
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.describe)('analyzeProject', () => {
|
|
35
|
+
(0, vitest_1.it)('should analyze project successfully with unique interface implementations', async () => {
|
|
36
|
+
const mockFiles = ['/test/src/service1.ts', '/test/src/service2.ts'];
|
|
37
|
+
const mockClasses = [
|
|
38
|
+
{
|
|
39
|
+
name: 'UserService',
|
|
40
|
+
filePath: '/test/src/service1.ts',
|
|
41
|
+
dependencies: ['UserRepository'],
|
|
42
|
+
constructorParams: [],
|
|
43
|
+
interfaceName: 'IUserService',
|
|
44
|
+
importPath: './service1',
|
|
45
|
+
scope: 'singleton'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'UserRepository',
|
|
49
|
+
filePath: '/test/src/service2.ts',
|
|
50
|
+
dependencies: [],
|
|
51
|
+
constructorParams: [],
|
|
52
|
+
interfaceName: 'IUserRepository',
|
|
53
|
+
importPath: './service2',
|
|
54
|
+
scope: 'singleton'
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
mockFileDiscovery.findTypeScriptFiles.mockResolvedValue(mockFiles);
|
|
58
|
+
mockClassAnalyzer.analyzeFile
|
|
59
|
+
.mockResolvedValueOnce([mockClasses[0]])
|
|
60
|
+
.mockResolvedValueOnce([mockClasses[1]]);
|
|
61
|
+
const result = await projectAnalyzer.analyzeProject();
|
|
62
|
+
(0, vitest_1.expect)(result).toEqual(mockClasses);
|
|
63
|
+
(0, vitest_1.expect)(mockFileDiscovery.findTypeScriptFiles).toHaveBeenCalledOnce();
|
|
64
|
+
(0, vitest_1.expect)(mockClassAnalyzer.analyzeFile).toHaveBeenCalledTimes(2);
|
|
65
|
+
});
|
|
66
|
+
(0, vitest_1.it)('should throw error when multiple classes implement the same interface', async () => {
|
|
67
|
+
const mockFiles = ['/test/src/service1.ts', '/test/src/service2.ts'];
|
|
68
|
+
const mockClasses = [
|
|
69
|
+
{
|
|
70
|
+
name: 'UserService',
|
|
71
|
+
filePath: '/test/src/service1.ts',
|
|
72
|
+
dependencies: [],
|
|
73
|
+
constructorParams: [],
|
|
74
|
+
interfaceName: 'IUserService',
|
|
75
|
+
importPath: './service1',
|
|
76
|
+
scope: 'singleton'
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'AnotherUserService',
|
|
80
|
+
filePath: '/test/src/service2.ts',
|
|
81
|
+
dependencies: [],
|
|
82
|
+
constructorParams: [],
|
|
83
|
+
interfaceName: 'IUserService', // Same interface as above
|
|
84
|
+
importPath: './service2',
|
|
85
|
+
scope: 'singleton'
|
|
86
|
+
}
|
|
87
|
+
];
|
|
88
|
+
mockFileDiscovery.findTypeScriptFiles.mockResolvedValue(mockFiles);
|
|
89
|
+
mockClassAnalyzer.analyzeFile
|
|
90
|
+
.mockResolvedValueOnce([mockClasses[0]])
|
|
91
|
+
.mockResolvedValueOnce([mockClasses[1]]);
|
|
92
|
+
// Mock console.error to avoid output during tests
|
|
93
|
+
const consoleSpy = vitest_1.vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
94
|
+
await (0, vitest_1.expect)(projectAnalyzer.analyzeProject()).rejects.toThrow('Multiple classes implement the same interface(s): IUserService. Each interface should only be implemented by one class for proper dependency injection.');
|
|
95
|
+
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith("Error: Interface 'IUserService' is implemented by multiple classes:");
|
|
96
|
+
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(' - UserService (/test/src/service1.ts)');
|
|
97
|
+
(0, vitest_1.expect)(consoleSpy).toHaveBeenCalledWith(' - AnotherUserService (/test/src/service2.ts)');
|
|
98
|
+
consoleSpy.mockRestore();
|
|
99
|
+
});
|
|
100
|
+
(0, vitest_1.it)('should throw error when multiple interfaces have duplicate implementations', async () => {
|
|
101
|
+
const mockFiles = ['/test/src/service1.ts', '/test/src/service2.ts', '/test/src/service3.ts'];
|
|
102
|
+
const mockClasses = [
|
|
103
|
+
{
|
|
104
|
+
name: 'UserService1',
|
|
105
|
+
filePath: '/test/src/service1.ts',
|
|
106
|
+
dependencies: [],
|
|
107
|
+
constructorParams: [],
|
|
108
|
+
interfaceName: 'IUserService',
|
|
109
|
+
importPath: './service1',
|
|
110
|
+
scope: 'singleton'
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'UserService2',
|
|
114
|
+
filePath: '/test/src/service2.ts',
|
|
115
|
+
dependencies: [],
|
|
116
|
+
constructorParams: [],
|
|
117
|
+
interfaceName: 'IUserService', // Duplicate
|
|
118
|
+
importPath: './service2',
|
|
119
|
+
scope: 'singleton'
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'OrderService1',
|
|
123
|
+
filePath: '/test/src/service3.ts',
|
|
124
|
+
dependencies: [],
|
|
125
|
+
constructorParams: [],
|
|
126
|
+
interfaceName: 'IOrderService',
|
|
127
|
+
importPath: './service3',
|
|
128
|
+
scope: 'singleton'
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'OrderService2',
|
|
132
|
+
filePath: '/test/src/service3.ts',
|
|
133
|
+
dependencies: [],
|
|
134
|
+
constructorParams: [],
|
|
135
|
+
interfaceName: 'IOrderService', // Duplicate
|
|
136
|
+
importPath: './service3',
|
|
137
|
+
scope: 'singleton'
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
mockFileDiscovery.findTypeScriptFiles.mockResolvedValue(mockFiles);
|
|
141
|
+
mockClassAnalyzer.analyzeFile
|
|
142
|
+
.mockResolvedValueOnce([mockClasses[0]])
|
|
143
|
+
.mockResolvedValueOnce([mockClasses[1]])
|
|
144
|
+
.mockResolvedValueOnce([mockClasses[2], mockClasses[3]]);
|
|
145
|
+
// Mock console.error to avoid output during tests
|
|
146
|
+
const consoleSpy = vitest_1.vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
147
|
+
await (0, vitest_1.expect)(projectAnalyzer.analyzeProject()).rejects.toThrow('Multiple classes implement the same interface(s): IUserService, IOrderService. Each interface should only be implemented by one class for proper dependency injection.');
|
|
148
|
+
consoleSpy.mockRestore();
|
|
149
|
+
});
|
|
150
|
+
(0, vitest_1.it)('should filter out classes that are not used as dependencies and have no interfaces', async () => {
|
|
151
|
+
const mockFiles = ['/test/src/service1.ts'];
|
|
152
|
+
const mockClasses = [
|
|
153
|
+
{
|
|
154
|
+
name: 'UserService',
|
|
155
|
+
filePath: '/test/src/service1.ts',
|
|
156
|
+
dependencies: ['UnusedClass'],
|
|
157
|
+
constructorParams: [],
|
|
158
|
+
interfaceName: 'IUserService',
|
|
159
|
+
importPath: './service1',
|
|
160
|
+
scope: 'singleton'
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: 'UnusedClass',
|
|
164
|
+
filePath: '/test/src/service1.ts',
|
|
165
|
+
dependencies: [],
|
|
166
|
+
constructorParams: [],
|
|
167
|
+
interfaceName: undefined, // No interface
|
|
168
|
+
importPath: './service1',
|
|
169
|
+
scope: 'singleton'
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'AnotherUnusedClass',
|
|
173
|
+
filePath: '/test/src/service1.ts',
|
|
174
|
+
dependencies: [],
|
|
175
|
+
constructorParams: [],
|
|
176
|
+
interfaceName: undefined, // No interface and not used as dependency
|
|
177
|
+
importPath: './service1',
|
|
178
|
+
scope: 'singleton'
|
|
179
|
+
}
|
|
180
|
+
];
|
|
181
|
+
mockFileDiscovery.findTypeScriptFiles.mockResolvedValue(mockFiles);
|
|
182
|
+
mockClassAnalyzer.analyzeFile.mockResolvedValueOnce(mockClasses);
|
|
183
|
+
const result = await projectAnalyzer.analyzeProject();
|
|
184
|
+
// Should include UserService (has interface) and UnusedClass (used as dependency)
|
|
185
|
+
// Should exclude AnotherUnusedClass (no interface and not used as dependency)
|
|
186
|
+
(0, vitest_1.expect)(result).toHaveLength(2);
|
|
187
|
+
(0, vitest_1.expect)(result.map(c => c.name)).toEqual(['UserService', 'UnusedClass']);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
//# sourceMappingURL=project-analyzer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-analyzer.test.js","sourceRoot":"","sources":["../../../src/__tests__/analyser/project-analyzer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyser/project-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKtD,qBAAa,eAAe;IAC1B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,EAAE,eAAe;IAK9B,cAAc,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"project-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyser/project-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKtD,qBAAa,eAAe;IAC1B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,EAAE,eAAe;IAK9B,cAAc,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAmB5C,OAAO,CAAC,8BAA8B;IAwBtC,OAAO,CAAC,sCAAsC;CAgC/C"}
|
|
@@ -15,6 +15,8 @@ class ProjectAnalyzer {
|
|
|
15
15
|
const allClasses = fileClassesArrays.flat();
|
|
16
16
|
// Filter classes to only include those that are used as dependencies
|
|
17
17
|
const filteredClasses = this.filterClassesByDependencyUsage(allClasses);
|
|
18
|
+
// Validate that no interface is implemented by multiple classes
|
|
19
|
+
this.validateUniqueInterfaceImplementations(filteredClasses);
|
|
18
20
|
return filteredClasses;
|
|
19
21
|
}
|
|
20
22
|
filterClassesByDependencyUsage(classes) {
|
|
@@ -37,6 +39,33 @@ class ProjectAnalyzer {
|
|
|
37
39
|
return allDependencies.has(classInfo.name);
|
|
38
40
|
});
|
|
39
41
|
}
|
|
42
|
+
validateUniqueInterfaceImplementations(classes) {
|
|
43
|
+
const interfaceToClassMap = new Map();
|
|
44
|
+
// Group classes by their interface names
|
|
45
|
+
for (const classInfo of classes) {
|
|
46
|
+
if (classInfo.interfaceName) {
|
|
47
|
+
if (!interfaceToClassMap.has(classInfo.interfaceName)) {
|
|
48
|
+
interfaceToClassMap.set(classInfo.interfaceName, []);
|
|
49
|
+
}
|
|
50
|
+
interfaceToClassMap.get(classInfo.interfaceName).push(classInfo);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Check for duplicate implementations
|
|
54
|
+
const duplicateInterfaces = [];
|
|
55
|
+
for (const [interfaceName, implementingClasses] of interfaceToClassMap) {
|
|
56
|
+
if (implementingClasses.length > 1) {
|
|
57
|
+
duplicateInterfaces.push(interfaceName);
|
|
58
|
+
console.error(`Error: Interface '${interfaceName}' is implemented by multiple classes:`);
|
|
59
|
+
for (const classInfo of implementingClasses) {
|
|
60
|
+
console.error(` - ${classInfo.name} (${classInfo.filePath})`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (duplicateInterfaces.length > 0) {
|
|
65
|
+
throw new Error(`Multiple classes implement the same interface(s): ${duplicateInterfaces.join(', ')}. ` +
|
|
66
|
+
'Each interface should only be implemented by one class for proper dependency injection.');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
40
69
|
}
|
|
41
70
|
exports.ProjectAnalyzer = ProjectAnalyzer;
|
|
42
71
|
//# sourceMappingURL=project-analyzer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-analyzer.js","sourceRoot":"","sources":["../../src/analyser/project-analyzer.ts"],"names":[],"mappings":";;;AACA,qDAAiD;AACjD,qDAAiD;AAGjD,MAAa,eAAe;IAI1B,YAAY,OAAwB;QAClC,IAAI,CAAC,aAAa,GAAG,IAAI,8BAAa,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QACnF,IAAI,CAAC,aAAa,GAAG,IAAI,8BAAa,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtF,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,mBAAmB,EAAE,CAAC;QAE/D,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAClD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,CACzC,CAAC;QAEF,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClE,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC;QAE5C,qEAAqE;QACrE,MAAM,eAAe,GAAG,IAAI,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC;QAExE,OAAO,eAAe,CAAC;IACzB,CAAC;IAEO,8BAA8B,CAAC,OAAoB;QACzD,4CAA4C;QAC5C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;QAE1C,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;YAChC,KAAK,MAAM,UAAU,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;gBAChD,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,mFAAmF;QACnF,+EAA+E;QAC/E,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;YAChC,yCAAyC;YACzC,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;gBAC5B,OAAO,IAAI,CAAC;YACd,CAAC;YAED,gFAAgF;YAChF,OAAO,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"project-analyzer.js","sourceRoot":"","sources":["../../src/analyser/project-analyzer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED