@adaas/a-utils 0.1.15 → 0.1.17
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/LICENSE +10 -19
- package/README.md +74 -18
- package/dist/index.d.mts +270 -58
- package/dist/index.d.ts +270 -58
- package/dist/index.js +323 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +324 -103
- package/dist/index.mjs.map +1 -1
- package/examples/{channel-examples.ts → A-Channel-examples.ts} +2 -2
- package/examples/{command-examples.ts → A-Command-examples.ts} +47 -45
- package/examples/A-Logger-examples.ts +308 -0
- package/examples/config.ts +1 -1
- package/package.json +45 -34
- package/src/lib/A-Command/A-Command.constants.ts +49 -13
- package/src/lib/A-Command/A-Command.entity.ts +21 -15
- package/src/lib/A-Command/A-Command.types.ts +2 -35
- package/src/lib/A-Config/A-Config.container.ts +3 -3
- package/src/lib/A-Config/components/ConfigReader.component.ts +4 -6
- package/src/lib/A-Logger/A-Logger.component.ts +369 -130
- package/src/lib/A-Logger/A-Logger.constants.ts +69 -0
- package/src/lib/A-Logger/A-Logger.env.ts +27 -0
- package/src/lib/A-Logger/A-Logger.types.ts +3 -0
- package/src/lib/A-Logger/README.md +383 -0
- package/src/lib/A-Manifest/A-Manifest.types.ts +1 -2
- package/src/lib/A-Memory/A-Memory.context.ts +1 -1
- package/tests/A-Command.test.ts +26 -26
- package/tests/A-Logger.test.ts +520 -0
- package/tests/A-Memory.test.ts +5 -5
- package/tests/A-Polyfill.test.ts +3 -2
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A-Logger Component Tests
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive test suite for the A_Logger component covering:
|
|
5
|
+
* - Basic logging functionality
|
|
6
|
+
* - Scope formatting and alignment
|
|
7
|
+
* - Error handling and formatting
|
|
8
|
+
* - Object and data type logging
|
|
9
|
+
* - Color support
|
|
10
|
+
* - Log level filtering
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { A_Scope, A_Error } from "@adaas/a-concept";
|
|
14
|
+
import { A_Logger } from "../src/lib/A-Logger/A-Logger.component";
|
|
15
|
+
import { A_Config } from "../src/lib/A-Config/A-Config.context";
|
|
16
|
+
import { A_LOGGER_COLORS } from "../src/lib/A-Logger/A-Logger.constants";
|
|
17
|
+
|
|
18
|
+
// Mock console methods for testing
|
|
19
|
+
const originalConsoleLog = console.log;
|
|
20
|
+
let capturedLogs: string[] = [];
|
|
21
|
+
|
|
22
|
+
function mockConsole() {
|
|
23
|
+
console.log = (...args: any[]) => {
|
|
24
|
+
capturedLogs.push(args.join(' '));
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function restoreConsole() {
|
|
29
|
+
console.log = originalConsoleLog;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getCapturedLogs(): string[] {
|
|
33
|
+
return capturedLogs;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function clearCapturedLogs() {
|
|
37
|
+
capturedLogs = [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// =============================================
|
|
41
|
+
// Test Suite Setup
|
|
42
|
+
// =============================================
|
|
43
|
+
|
|
44
|
+
describe('A_Logger Component', () => {
|
|
45
|
+
let scope: A_Scope;
|
|
46
|
+
let logger: A_Logger;
|
|
47
|
+
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
scope = new A_Scope({ name: 'TestScope' });
|
|
50
|
+
logger = new A_Logger(scope);
|
|
51
|
+
clearCapturedLogs();
|
|
52
|
+
mockConsole();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
restoreConsole();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// =============================================
|
|
60
|
+
// Basic Functionality Tests
|
|
61
|
+
// =============================================
|
|
62
|
+
|
|
63
|
+
describe('Basic Logging', () => {
|
|
64
|
+
test('should log simple string messages', () => {
|
|
65
|
+
logger.log('Test message');
|
|
66
|
+
|
|
67
|
+
const logs = getCapturedLogs();
|
|
68
|
+
expect(logs).toHaveLength(1);
|
|
69
|
+
expect(logs[0]).toContain('TestScope');
|
|
70
|
+
expect(logs[0]).toContain('Test message');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('should log with custom colors', () => {
|
|
74
|
+
logger.log('green', 'Success message');
|
|
75
|
+
|
|
76
|
+
const logs = getCapturedLogs();
|
|
77
|
+
expect(logs[0]).toContain('Success message');
|
|
78
|
+
// Colors might not be shown in test environment, just verify message content
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('should log warning messages with yellow color', () => {
|
|
82
|
+
logger.warning('Warning message');
|
|
83
|
+
|
|
84
|
+
const logs = getCapturedLogs();
|
|
85
|
+
expect(logs[0]).toContain('Warning message');
|
|
86
|
+
// Colors might not be shown in test environment, just verify message content
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('should log error messages with red color', () => {
|
|
90
|
+
logger.error('Error message');
|
|
91
|
+
|
|
92
|
+
const logs = getCapturedLogs();
|
|
93
|
+
expect(logs[0]).toContain('Error message');
|
|
94
|
+
// Colors might not be shown in test environment, just verify message content
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// =============================================
|
|
99
|
+
// Scope Formatting Tests
|
|
100
|
+
// =============================================
|
|
101
|
+
|
|
102
|
+
describe('Scope Formatting', () => {
|
|
103
|
+
test('should pad short scope names to standard length', () => {
|
|
104
|
+
const shortScope = new A_Scope({ name: 'API' });
|
|
105
|
+
const shortLogger = new A_Logger(shortScope);
|
|
106
|
+
|
|
107
|
+
shortLogger.log('Test message');
|
|
108
|
+
|
|
109
|
+
const logs = getCapturedLogs();
|
|
110
|
+
expect(logs[0]).toContain('API'); // Should contain the scope name
|
|
111
|
+
// The formatting should ensure consistent alignment
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('should handle long scope names', () => {
|
|
115
|
+
const longScope = new A_Scope({ name: 'VeryLongServiceNameThatExceedsStandardLength' });
|
|
116
|
+
const longLogger = new A_Logger(longScope);
|
|
117
|
+
|
|
118
|
+
longLogger.log('Test message');
|
|
119
|
+
|
|
120
|
+
const logs = getCapturedLogs();
|
|
121
|
+
expect(logs[0]).toContain('VeryLongServiceNameThatExceedsStandardLength');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('should maintain consistent alignment across different scope lengths', () => {
|
|
125
|
+
const scopes = [
|
|
126
|
+
new A_Scope({ name: 'A' }),
|
|
127
|
+
new A_Scope({ name: 'MediumLengthScope' }),
|
|
128
|
+
new A_Scope({ name: 'VeryVeryLongScopeName' })
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
scopes.forEach(testScope => {
|
|
132
|
+
const testLogger = new A_Logger(testScope);
|
|
133
|
+
testLogger.log('Alignment test');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const logs = getCapturedLogs();
|
|
137
|
+
expect(logs).toHaveLength(3);
|
|
138
|
+
|
|
139
|
+
// All logs should have similar structure for alignment
|
|
140
|
+
logs.forEach(log => {
|
|
141
|
+
expect(log).toContain('Alignment test');
|
|
142
|
+
expect(log).toMatch(/\[.*\] \|.*\|/); // Pattern: [scope] |time|
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// =============================================
|
|
148
|
+
// Object Logging Tests
|
|
149
|
+
// =============================================
|
|
150
|
+
|
|
151
|
+
describe('Object Logging', () => {
|
|
152
|
+
test('should format simple objects as JSON', () => {
|
|
153
|
+
const testObject = { id: 1, name: 'test', active: true };
|
|
154
|
+
|
|
155
|
+
logger.log('Object data:', testObject);
|
|
156
|
+
|
|
157
|
+
const logs = getCapturedLogs();
|
|
158
|
+
expect(logs[0]).toContain('"id": 1');
|
|
159
|
+
expect(logs[0]).toContain('"name": "test"');
|
|
160
|
+
expect(logs[0]).toContain('"active": true');
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('should handle nested objects', () => {
|
|
164
|
+
const nestedObject = {
|
|
165
|
+
user: {
|
|
166
|
+
id: 1,
|
|
167
|
+
profile: {
|
|
168
|
+
name: 'John',
|
|
169
|
+
settings: { theme: 'dark' }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
logger.log('Nested object:', nestedObject);
|
|
175
|
+
|
|
176
|
+
const logs = getCapturedLogs();
|
|
177
|
+
expect(logs[0]).toContain('"theme": "dark"');
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test('should handle arrays', () => {
|
|
181
|
+
const testArray = [1, 2, 3, 'test'];
|
|
182
|
+
|
|
183
|
+
logger.log('Array data:', testArray);
|
|
184
|
+
|
|
185
|
+
const logs = getCapturedLogs();
|
|
186
|
+
expect(logs[0]).toContain('[');
|
|
187
|
+
expect(logs[0]).toContain('1,');
|
|
188
|
+
expect(logs[0]).toContain('"test"');
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test('should handle multiple arguments', () => {
|
|
192
|
+
logger.log('Processing:', 'User ID:', 123, 'Status:', { active: true });
|
|
193
|
+
|
|
194
|
+
const logs = getCapturedLogs();
|
|
195
|
+
expect(logs[0]).toContain('Processing:');
|
|
196
|
+
expect(logs[0]).toContain('User ID:');
|
|
197
|
+
expect(logs[0]).toContain('123');
|
|
198
|
+
expect(logs[0]).toContain('"active": true');
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// =============================================
|
|
203
|
+
// Error Handling Tests
|
|
204
|
+
// =============================================
|
|
205
|
+
|
|
206
|
+
describe('Error Handling', () => {
|
|
207
|
+
test('should format standard JavaScript errors', () => {
|
|
208
|
+
const error = new Error('Test error message');
|
|
209
|
+
|
|
210
|
+
logger.error('Error occurred:', error);
|
|
211
|
+
|
|
212
|
+
const logs = getCapturedLogs();
|
|
213
|
+
expect(logs[0]).toContain('Test error message');
|
|
214
|
+
expect(logs[0]).toContain('"name": "Error"');
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test('should format A_Error instances with special formatting', () => {
|
|
218
|
+
const aError = new A_Error('Custom error message');
|
|
219
|
+
|
|
220
|
+
logger.error('A_Error occurred:', aError);
|
|
221
|
+
|
|
222
|
+
const logs = getCapturedLogs();
|
|
223
|
+
expect(logs[0]).toContain('Custom error message');
|
|
224
|
+
expect(logs[0]).toContain('-------------------------------');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('should handle errors with stack traces', () => {
|
|
228
|
+
const error = new Error('Stack trace test');
|
|
229
|
+
// Ensure error has stack
|
|
230
|
+
if (error.stack) {
|
|
231
|
+
logger.error(error);
|
|
232
|
+
|
|
233
|
+
const logs = getCapturedLogs();
|
|
234
|
+
expect(logs[0]).toContain('Stack trace test');
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// =============================================
|
|
240
|
+
// Color Support Tests
|
|
241
|
+
// =============================================
|
|
242
|
+
|
|
243
|
+
describe('Color Support', () => {
|
|
244
|
+
test('should support all defined colors', () => {
|
|
245
|
+
const colors: Array<keyof typeof A_LOGGER_COLORS> = [
|
|
246
|
+
'green', 'blue', 'red', 'yellow', 'gray',
|
|
247
|
+
'magenta', 'cyan', 'white', 'pink'
|
|
248
|
+
];
|
|
249
|
+
|
|
250
|
+
colors.forEach(color => {
|
|
251
|
+
clearCapturedLogs();
|
|
252
|
+
logger.log(color, `${color} message`);
|
|
253
|
+
|
|
254
|
+
const logs = getCapturedLogs();
|
|
255
|
+
expect(logs[0]).toContain(`${color} message`);
|
|
256
|
+
// Colors might not be shown in test environment, just verify message content
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
test('should default to blue color when no color specified', () => {
|
|
261
|
+
logger.log('Default color message');
|
|
262
|
+
|
|
263
|
+
const logs = getCapturedLogs();
|
|
264
|
+
expect(logs[0]).toContain('Default color message');
|
|
265
|
+
// Colors might not be shown in test environment, just verify message content
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
test('should treat non-color first argument as message', () => {
|
|
269
|
+
logger.log('not-a-color', 'Second argument');
|
|
270
|
+
|
|
271
|
+
const logs = getCapturedLogs();
|
|
272
|
+
expect(logs[0]).toContain('not-a-color');
|
|
273
|
+
expect(logs[0]).toContain('Second argument');
|
|
274
|
+
// Colors might not be shown in test environment, just verify message content
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// =============================================
|
|
279
|
+
// Log Level Filtering Tests
|
|
280
|
+
// =============================================
|
|
281
|
+
|
|
282
|
+
describe('Log Level Filtering', () => {
|
|
283
|
+
test('should respect debug log level (show all)', () => {
|
|
284
|
+
const config = { get: () => 'debug' } as any;
|
|
285
|
+
const debugLogger = new A_Logger(scope, config);
|
|
286
|
+
|
|
287
|
+
debugLogger.log('Debug message');
|
|
288
|
+
debugLogger.warning('Warning message');
|
|
289
|
+
debugLogger.error('Error message');
|
|
290
|
+
|
|
291
|
+
const logs = getCapturedLogs();
|
|
292
|
+
expect(logs).toHaveLength(3);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test('should respect info log level (show log, warning, error)', () => {
|
|
296
|
+
const config = { get: () => 'info' } as any;
|
|
297
|
+
const infoLogger = new A_Logger(scope, config);
|
|
298
|
+
|
|
299
|
+
infoLogger.log('Info message');
|
|
300
|
+
infoLogger.warning('Warning message');
|
|
301
|
+
infoLogger.error('Error message');
|
|
302
|
+
|
|
303
|
+
const logs = getCapturedLogs();
|
|
304
|
+
expect(logs).toHaveLength(3);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
test('should respect warn log level (show warning, error only)', () => {
|
|
308
|
+
const config = { get: () => 'warn' } as any;
|
|
309
|
+
const warnLogger = new A_Logger(scope, config);
|
|
310
|
+
|
|
311
|
+
warnLogger.log('Info message');
|
|
312
|
+
warnLogger.warning('Warning message');
|
|
313
|
+
warnLogger.error('Error message');
|
|
314
|
+
|
|
315
|
+
const logs = getCapturedLogs();
|
|
316
|
+
expect(logs).toHaveLength(2); // Only warning and error
|
|
317
|
+
expect(logs[0]).toContain('Warning message');
|
|
318
|
+
expect(logs[1]).toContain('Error message');
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test('should respect error log level (show error only)', () => {
|
|
322
|
+
const config = { get: () => 'error' } as any;
|
|
323
|
+
const errorLogger = new A_Logger(scope, config);
|
|
324
|
+
|
|
325
|
+
errorLogger.log('Info message');
|
|
326
|
+
errorLogger.warning('Warning message');
|
|
327
|
+
errorLogger.error('Error message');
|
|
328
|
+
|
|
329
|
+
const logs = getCapturedLogs();
|
|
330
|
+
expect(logs).toHaveLength(1); // Only error
|
|
331
|
+
expect(logs[0]).toContain('Error message');
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
test('should handle unknown log level (default to no logging)', () => {
|
|
335
|
+
const config = { get: () => 'unknown' } as any;
|
|
336
|
+
const unknownLogger = new A_Logger(scope, config);
|
|
337
|
+
|
|
338
|
+
unknownLogger.log('Info message');
|
|
339
|
+
unknownLogger.warning('Warning message');
|
|
340
|
+
unknownLogger.error('Error message');
|
|
341
|
+
|
|
342
|
+
const logs = getCapturedLogs();
|
|
343
|
+
expect(logs).toHaveLength(0);
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// =============================================
|
|
348
|
+
// Timestamp Tests
|
|
349
|
+
// =============================================
|
|
350
|
+
|
|
351
|
+
describe('Timestamp Formatting', () => {
|
|
352
|
+
test('should include timestamp in log messages', () => {
|
|
353
|
+
logger.log('Timestamp test');
|
|
354
|
+
|
|
355
|
+
const logs = getCapturedLogs();
|
|
356
|
+
// Should match pattern like |12:34:567|
|
|
357
|
+
expect(logs[0]).toMatch(/\|\d{2}:\d{2}:\d{3}\|/);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
test('should use consistent timestamp format', () => {
|
|
361
|
+
logger.log('First message');
|
|
362
|
+
logger.log('Second message');
|
|
363
|
+
|
|
364
|
+
const logs = getCapturedLogs();
|
|
365
|
+
|
|
366
|
+
// Extract timestamps from both logs
|
|
367
|
+
const timestampRegex = /\|(\d{2}:\d{2}:\d{3})\|/;
|
|
368
|
+
const timestamp1 = logs[0].match(timestampRegex);
|
|
369
|
+
const timestamp2 = logs[1].match(timestampRegex);
|
|
370
|
+
|
|
371
|
+
expect(timestamp1).not.toBeNull();
|
|
372
|
+
expect(timestamp2).not.toBeNull();
|
|
373
|
+
if (timestamp1 && timestamp2) {
|
|
374
|
+
expect(timestamp1[1]).toMatch(/\d{2}:\d{2}:\d{3}/);
|
|
375
|
+
expect(timestamp2[1]).toMatch(/\d{2}:\d{2}:\d{3}/);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// =============================================
|
|
381
|
+
// Edge Cases and Error Conditions
|
|
382
|
+
// =============================================
|
|
383
|
+
|
|
384
|
+
describe('Edge Cases', () => {
|
|
385
|
+
test('should handle null and undefined values', () => {
|
|
386
|
+
logger.log('Null value:', null);
|
|
387
|
+
logger.log('Undefined value:', undefined);
|
|
388
|
+
|
|
389
|
+
const logs = getCapturedLogs();
|
|
390
|
+
expect(logs[0]).toContain('null');
|
|
391
|
+
expect(logs[1]).toContain('undefined');
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
test('should handle circular references in objects', () => {
|
|
395
|
+
const circularObj: any = { name: 'test' };
|
|
396
|
+
circularObj.self = circularObj;
|
|
397
|
+
|
|
398
|
+
// Should not throw an error and should handle circular reference gracefully
|
|
399
|
+
expect(() => {
|
|
400
|
+
logger.log('Circular object:', circularObj);
|
|
401
|
+
}).not.toThrow();
|
|
402
|
+
|
|
403
|
+
const logs = getCapturedLogs();
|
|
404
|
+
expect(logs[0]).toContain('Circular object:');
|
|
405
|
+
expect(logs[0]).toContain('[Circular Reference]');
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
test('should handle very long strings', () => {
|
|
409
|
+
const longString = 'A'.repeat(1000);
|
|
410
|
+
|
|
411
|
+
logger.log('Long string:', longString);
|
|
412
|
+
|
|
413
|
+
const logs = getCapturedLogs();
|
|
414
|
+
expect(logs[0]).toContain(longString);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
test('should handle empty scope name', () => {
|
|
418
|
+
const emptyScope = new A_Scope({ name: '' });
|
|
419
|
+
const emptyLogger = new A_Logger(emptyScope);
|
|
420
|
+
|
|
421
|
+
emptyLogger.log('Empty scope test');
|
|
422
|
+
|
|
423
|
+
const logs = getCapturedLogs();
|
|
424
|
+
expect(logs).toHaveLength(1);
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
// =============================================
|
|
429
|
+
// Performance Tests
|
|
430
|
+
// =============================================
|
|
431
|
+
|
|
432
|
+
describe('Performance', () => {
|
|
433
|
+
test('should handle multiple rapid log calls', () => {
|
|
434
|
+
const startTime = Date.now();
|
|
435
|
+
|
|
436
|
+
for (let i = 0; i < 100; i++) {
|
|
437
|
+
logger.log(`Message ${i}`);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const endTime = Date.now();
|
|
441
|
+
const logs = getCapturedLogs();
|
|
442
|
+
|
|
443
|
+
expect(logs).toHaveLength(100);
|
|
444
|
+
expect(endTime - startTime).toBeLessThan(1000); // Should complete within 1 second
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
test('should handle large objects efficiently', () => {
|
|
448
|
+
const largeObject = {
|
|
449
|
+
data: Array.from({ length: 100 }, (_, i) => ({
|
|
450
|
+
id: i,
|
|
451
|
+
name: `Item ${i}`,
|
|
452
|
+
metadata: { timestamp: Date.now(), active: true }
|
|
453
|
+
}))
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
const startTime = Date.now();
|
|
457
|
+
logger.log('Large object:', largeObject);
|
|
458
|
+
const endTime = Date.now();
|
|
459
|
+
|
|
460
|
+
const logs = getCapturedLogs();
|
|
461
|
+
expect(logs).toHaveLength(1);
|
|
462
|
+
expect(endTime - startTime).toBeLessThan(500); // Should complete within 500ms
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// =============================================
|
|
468
|
+
// Integration Tests
|
|
469
|
+
// =============================================
|
|
470
|
+
|
|
471
|
+
describe('A_Logger Integration', () => {
|
|
472
|
+
beforeEach(() => {
|
|
473
|
+
clearCapturedLogs();
|
|
474
|
+
mockConsole();
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
afterEach(() => {
|
|
478
|
+
restoreConsole();
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
test('should work with different scope configurations', () => {
|
|
482
|
+
const scopes = [
|
|
483
|
+
new A_Scope({ name: 'Service1' }),
|
|
484
|
+
new A_Scope({ name: 'Service2' }),
|
|
485
|
+
new A_Scope({ name: 'Service3' })
|
|
486
|
+
];
|
|
487
|
+
|
|
488
|
+
scopes.forEach((scope, index) => {
|
|
489
|
+
const logger = new A_Logger(scope);
|
|
490
|
+
logger.log(`Message from ${scope.name}`);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
const logs = getCapturedLogs();
|
|
494
|
+
expect(logs).toHaveLength(3);
|
|
495
|
+
|
|
496
|
+
logs.forEach((log, index) => {
|
|
497
|
+
expect(log).toContain(`Service${index + 1}`);
|
|
498
|
+
expect(log).toContain(`Message from Service${index + 1}`);
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
test('should maintain scope isolation', () => {
|
|
503
|
+
const scope1 = new A_Scope({ name: 'Scope1' });
|
|
504
|
+
const scope2 = new A_Scope({ name: 'Scope2' });
|
|
505
|
+
|
|
506
|
+
const logger1 = new A_Logger(scope1);
|
|
507
|
+
const logger2 = new A_Logger(scope2);
|
|
508
|
+
|
|
509
|
+
logger1.log('Message from logger 1');
|
|
510
|
+
logger2.log('Message from logger 2');
|
|
511
|
+
|
|
512
|
+
const logs = getCapturedLogs();
|
|
513
|
+
expect(logs[0]).toContain('Scope1');
|
|
514
|
+
expect(logs[0]).toContain('Message from logger 1');
|
|
515
|
+
expect(logs[1]).toContain('Scope2');
|
|
516
|
+
expect(logs[1]).toContain('Message from logger 2');
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
export { mockConsole, restoreConsole, getCapturedLogs, clearCapturedLogs };
|
package/tests/A-Memory.test.ts
CHANGED
|
@@ -104,18 +104,18 @@ describe('A-Memory tests', () => {
|
|
|
104
104
|
}>();
|
|
105
105
|
|
|
106
106
|
// No values set initially
|
|
107
|
-
expect(await memory.
|
|
107
|
+
expect(await memory.prerequisites(['required1', 'required2'])).toBe(false);
|
|
108
108
|
|
|
109
109
|
// Set one required value
|
|
110
110
|
await memory.set('required1', 'value1');
|
|
111
|
-
expect(await memory.
|
|
111
|
+
expect(await memory.prerequisites(['required1', 'required2'])).toBe(false);
|
|
112
112
|
|
|
113
113
|
// Set both required values
|
|
114
114
|
await memory.set('required2', 42);
|
|
115
|
-
expect(await memory.
|
|
116
|
-
|
|
115
|
+
expect(await memory.prerequisites(['required1', 'required2'])).toBe(true);
|
|
116
|
+
|
|
117
117
|
// Test with empty requirements
|
|
118
|
-
expect(await memory.
|
|
118
|
+
expect(await memory.prerequisites([])).toBe(true);
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
it('Should serialize to JSON correctly', async () => {
|
package/tests/A-Polyfill.test.ts
CHANGED
|
@@ -14,7 +14,7 @@ describe('A-Polyfill Tests', () => {
|
|
|
14
14
|
testScope = new A_Scope({
|
|
15
15
|
components: [A_Polyfill, A_Logger],
|
|
16
16
|
});
|
|
17
|
-
polyfill = testScope.resolve(A_Polyfill)
|
|
17
|
+
polyfill = testScope.resolve(A_Polyfill)!;
|
|
18
18
|
await polyfill.load();
|
|
19
19
|
});
|
|
20
20
|
|
|
@@ -190,6 +190,7 @@ describe('A-Polyfill Tests', () => {
|
|
|
190
190
|
);
|
|
191
191
|
|
|
192
192
|
req.on('error', (err) => {
|
|
193
|
+
console.log('Request error:', err);
|
|
193
194
|
reject(err);
|
|
194
195
|
});
|
|
195
196
|
|
|
@@ -429,7 +430,7 @@ describe('A-Polyfill Tests', () => {
|
|
|
429
430
|
const freshScope = new A_Scope({
|
|
430
431
|
components: [A_Polyfill, A_Logger]
|
|
431
432
|
});
|
|
432
|
-
const freshPolyfill = freshScope.resolve(A_Polyfill)
|
|
433
|
+
const freshPolyfill = freshScope.resolve(A_Polyfill)!;
|
|
433
434
|
|
|
434
435
|
// Only initialize the needed polyfills
|
|
435
436
|
const crypto = await freshPolyfill.crypto();
|