0
# Garbage Collection Utilities
1
2
Memory management and cleanup utilities for test isolation and performance optimization. These utilities provide controlled property deletion and protection mechanisms to manage memory usage and prevent test interference.
3
4
## Capabilities
5
6
### Deletion Mode
7
8
Enumeration defining different modes for property deletion behavior in the garbage collection system.
9
10
```typescript { .api }
11
/**
12
* Deletion mode for garbage collection behavior
13
*/
14
type DeletionMode = 'soft' | 'off' | 'on';
15
```
16
17
**Mode Descriptions:**
18
- **'off'**: Deletion completely disabled - properties are never deleted
19
- **'soft'**: Wraps getters/setters with deprecation warnings instead of deleting
20
- **'on'**: Actually deletes properties using the `delete` operator
21
22
### Initialize Garbage Collection Utils
23
24
Initializes the garbage collection system with a specified deletion mode for the given global object.
25
26
```typescript { .api }
27
/**
28
* Initializes garbage collection system with specified deletion mode
29
* @param globalObject - Global object to initialize GC system on
30
* @param deletionMode - Mode for property deletion behavior
31
* @throws Warning if mode already initialized with different setting
32
*/
33
function initializeGarbageCollectionUtils(
34
globalObject: typeof globalThis,
35
deletionMode: DeletionMode
36
): void;
37
```
38
39
**Usage Examples:**
40
41
```typescript
42
import { initializeGarbageCollectionUtils } from "jest-util";
43
44
// Initialize GC system for test environment
45
initializeGarbageCollectionUtils(globalThis, 'soft');
46
47
// Different modes for different environments
48
if (process.env.NODE_ENV === 'test') {
49
initializeGarbageCollectionUtils(globalThis, 'on'); // Aggressive cleanup
50
} else if (process.env.NODE_ENV === 'development') {
51
initializeGarbageCollectionUtils(globalThis, 'soft'); // Warnings only
52
} else {
53
initializeGarbageCollectionUtils(globalThis, 'off'); // No cleanup
54
}
55
56
// Jest test environment setup
57
function setupTestEnvironment() {
58
initializeGarbageCollectionUtils(globalThis, 'soft');
59
// Now all GC utilities will use soft deletion mode
60
}
61
```
62
63
### Can Delete Properties
64
65
Type guard that determines if a value has properties that can be deleted through the garbage collection system.
66
67
```typescript { .api }
68
/**
69
* Type guard checking if value has deletable properties
70
* @param value - Value to check for deletable properties
71
* @returns true for objects and functions (excluding null)
72
*/
73
function canDeleteProperties(value: unknown): value is object;
74
```
75
76
**Usage Examples:**
77
78
```typescript
79
import { canDeleteProperties } from "jest-util";
80
81
// Safe property deletion check
82
function cleanupValue(value: unknown) {
83
if (canDeleteProperties(value)) {
84
// TypeScript knows 'value' is an object here
85
deleteProperties(value);
86
}
87
}
88
89
// Test cleanup with type safety
90
const testValues = [
91
{ data: "test" }, // object - can delete
92
() => {}, // function - can delete
93
null, // null - cannot delete
94
"string", // primitive - cannot delete
95
42, // primitive - cannot delete
96
undefined // undefined - cannot delete
97
];
98
99
testValues.forEach(value => {
100
if (canDeleteProperties(value)) {
101
console.log("Can clean up:", typeof value);
102
// Safely perform cleanup operations
103
}
104
});
105
106
// Conditional cleanup in test teardown
107
function teardownTestObject(testObj: any) {
108
if (canDeleteProperties(testObj)) {
109
// Safe to attempt property deletion
110
protectProperties(testObj, ['id', 'name']); // Protect essential props
111
deleteProperties(testObj); // Clean up the rest
112
}
113
}
114
```
115
116
### Protect Properties
117
118
Protects specified object properties from garbage collection deletion, with optional recursive protection.
119
120
```typescript { .api }
121
/**
122
* Protects object properties from garbage collection deletion
123
* @param value - Object to protect properties on
124
* @param properties - Specific properties to protect (empty array = all properties)
125
* @param depth - Nesting depth for recursive protection (default: 2)
126
* @returns Whether protection was successfully applied
127
*/
128
function protectProperties<T>(
129
value: T,
130
properties?: Array<keyof T>,
131
depth?: number
132
): boolean;
133
```
134
135
**Usage Examples:**
136
137
```typescript
138
import { protectProperties, deleteProperties } from "jest-util";
139
140
// Protect specific properties
141
const testObject = {
142
id: 1,
143
name: "Test",
144
tempData: "will be deleted",
145
cacheValue: "will be deleted"
146
};
147
148
// Protect only essential properties
149
protectProperties(testObject, ['id', 'name']);
150
deleteProperties(testObject);
151
152
// testObject now has: { id: 1, name: "Test" }
153
// tempData and cacheValue were deleted
154
155
// Protect all properties
156
const importantObject = { config: "value", settings: "data" };
157
protectProperties(importantObject); // Protects all properties
158
deleteProperties(importantObject); // Nothing gets deleted
159
160
// Recursive protection with depth control
161
const nestedObject = {
162
level1: {
163
level2: {
164
level3: {
165
data: "deep value"
166
}
167
},
168
otherData: "value"
169
},
170
topLevel: "value"
171
};
172
173
// Protect with depth 2 (default)
174
protectProperties(nestedObject);
175
// Protects: topLevel, level1, level1.level2, level1.otherData
176
// Does NOT protect: level1.level2.level3 (depth 3)
177
178
// Custom depth protection
179
protectProperties(nestedObject, [], 3);
180
// Protects all properties up to 3 levels deep
181
182
// Test fixture protection
183
function createProtectedTestFixture() {
184
const fixture = {
185
essentialData: { id: 1, name: "test" },
186
temporaryCache: new Map(),
187
disposableResults: []
188
};
189
190
// Protect essential data but allow cleanup of cache and results
191
protectProperties(fixture, ['essentialData']);
192
193
return fixture;
194
}
195
```
196
197
### Delete Properties
198
199
Deletes all non-protected properties from an object according to the current deletion mode.
200
201
```typescript { .api }
202
/**
203
* Deletes all non-protected properties from an object
204
* @param value - Object to delete properties from
205
* @remarks Respects protection settings and deletion mode
206
*/
207
function deleteProperties(value: unknown): void;
208
```
209
210
**Usage Examples:**
211
212
```typescript
213
import {
214
deleteProperties,
215
protectProperties,
216
initializeGarbageCollectionUtils
217
} from "jest-util";
218
219
// Basic cleanup
220
const testData = {
221
result: "value",
222
cache: new Map(),
223
temp: "temporary"
224
};
225
226
deleteProperties(testData);
227
// All properties deleted (assuming no protection)
228
229
// Selective cleanup with protection
230
const userSession = {
231
userId: 123,
232
sessionId: "abc-123",
233
tempData: { calculations: [1, 2, 3] },
234
cache: new WeakMap()
235
};
236
237
protectProperties(userSession, ['userId', 'sessionId']);
238
deleteProperties(userSession);
239
// Only tempData and cache are deleted
240
241
// Test isolation cleanup
242
function isolateTest(testEnvironment: any) {
243
// Protect test framework essentials
244
protectProperties(testEnvironment, [
245
'describe', 'it', 'expect', 'beforeEach', 'afterEach'
246
]);
247
248
// Clean up everything else from previous tests
249
deleteProperties(testEnvironment);
250
}
251
252
// Batch cleanup for test suites
253
function cleanupTestSuite(testObjects: any[]) {
254
testObjects.forEach(obj => {
255
if (canDeleteProperties(obj)) {
256
deleteProperties(obj);
257
}
258
});
259
}
260
261
// Memory leak prevention
262
function preventMemoryLeaks() {
263
const leakyObjects = [
264
globalThis.testCache,
265
globalThis.mockDatabase,
266
globalThis.temporaryHandlers
267
];
268
269
leakyObjects.forEach(obj => {
270
if (obj && canDeleteProperties(obj)) {
271
deleteProperties(obj);
272
}
273
});
274
}
275
```
276
277
**Deletion Mode Behavior:**
278
279
```typescript
280
// Different behaviors based on deletion mode
281
initializeGarbageCollectionUtils(globalThis, 'off');
282
deleteProperties(someObject); // No properties deleted
283
284
initializeGarbageCollectionUtils(globalThis, 'soft');
285
deleteProperties(someObject); // Properties wrapped with deprecation warnings
286
287
initializeGarbageCollectionUtils(globalThis, 'on');
288
deleteProperties(someObject); // Properties actually deleted
289
```
290
291
## Complete Workflow Example
292
293
```typescript
294
import {
295
initializeGarbageCollectionUtils,
296
protectProperties,
297
canDeleteProperties,
298
deleteProperties
299
} from "jest-util";
300
301
// 1. Initialize GC system
302
initializeGarbageCollectionUtils(globalThis, 'soft');
303
304
// 2. Create test environment
305
const testEnvironment = {
306
// Essential test framework functions
307
describe: globalThis.describe,
308
it: globalThis.it,
309
expect: globalThis.expect,
310
311
// Test data that should be cleaned up
312
testResults: [],
313
mockDatabase: new Map(),
314
temporaryFiles: [],
315
316
// Configuration that should persist
317
testConfig: { timeout: 5000, verbose: true }
318
};
319
320
// 3. Protect essential properties
321
protectProperties(testEnvironment, [
322
'describe', 'it', 'expect', 'testConfig'
323
]);
324
325
// 4. Run tests (test data accumulates)
326
// ... test execution ...
327
328
// 5. Clean up after test suite
329
if (canDeleteProperties(testEnvironment)) {
330
deleteProperties(testEnvironment);
331
// Only testResults, mockDatabase, temporaryFiles are deleted
332
// describe, it, expect, testConfig remain intact
333
}
334
335
// 6. Verify cleanup
336
console.log(testEnvironment);
337
// {
338
// describe: [Function],
339
// it: [Function],
340
// expect: [Function],
341
// testConfig: { timeout: 5000, verbose: true }
342
// }
343
```
344
345
## Performance Considerations
346
347
- **Protection Overhead**: Property protection adds metadata tracking - use sparingly for large objects
348
- **Deletion Modes**: 'soft' mode has higher overhead due to wrapper functions
349
- **Recursive Protection**: Deep protection can be expensive - limit depth for large nested objects
350
- **Memory Usage**: Protected properties consume additional memory for tracking metadata
351
352
## Integration with Jest
353
354
```typescript
355
// Jest test environment setup
356
export default class CustomTestEnvironment {
357
async setup() {
358
// Initialize GC with soft mode for development
359
initializeGarbageCollectionUtils(this.global, 'soft');
360
361
// Protect Jest globals
362
protectProperties(this.global, [
363
'describe', 'it', 'test', 'expect',
364
'beforeEach', 'afterEach', 'beforeAll', 'afterAll'
365
]);
366
}
367
368
async teardown() {
369
// Clean up test artifacts while preserving Jest globals
370
if (canDeleteProperties(this.global)) {
371
deleteProperties(this.global);
372
}
373
}
374
}
375
```