@reldens/utils 0.52.0 → 0.54.0
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/CLAUDE.md +87 -0
- package/README.md +93 -6
- package/lib/events-manager.js +25 -4
- package/package.json +1 -1
- package/tests/events-manager-test.js +71 -44
- package/tests/run.js +8 -6
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Package Overview
|
|
6
|
+
|
|
7
|
+
**@reldens/utils** is a core utility package used throughout the Reldens ecosystem. It provides essential utilities for:
|
|
8
|
+
- Object manipulation (Shortcuts class)
|
|
9
|
+
- Event management (EventsManager)
|
|
10
|
+
- Logging (Logger)
|
|
11
|
+
- Schema validation (SchemaValidator)
|
|
12
|
+
- Environment variables (EnvVar)
|
|
13
|
+
- Error handling (ErrorManager)
|
|
14
|
+
- Interaction area validation (InteractionArea)
|
|
15
|
+
- Pagination utilities (PageRangeProvider)
|
|
16
|
+
- Validator base interface (ValidatorInterface)
|
|
17
|
+
|
|
18
|
+
## Key Commands
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Run tests
|
|
22
|
+
npm test
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
### Core Classes
|
|
28
|
+
|
|
29
|
+
**Shortcuts** (`lib/shortcuts.js`):
|
|
30
|
+
- Provides utility methods for object manipulation, property access, and validation
|
|
31
|
+
- Imported as `sc` throughout the Reldens codebase
|
|
32
|
+
- Key methods: `get`, `hasOwn`, `isObject`, `isArray`, `deepMerge`, `deepClone`, etc.
|
|
33
|
+
- Used instead of direct property access or Object.prototype methods
|
|
34
|
+
|
|
35
|
+
**EventsManager** (`lib/events-manager.js`):
|
|
36
|
+
- Singleton event system used across Reldens
|
|
37
|
+
- Supports both sync (`emitSync`) and async (`emit`) events
|
|
38
|
+
- Allows event listeners to modify data via reference
|
|
39
|
+
- Debug mode available via `debug` property
|
|
40
|
+
|
|
41
|
+
**Logger** (`lib/logger.js`):
|
|
42
|
+
- Centralized logging utility with multiple log levels
|
|
43
|
+
- Levels: emergency, alert, critical, error, warning, notice, info, debug
|
|
44
|
+
- Configurable log level and trace options
|
|
45
|
+
- Used instead of console.log
|
|
46
|
+
|
|
47
|
+
**SchemaValidator** (`lib/schema-validator.js`):
|
|
48
|
+
- JSON schema validation utility
|
|
49
|
+
- Validates data structures against defined schemas
|
|
50
|
+
- Returns validation results with errors
|
|
51
|
+
|
|
52
|
+
**EnvVar** (`lib/env-var.js`):
|
|
53
|
+
- Environment variable utilities
|
|
54
|
+
- Type conversion and validation
|
|
55
|
+
- Safe environment variable access
|
|
56
|
+
|
|
57
|
+
**ErrorManager** (`lib/error-manager.js`):
|
|
58
|
+
- Singleton error handling utility
|
|
59
|
+
- Configurable error tracing via `enableTrace` property
|
|
60
|
+
- Supports custom error callbacks via `callback` property
|
|
61
|
+
- Default behavior throws Error with a message
|
|
62
|
+
|
|
63
|
+
**InteractionArea** (`lib/interaction-area.js`):
|
|
64
|
+
- Validates if positions are within interaction range
|
|
65
|
+
- Used for player-to-player, player-to-object interactions
|
|
66
|
+
- Configurable interaction area/margin
|
|
67
|
+
- Key methods: `setupInteractionArea`, `isValidInteraction`, `getPosition`
|
|
68
|
+
|
|
69
|
+
**PageRangeProvider** (`lib/page-range-provider.js`):
|
|
70
|
+
- Singleton pagination utility
|
|
71
|
+
- Generates page ranges for UI pagination
|
|
72
|
+
- Key method: `fetch(page, totalPages, totalDisplayedPages, firstLabel, lastLabel)`
|
|
73
|
+
- Returns array of page objects with label and value
|
|
74
|
+
|
|
75
|
+
**ValidatorInterface** (`lib/validator-interface.js`):
|
|
76
|
+
- Base interface for validator implementations
|
|
77
|
+
- Provides default `validate()` method that returns true
|
|
78
|
+
- Extend this class to create custom validators
|
|
79
|
+
|
|
80
|
+
## Important Notes
|
|
81
|
+
|
|
82
|
+
- This package has NO external dependencies
|
|
83
|
+
- All code must be pure JavaScript with no dependencies
|
|
84
|
+
- The Shortcuts class is used extensively across Reldens - any changes affect the entire ecosystem
|
|
85
|
+
- Singleton pattern is used for: ErrorManager, PageRangeProvider, and EventsManagerSingleton (exported alongside the EventsManager class)
|
|
86
|
+
- Logger methods should be used instead of console.log everywhere in Reldens
|
|
87
|
+
- InteractionArea is instantiable (not a singleton) - create instances for each interactive object
|
package/README.md
CHANGED
|
@@ -78,14 +78,13 @@ Pagination helper that calculates page ranges for UI components, handling first/
|
|
|
78
78
|
|
|
79
79
|
```javascript
|
|
80
80
|
const { PageRangeProvider } = require('@reldens/utils');
|
|
81
|
-
let pageProvider = new PageRangeProvider();
|
|
82
81
|
|
|
83
|
-
// Generate page range
|
|
84
|
-
let range =
|
|
82
|
+
// Generate page range (it's a singleton, use directly)
|
|
83
|
+
let range = PageRangeProvider.fetch(5, 20, 7, 'First', 'Last');
|
|
85
84
|
// Returns: [{label: 'First', value: 1}, {label: 2, value: 2}, ...]
|
|
86
85
|
|
|
87
86
|
// Simple range
|
|
88
|
-
let simpleRange =
|
|
87
|
+
let simpleRange = PageRangeProvider.fetch(3, 10, 5);
|
|
89
88
|
// Returns pages around current page 3
|
|
90
89
|
```
|
|
91
90
|
|
|
@@ -98,8 +97,8 @@ const { SchemaValidator } = require('@reldens/utils');
|
|
|
98
97
|
let schema = {
|
|
99
98
|
username: { type: 'string', min: 3, max: 20 },
|
|
100
99
|
age: { type: 'int', min: 18 },
|
|
101
|
-
profile: {
|
|
102
|
-
type: 'object',
|
|
100
|
+
profile: {
|
|
101
|
+
type: 'object',
|
|
103
102
|
nested: {
|
|
104
103
|
email: { type: 'string', required: true }
|
|
105
104
|
}
|
|
@@ -111,6 +110,94 @@ let userData = { username: 'player1', age: 25, profile: { email: 'test@example.c
|
|
|
111
110
|
let isValid = validator.validate(userData);
|
|
112
111
|
```
|
|
113
112
|
|
|
113
|
+
### Shortcuts (sc)
|
|
114
|
+
Core utility class providing essential object manipulation, property access, and validation methods used throughout Reldens.
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
const { sc } = require('@reldens/utils');
|
|
118
|
+
|
|
119
|
+
// Safe property access
|
|
120
|
+
let value = sc.get(obj, 'nested.property.path', 'defaultValue');
|
|
121
|
+
|
|
122
|
+
// Check property ownership
|
|
123
|
+
if (sc.hasOwn(obj, 'propertyName')) {
|
|
124
|
+
// Property exists
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Type checking
|
|
128
|
+
sc.isObject(value); // true/false
|
|
129
|
+
sc.isArray(value); // true/false
|
|
130
|
+
sc.isFunction(value); // true/false
|
|
131
|
+
|
|
132
|
+
// Deep operations
|
|
133
|
+
let cloned = sc.deepClone(originalObject);
|
|
134
|
+
let merged = sc.deepMerge(obj1, obj2);
|
|
135
|
+
|
|
136
|
+
// Property manipulation
|
|
137
|
+
sc.getDef(obj, 'key', 'default'); // Get with default
|
|
138
|
+
sc.getOneDef(obj, ['key1', 'key2'], 'default'); // Get first found key
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### ErrorManager
|
|
142
|
+
Singleton error handling utility with configurable tracing and custom error callbacks.
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
const { ErrorManager } = require('@reldens/utils');
|
|
146
|
+
|
|
147
|
+
// Enable stack traces
|
|
148
|
+
ErrorManager.enableTrace = true;
|
|
149
|
+
|
|
150
|
+
// Custom error handling
|
|
151
|
+
ErrorManager.callback = (message) => {
|
|
152
|
+
// Custom error handling logic
|
|
153
|
+
console.error('Custom error:', message);
|
|
154
|
+
// Return false to prevent default throw
|
|
155
|
+
return false;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// Trigger error
|
|
159
|
+
ErrorManager.error('Something went wrong');
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### EnvVar
|
|
163
|
+
Environment variable utilities with type conversion and validation for safe environment variable access.
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
const { EnvVar } = require('@reldens/utils');
|
|
167
|
+
|
|
168
|
+
// Get environment variables with type conversion
|
|
169
|
+
let port = EnvVar.integer(process.env, 'PORT', 3000); // Returns integer or default
|
|
170
|
+
let enabled = EnvVar.boolean(process.env, 'FEATURE_ENABLED', false); // Returns boolean
|
|
171
|
+
let apiUrl = EnvVar.string(process.env, 'API_URL', 'http://localhost'); // Returns string
|
|
172
|
+
|
|
173
|
+
// Other type helpers
|
|
174
|
+
let portNumber = EnvVar.port(process.env, 'PORT', 8080); // Validates port range 1-65535
|
|
175
|
+
let config = EnvVar.json(process.env, 'CONFIG', {}); // Parse JSON string
|
|
176
|
+
let items = EnvVar.array(process.env, 'ITEMS', [], ','); // Split string to array
|
|
177
|
+
let url = EnvVar.url(process.env, 'API_URL', 'http://localhost'); // Validate URL
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### ValidatorInterface
|
|
181
|
+
Base interface for creating custom validators with a standard validate method.
|
|
182
|
+
|
|
183
|
+
```javascript
|
|
184
|
+
const { ValidatorInterface } = require('@reldens/utils');
|
|
185
|
+
|
|
186
|
+
// Extend to create custom validators
|
|
187
|
+
class CustomValidator extends ValidatorInterface {
|
|
188
|
+
validate(data) {
|
|
189
|
+
// Custom validation logic
|
|
190
|
+
if (!data.requiredField) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let validator = new CustomValidator();
|
|
198
|
+
let isValid = validator.validate({ requiredField: 'value' });
|
|
199
|
+
```
|
|
200
|
+
|
|
114
201
|
---
|
|
115
202
|
|
|
116
203
|
Need something specific?
|
package/lib/events-manager.js
CHANGED
|
@@ -21,10 +21,11 @@ class EventsManager
|
|
|
21
21
|
this.maxEventKeyLength = 1000;
|
|
22
22
|
this.maxListeners = 10000;
|
|
23
23
|
this.maxEventArgs = 50;
|
|
24
|
-
this.sensitiveFields = ['password', 'token', 'secret', '
|
|
24
|
+
this.sensitiveFields = ['password', 'token', 'secret', 'auth', 'credential'];
|
|
25
25
|
this.hasLoggedMaxListeners = false;
|
|
26
26
|
this.symbolString = '--[[await-event-emitter]]--';
|
|
27
27
|
this.typeKeyName = sc.isFunction(Symbol) ? Symbol.for(this.symbolString) : this.symbolString;
|
|
28
|
+
this.enableSensitiveDataFiltering = false;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
assertType(type)
|
|
@@ -81,6 +82,9 @@ class EventsManager
|
|
|
81
82
|
Logger.warning('Event arguments exceed maximum: '+args.length);
|
|
82
83
|
return [];
|
|
83
84
|
}
|
|
85
|
+
if(!this.enableSensitiveDataFiltering){
|
|
86
|
+
return args;
|
|
87
|
+
}
|
|
84
88
|
return args.map(arg => {
|
|
85
89
|
if(sc.isObject(arg)){
|
|
86
90
|
return this.filterSensitiveData(arg);
|
|
@@ -89,11 +93,21 @@ class EventsManager
|
|
|
89
93
|
});
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
filterSensitiveData(obj)
|
|
96
|
+
filterSensitiveData(obj, visited = new WeakSet())
|
|
93
97
|
{
|
|
94
98
|
if(!sc.isObject(obj)){
|
|
95
99
|
return obj;
|
|
96
100
|
}
|
|
101
|
+
if(visited.has(obj)){
|
|
102
|
+
return '[CIRCULAR]';
|
|
103
|
+
}
|
|
104
|
+
if(obj instanceof Map || obj instanceof Set || obj instanceof Date || obj instanceof Array){
|
|
105
|
+
return obj;
|
|
106
|
+
}
|
|
107
|
+
if(Object.getPrototypeOf(obj) !== Object.prototype){
|
|
108
|
+
return obj;
|
|
109
|
+
}
|
|
110
|
+
visited.add(obj);
|
|
97
111
|
let filtered = {};
|
|
98
112
|
for(let key of Object.keys(obj)){
|
|
99
113
|
if(sc.hasDangerousKeys(null, key)){
|
|
@@ -107,11 +121,16 @@ class EventsManager
|
|
|
107
121
|
continue;
|
|
108
122
|
}
|
|
109
123
|
if(sc.isObject(obj[key])){
|
|
110
|
-
filtered[key] = this.filterSensitiveData(obj[key]);
|
|
124
|
+
filtered[key] = this.filterSensitiveData(obj[key], visited);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if(sc.isFunction(obj[key])) {
|
|
128
|
+
filtered[key] = obj[key];
|
|
111
129
|
continue;
|
|
112
130
|
}
|
|
113
131
|
filtered[key] = obj[key];
|
|
114
132
|
}
|
|
133
|
+
visited.delete(obj);
|
|
115
134
|
return filtered;
|
|
116
135
|
}
|
|
117
136
|
|
|
@@ -442,7 +461,9 @@ class EventsManager
|
|
|
442
461
|
}
|
|
443
462
|
let logMessage = type+' Event: '+key;
|
|
444
463
|
if(args && 0 < args.length){
|
|
445
|
-
let filteredArgs =
|
|
464
|
+
let filteredArgs = this.enableSensitiveDataFiltering
|
|
465
|
+
? args.map(arg => this.filterSensitiveData(arg))
|
|
466
|
+
: args;
|
|
446
467
|
logMessage += ' with '+filteredArgs.length+' arguments';
|
|
447
468
|
}
|
|
448
469
|
Logger.debug(logMessage);
|
package/package.json
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - TestEventsManager
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const EventsManager = require('../lib/events-manager');
|
|
2
8
|
|
|
3
9
|
class TestEventsManager
|
|
@@ -8,6 +14,7 @@ class TestEventsManager
|
|
|
8
14
|
this.testResults = [];
|
|
9
15
|
this.testCount = 0;
|
|
10
16
|
this.passedCount = 0;
|
|
17
|
+
this.currentTestMethod = '';
|
|
11
18
|
}
|
|
12
19
|
|
|
13
20
|
test(name, testFn)
|
|
@@ -15,11 +22,13 @@ class TestEventsManager
|
|
|
15
22
|
this.testCount++;
|
|
16
23
|
try{
|
|
17
24
|
testFn();
|
|
18
|
-
|
|
25
|
+
let logMessage = '✓ PASS: '+this.currentTestMethod+' - '+name;
|
|
26
|
+
console.log(logMessage);
|
|
19
27
|
this.passedCount++;
|
|
20
28
|
this.testResults.push({name, status: 'PASS'});
|
|
21
29
|
} catch(error){
|
|
22
|
-
|
|
30
|
+
let logMessage = '✗ FAIL: '+this.currentTestMethod+' - '+name+' - '+error.message;
|
|
31
|
+
console.log(logMessage);
|
|
23
32
|
this.testResults.push({name, status: 'FAIL', error: error.message});
|
|
24
33
|
}
|
|
25
34
|
}
|
|
@@ -31,21 +40,23 @@ class TestEventsManager
|
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
runAllTests()
|
|
43
|
+
async runAllTests()
|
|
35
44
|
{
|
|
36
45
|
console.log('Running tests for EventsManager...\n');
|
|
37
|
-
|
|
38
46
|
let methodNames = Object.getOwnPropertyNames(Object.getPrototypeOf(this));
|
|
39
47
|
let testMethods = methodNames.filter(name =>
|
|
40
48
|
name.startsWith('test') &&
|
|
41
49
|
'function' === typeof this[name] &&
|
|
42
50
|
name !== 'test'
|
|
43
51
|
);
|
|
44
|
-
|
|
45
52
|
for(let methodName of testMethods){
|
|
46
|
-
this
|
|
53
|
+
this.currentTestMethod = methodName;
|
|
54
|
+
try{
|
|
55
|
+
await this[methodName]();
|
|
56
|
+
} catch(error){
|
|
57
|
+
console.error('Test method failed:', methodName, error.message);
|
|
58
|
+
}
|
|
47
59
|
}
|
|
48
|
-
|
|
49
60
|
this.printSummary();
|
|
50
61
|
}
|
|
51
62
|
|
|
@@ -289,16 +300,17 @@ class TestEventsManager
|
|
|
289
300
|
let loggedMessages = [];
|
|
290
301
|
let originalDebug = console.log;
|
|
291
302
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
303
|
+
try{
|
|
304
|
+
console.log = (...args) => loggedMessages.push(args.join(' '));
|
|
305
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
306
|
+
for(let i = 0; i < 10; i++){
|
|
307
|
+
emitter.on('test-max-'+i, () => {});
|
|
308
|
+
}
|
|
309
|
+
} finally{
|
|
310
|
+
console.log = originalDebug;
|
|
311
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
297
312
|
}
|
|
298
313
|
|
|
299
|
-
console.log = originalDebug;
|
|
300
|
-
delete process.env.RELDENS_LOG_LEVEL;
|
|
301
|
-
|
|
302
314
|
let debugLogs = loggedMessages.filter(log => log.includes('High listener count detected'));
|
|
303
315
|
this.assert(1 === debugLogs.length, 'Should log high listener count only once');
|
|
304
316
|
this.assert(true === emitter.hasLoggedMaxListeners, 'Should set flag after logging');
|
|
@@ -498,14 +510,15 @@ class TestEventsManager
|
|
|
498
510
|
let loggedMessages = [];
|
|
499
511
|
let originalLog = console.log;
|
|
500
512
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
513
|
+
try{
|
|
514
|
+
console.log = (...args) => loggedMessages.push(args.join(' '));
|
|
515
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
516
|
+
let sensitiveArgs = [{password: 'secret', safe: 'data'}];
|
|
517
|
+
emitter.logDebugEvent('test', 'Fire', sensitiveArgs);
|
|
518
|
+
} finally{
|
|
519
|
+
console.log = originalLog;
|
|
520
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
521
|
+
}
|
|
509
522
|
|
|
510
523
|
let debugLog = loggedMessages.find(log => log.includes('Fire Event: test'));
|
|
511
524
|
this.assert(debugLog, 'Should log debug event');
|
|
@@ -580,13 +593,14 @@ class TestEventsManager
|
|
|
580
593
|
|
|
581
594
|
let loggedMessages = [];
|
|
582
595
|
let originalLog = console.log;
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
596
|
+
try{
|
|
597
|
+
console.log = (...args) => loggedMessages.push(args.join(' '));
|
|
598
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
599
|
+
emitter.logDebugEvent('non-matching-key', 'Listen');
|
|
600
|
+
} finally{
|
|
601
|
+
console.log = originalLog;
|
|
602
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
603
|
+
}
|
|
590
604
|
|
|
591
605
|
let debugLogs = loggedMessages.filter(log => log.includes('Listen Event:'));
|
|
592
606
|
this.assert(0 === debugLogs.length, 'Should not log when no pattern matches');
|
|
@@ -894,17 +908,16 @@ class TestEventsManager
|
|
|
894
908
|
let emitter = new EventsManager();
|
|
895
909
|
let loggedEvents = [];
|
|
896
910
|
let originalLog = console.log;
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
911
|
+
try{
|
|
912
|
+
console.log = (...args) => loggedEvents.push(args.join(' '));
|
|
913
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
914
|
+
emitter.debug = 'all';
|
|
915
|
+
emitter.on('debug-test', () => {});
|
|
916
|
+
await emitter.emit('debug-test');
|
|
917
|
+
} finally{
|
|
918
|
+
console.log = originalLog;
|
|
919
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
920
|
+
}
|
|
908
921
|
let hasListenLog = loggedEvents.some(log => log.includes('Listen Event:'));
|
|
909
922
|
let hasFireLog = loggedEvents.some(log => log.includes('Fire Event:'));
|
|
910
923
|
this.assert(hasListenLog, 'Should log listen events');
|
|
@@ -1058,6 +1071,17 @@ class TestEventsManager
|
|
|
1058
1071
|
});
|
|
1059
1072
|
}
|
|
1060
1073
|
|
|
1074
|
+
testFilterSensitiveDataWithCircularReferences()
|
|
1075
|
+
{
|
|
1076
|
+
this.test('filterSensitiveData handles circular references', () => {
|
|
1077
|
+
let emitter = new EventsManager();
|
|
1078
|
+
let obj = {safe: 'data'};
|
|
1079
|
+
obj.circular = obj;
|
|
1080
|
+
let result = emitter.filterSensitiveData(obj);
|
|
1081
|
+
this.assert('[CIRCULAR]' === result.circular, 'Should handle circular refs');
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1061
1085
|
printSummary()
|
|
1062
1086
|
{
|
|
1063
1087
|
console.log('\n'+'='.repeat(50));
|
|
@@ -1067,7 +1091,6 @@ class TestEventsManager
|
|
|
1067
1091
|
console.log('Passed:', this.passedCount);
|
|
1068
1092
|
console.log('Failed:', this.testCount - this.passedCount);
|
|
1069
1093
|
console.log('Success rate:', Math.round((this.passedCount / this.testCount) * 100)+'%');
|
|
1070
|
-
|
|
1071
1094
|
if(this.testCount - this.passedCount > 0){
|
|
1072
1095
|
console.log('\nFailed tests:');
|
|
1073
1096
|
for(let result of this.testResults){
|
|
@@ -1076,9 +1099,13 @@ class TestEventsManager
|
|
|
1076
1099
|
}
|
|
1077
1100
|
}
|
|
1078
1101
|
}
|
|
1102
|
+
console.log('\n'+'='.repeat(60));
|
|
1103
|
+
if(this.testCount - this.passedCount === 0){
|
|
1104
|
+
console.log('All tests completed successfully!');
|
|
1105
|
+
}
|
|
1106
|
+
console.log('='.repeat(60));
|
|
1079
1107
|
}
|
|
1080
1108
|
|
|
1081
1109
|
}
|
|
1082
1110
|
|
|
1083
|
-
|
|
1084
|
-
testRunner.runAllTests();
|
|
1111
|
+
module.exports.TestEventsManager = TestEventsManager;
|
package/tests/run.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
console.log('Running all tests...\n');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
async function runTests(){
|
|
4
4
|
console.log('='.repeat(60));
|
|
5
|
-
console.log('TESTING
|
|
5
|
+
console.log('TESTING IMPLEMENTATION');
|
|
6
6
|
console.log('='.repeat(60));
|
|
7
|
-
require('./events-manager-test.js');
|
|
7
|
+
const { TestEventsManager } = require('./events-manager-test.js');
|
|
8
|
+
let testInstance = new TestEventsManager();
|
|
9
|
+
await testInstance.runAllTests();
|
|
10
|
+
}
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
} catch(error){
|
|
12
|
+
runTests().catch(error => {
|
|
11
13
|
console.error('\nTest execution failed:', error.message);
|
|
12
14
|
process.exit(1);
|
|
13
|
-
}
|
|
15
|
+
});
|