0
# Data Manipulation
1
2
Utilities for copying, transforming, and manipulating data structures commonly used in test scenarios. These functions provide safe and reliable data operations that handle edge cases like circular references and complex object structures.
3
4
## Capabilities
5
6
### Deep Cyclic Copy
7
8
Creates a deep copy of objects while safely handling circular references, with configurable options for property filtering and prototype preservation.
9
10
```typescript { .api }
11
/**
12
* Deep copies objects while handling circular references
13
* @param value - Value to copy
14
* @param options - Copy options for customizing behavior
15
* @param cycles - Internal cycle tracking (used recursively)
16
* @returns Deep copy of the input value
17
*/
18
function deepCyclicCopy<T>(
19
value: T,
20
options?: DeepCyclicCopyOptions,
21
cycles?: WeakMap<any, any>
22
): T;
23
24
interface DeepCyclicCopyOptions {
25
/** Property names to skip during copying */
26
blacklist?: Set<string>;
27
/** Whether to preserve prototype chain */
28
keepPrototype?: boolean;
29
}
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { deepCyclicCopy } from "jest-util";
36
37
// Basic deep copying
38
const original = {
39
user: { name: "Alice", age: 30 },
40
settings: { theme: "dark", notifications: true },
41
data: [1, 2, { nested: "value" }]
42
};
43
44
const copy = deepCyclicCopy(original);
45
copy.user.name = "Bob"; // original.user.name remains "Alice"
46
47
// Handling circular references safely
48
const circularObj: any = { name: "test" };
49
circularObj.self = circularObj; // Creates circular reference
50
51
const safeCopy = deepCyclicCopy(circularObj);
52
console.log(safeCopy.self === safeCopy); // true - circular reference preserved
53
54
// Using blacklist to skip sensitive properties
55
const sensitiveData = {
56
publicInfo: { name: "Alice" },
57
password: "secret123",
58
token: "jwt-token-here",
59
internalId: "internal-use-only"
60
};
61
62
const publicCopy = deepCyclicCopy(sensitiveData, {
63
blacklist: new Set(["password", "token", "internalId"])
64
});
65
// publicCopy only contains publicInfo
66
67
// Preserving prototype chain
68
class TestClass {
69
method() { return "test"; }
70
}
71
const instance = new TestClass();
72
instance.data = { value: 42 };
73
74
const copyWithPrototype = deepCyclicCopy(instance, { keepPrototype: true });
75
console.log(copyWithPrototype instanceof TestClass); // true
76
console.log(copyWithPrototype.method()); // "test"
77
78
const copyWithoutPrototype = deepCyclicCopy(instance, { keepPrototype: false });
79
console.log(copyWithoutPrototype instanceof TestClass); // false
80
```
81
82
**Advanced Usage:**
83
84
```typescript
85
// Test fixture preparation
86
function createTestFixture() {
87
const baseData = {
88
users: [
89
{ id: 1, name: "Alice", posts: [] },
90
{ id: 2, name: "Bob", posts: [] }
91
],
92
metadata: { version: "1.0", timestamp: Date.now() }
93
};
94
95
// Create circular references for realistic data
96
baseData.users[0].posts.push({ author: baseData.users[0], content: "Hello" });
97
98
return baseData;
99
}
100
101
// Each test gets an independent copy
102
test("user modification", () => {
103
const testData = deepCyclicCopy(createTestFixture());
104
testData.users[0].name = "Charlie";
105
// Original fixture remains unchanged
106
});
107
108
// Mock object preparation with prototype preservation
109
class DatabaseConnection {
110
query(sql: string) { return []; }
111
close() { }
112
}
113
114
const mockConnection = deepCyclicCopy(new DatabaseConnection(), {
115
keepPrototype: true
116
});
117
// mockConnection retains DatabaseConnection methods
118
```
119
120
### Convert Descriptor To String
121
122
Converts various descriptor types (functions, numbers, strings) to their string representation, commonly used for test output and error messages.
123
124
```typescript { .api }
125
/**
126
* Converts various descriptor types to string representation
127
* @param descriptor - Function, number, string, or undefined to convert
128
* @returns String representation of the descriptor
129
* @throws Error for invalid descriptor types
130
*/
131
function convertDescriptorToString(
132
descriptor: Global.BlockNameLike | undefined
133
): string;
134
```
135
136
**Usage Examples:**
137
138
```typescript
139
import { convertDescriptorToString } from "jest-util";
140
141
// Function descriptors
142
function testFunction() { return "test"; }
143
console.log(convertDescriptorToString(testFunction)); // "testFunction"
144
145
const anonymousFunction = () => {};
146
console.log(convertDescriptorToString(anonymousFunction)); // function name or "[anonymous]"
147
148
// String descriptors
149
console.log(convertDescriptorToString("test suite")); // "test suite"
150
console.log(convertDescriptorToString("")); // ""
151
152
// Number descriptors
153
console.log(convertDescriptorToString(42)); // "42"
154
console.log(convertDescriptorToString(0)); // "0"
155
156
// Undefined descriptor
157
console.log(convertDescriptorToString(undefined)); // ""
158
159
// Jest test context usage
160
function describeTestBlock(descriptor: Global.BlockNameLike | undefined) {
161
const name = convertDescriptorToString(descriptor);
162
console.log(`Running test block: ${name || "unnamed"}`);
163
}
164
165
// Test suite generation
166
const testSuites = [
167
testFunction,
168
"Integration Tests",
169
42, // Test group number
170
undefined
171
];
172
173
testSuites.forEach(suite => {
174
const suiteName = convertDescriptorToString(suite);
175
console.log(`Test Suite: ${suiteName}`);
176
});
177
```
178
179
**Error Handling:**
180
181
```typescript
182
// Invalid descriptor types throw errors
183
try {
184
convertDescriptorToString({}); // Object is not a valid descriptor
185
} catch (error) {
186
console.log("Invalid descriptor type");
187
}
188
189
try {
190
convertDescriptorToString([]); // Array is not a valid descriptor
191
} catch (error) {
192
console.log("Invalid descriptor type");
193
}
194
```
195
196
## Types
197
198
```typescript { .api }
199
interface DeepCyclicCopyOptions {
200
/** Property names to skip during copying */
201
blacklist?: Set<string>;
202
/** Whether to preserve prototype chain */
203
keepPrototype?: boolean;
204
}
205
206
// From @jest/types
207
type Global.BlockNameLike = string | number | Function | undefined;
208
```
209
210
**Performance Considerations:**
211
212
- **deepCyclicCopy**: Uses WeakMap for cycle detection, providing O(1) lookups
213
- **Blacklist checking**: Property filtering is optimized for large blacklists using Set
214
- **Prototype handling**: Prototype preservation adds minimal overhead when enabled
215
- **Memory usage**: Circular reference tracking scales with object complexity