Skip to content

Commit f3d08d0

Browse files
CopilotneSpecc
andcommitted
Implement dot notation for nested objects in backtrace frame arguments
Co-authored-by: neSpecc <3684889+neSpecc@users.noreply.github.com>
1 parent ed1d375 commit f3d08d0

11 files changed

+576
-247
lines changed

lib/memoize/index.test.ts

Lines changed: 95 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,16 @@ describe('memoize decorator — per-test inline classes', () => {
2020
});
2121

2222
it('should memoize return value with concat strategy across several calls', async () => {
23+
/**
24+
*
25+
*/
2326
class Sample {
2427
public calls = 0;
2528

29+
/**
30+
* @param a
31+
* @param b
32+
*/
2633
@memoize({ strategy: 'concat', ttl: 60_000, max: 50 })
2734
public async run(a: number, b: string) {
2835
this.calls += 1;
@@ -47,9 +54,16 @@ describe('memoize decorator — per-test inline classes', () => {
4754
});
4855

4956
it('should memoize return value with set of arguments with concat strategy across several calls', async () => {
57+
/**
58+
*
59+
*/
5060
class Sample {
5161
public calls = 0;
5262

63+
/**
64+
* @param a
65+
* @param b
66+
*/
5367
@memoize({ strategy: 'concat' })
5468
public async run(a: unknown, b: unknown) {
5569
this.calls += 1;
@@ -84,9 +98,16 @@ describe('memoize decorator — per-test inline classes', () => {
8498
});
8599

86100
it('should memoize return value for stringified objects across several calls', async () => {
101+
/**
102+
*
103+
*/
87104
class Sample {
88105
public calls = 0;
89106

107+
/**
108+
* @param x
109+
* @param y
110+
*/
90111
@memoize({ strategy: 'concat' })
91112
public async run(x: unknown, y: unknown) {
92113
this.calls += 1;
@@ -105,9 +126,15 @@ describe('memoize decorator — per-test inline classes', () => {
105126
});
106127

107128
it('should memoize return value for method with non-default arguments (NaN, Infinity, -0, Symbol, Date, RegExp) still cache same-args', async () => {
129+
/**
130+
*
131+
*/
108132
class Sample {
109133
public calls = 0;
110134

135+
/**
136+
* @param {...any} args
137+
*/
111138
@memoize({ strategy: 'concat' })
112139
public async run(...args: unknown[]) {
113140
this.calls += 1;
@@ -131,9 +158,15 @@ describe('memoize decorator — per-test inline classes', () => {
131158
it('should call crypto hash with blake2b512 algo and base64url digest, should memoize return value with hash strategy', async () => {
132159
const hashSpy = jest.spyOn(Crypto, 'hash');
133160

161+
/**
162+
*
163+
*/
134164
class Sample {
135165
public calls = 0;
136166

167+
/**
168+
* @param {...any} args
169+
*/
137170
@memoize({ strategy: 'hash' })
138171
public async run(...args: unknown[]) {
139172
this.calls += 1;
@@ -151,9 +184,15 @@ describe('memoize decorator — per-test inline classes', () => {
151184
});
152185

153186
it('should not memoize return value with hash strategy and different arguments', async () => {
187+
/**
188+
*
189+
*/
154190
class Sample {
155191
public calls = 0;
156192

193+
/**
194+
* @param {...any} args
195+
*/
157196
@memoize({ strategy: 'hash' })
158197
public async run(...args: unknown[]) {
159198
this.calls += 1;
@@ -171,9 +210,15 @@ describe('memoize decorator — per-test inline classes', () => {
171210
});
172211

173212
it('should memoize return value with hash strategy across several calls with same args', async () => {
213+
/**
214+
*
215+
*/
174216
class Sample {
175217
public calls = 0;
176218

219+
/**
220+
* @param arg
221+
*/
177222
@memoize({ strategy: 'hash' })
178223
public async run(arg: unknown) {
179224
this.calls += 1;
@@ -196,9 +241,15 @@ describe('memoize decorator — per-test inline classes', () => {
196241

197242
const { memoize: memoizeWithMockedTimers } = await import('../memoize/index');
198243

244+
/**
245+
*
246+
*/
199247
class Sample {
200248
public calls = 0;
201249

250+
/**
251+
* @param x
252+
*/
202253
@memoizeWithMockedTimers({ strategy: 'concat', ttl: 1_000 })
203254
public async run(x: string) {
204255
this.calls += 1;
@@ -221,9 +272,15 @@ describe('memoize decorator — per-test inline classes', () => {
221272
});
222273

223274
it('error calls should never be momized', async () => {
275+
/**
276+
*
277+
*/
224278
class Sample {
225279
public calls = 0;
226280

281+
/**
282+
* @param x
283+
*/
227284
@memoize()
228285
public async run(x: number) {
229286
this.calls += 1;
@@ -245,9 +302,15 @@ describe('memoize decorator — per-test inline classes', () => {
245302
});
246303

247304
it('should NOT cache results listed in skipCache (primitives)', async () => {
305+
/**
306+
*
307+
*/
248308
class Sample {
249309
public calls = 0;
250-
310+
311+
/**
312+
* @param kind
313+
*/
251314
@memoize({ strategy: 'concat', skipCache: [null, undefined, 0, false, ''] })
252315
public async run(kind: 'null' | 'undef' | 'zero' | 'false' | 'empty') {
253316
this.calls += 1;
@@ -260,68 +323,81 @@ describe('memoize decorator — per-test inline classes', () => {
260323
}
261324
}
262325
}
263-
326+
264327
const sample = new Sample();
265-
328+
266329
// Each repeated call should invoke the original again because result is in skipCache.
267330
await sample.run('null');
268331
await sample.run('null');
269-
332+
270333
await sample.run('undef');
271334
await sample.run('undef');
272-
335+
273336
await sample.run('zero');
274337
await sample.run('zero');
275-
338+
276339
await sample.run('false');
277340
await sample.run('false');
278-
341+
279342
await sample.run('empty');
280343
await sample.run('empty');
281-
344+
282345
// 5 kinds × 2 calls each = 10 calls, none cached
283346
expect(sample.calls).toBe(10);
284347
});
285-
348+
286349
it('should cache results NOT listed in skipCache', async () => {
350+
/**
351+
*
352+
*/
287353
class Sample {
288354
public calls = 0;
289-
355+
356+
/**
357+
* @param x
358+
*/
290359
@memoize({ strategy: 'concat', skipCache: [null, undefined] })
291360
public async run(x: number) {
292361
this.calls += 1;
362+
293363
// returns a non-skipped primitive
294364
return x * 2;
295365
}
296366
}
297-
367+
298368
const sample = new Sample();
299-
369+
300370
expect(await sample.run(21)).toBe(42);
301371
expect(await sample.run(21)).toBe(42);
302-
372+
303373
expect(sample.calls).toBe(1);
304374
});
305-
375+
306376
it('should use equality for skipCache with objects: deep equal objects are cached', async () => {
307377
const deepEqualObject = { a: 1 };
308-
378+
379+
/**
380+
*
381+
*/
309382
class Sample {
310383
public calls = 0;
311-
384+
385+
/**
386+
*
387+
*/
312388
@memoize({ strategy: 'concat', skipCache: [deepEqualObject] })
313389
public async run() {
314390
this.calls += 1;
315391

316392
return { a: 1 };
317393
}
318394
}
319-
395+
320396
const sample = new Sample();
321-
397+
322398
const first = await sample.run();
323399
const second = await sample.run();
324-
400+
325401
expect(first).toEqual({ a: 1 });
326402
expect(second).toBe(first);
327403
expect(sample.calls).toBe(1);

lib/utils/payday.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ const resetMockedNow = (): void => {
1717

1818
// Override Date constructor
1919
const RealDate = Date;
20+
2021
global.Date = class extends RealDate {
2122
/**
2223
* Constructor for mocked Date class
24+
*
2325
* @param args - arguments passed to Date constructor
2426
*/
2527
constructor(...args: unknown[]) {
@@ -30,6 +32,9 @@ global.Date = class extends RealDate {
3032
}
3133
}
3234

35+
/**
36+
*
37+
*/
3338
public static now(): number {
3439
return mockedNow !== null ? mockedNow : RealDate.now();
3540
}

0 commit comments

Comments
 (0)