Skip to content

Commit d03d6f0

Browse files
authored
Add type parameters to all loaders in test (#218)
1 parent 2219c1d commit d03d6f0

File tree

2 files changed

+44
-36
lines changed

2 files changed

+44
-36
lines changed

src/__tests__/abuse.test.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ describe('Provides descriptive error messages for API abuse', () => {
3030
});
3131

3232
it('Load function requires an key', () => {
33-
const idLoader = new DataLoader(keys => Promise.resolve(keys));
33+
const idLoader = new DataLoader<number, number>(async keys => keys);
3434

3535
expect(() => {
36+
// $FlowExpectError
3637
idLoader.load();
3738
}).toThrow(
3839
'The loader.load() function must be called with a value,' +
3940
'but got: undefined.'
4041
);
4142

4243
expect(() => {
44+
// $FlowExpectError
4345
idLoader.load(null);
4446
}).toThrow(
4547
'The loader.load() function must be called with a value,' +
@@ -53,7 +55,7 @@ describe('Provides descriptive error messages for API abuse', () => {
5355
});
5456

5557
it('LoadMany function requires a list of key', () => {
56-
const idLoader = new DataLoader(keys => Promise.resolve(keys));
58+
const idLoader = new DataLoader<number, number>(async keys => keys);
5759

5860
expect(() => {
5961
// $FlowExpectError
@@ -79,7 +81,7 @@ describe('Provides descriptive error messages for API abuse', () => {
7981

8082
it('Batch function must return a Promise, not null', async () => {
8183
// $FlowExpectError
82-
const badLoader = new DataLoader(() => null);
84+
const badLoader = new DataLoader<number, number>(() => null);
8385

8486
let caughtError;
8587
try {
@@ -98,7 +100,7 @@ describe('Provides descriptive error messages for API abuse', () => {
98100
it('Batch function must return a Promise, not a value', async () => {
99101
// Note: this is returning the keys directly, rather than a promise to keys.
100102
// $FlowExpectError
101-
const badLoader = new DataLoader(keys => keys);
103+
const badLoader = new DataLoader<number, number>(keys => keys);
102104

103105
let caughtError;
104106
try {
@@ -117,7 +119,7 @@ describe('Provides descriptive error messages for API abuse', () => {
117119
it('Batch function must return a Promise of an Array, not null', async () => {
118120
// Note: this resolves to undefined
119121
// $FlowExpectError
120-
const badLoader = new DataLoader(() => Promise.resolve(undefined));
122+
const badLoader = new DataLoader<number, number>(async () => null);
121123

122124
let caughtError;
123125
try {
@@ -129,13 +131,13 @@ describe('Provides descriptive error messages for API abuse', () => {
129131
expect((caughtError: any).message).toBe(
130132
'DataLoader must be constructed with a function which accepts ' +
131133
'Array<key> and returns Promise<Array<value>>, but the function did ' +
132-
'not return a Promise of an Array: undefined.'
134+
'not return a Promise of an Array: null.'
133135
);
134136
});
135137

136138
it('Batch function must promise an Array of correct length', async () => {
137139
// Note: this resolves to empty array
138-
const badLoader = new DataLoader(() => Promise.resolve([]));
140+
const badLoader = new DataLoader<number, number>(async () => []);
139141

140142
let caughtError;
141143
try {

src/__tests__/dataloader.test.js

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import type { Options } from '..';
1111
const DataLoader = require('..');
1212

13-
function idLoader<K, C>(
13+
function idLoader<K, C = K>(
1414
options?: Options<K, K, C>
1515
): [ DataLoader<K, K, C>, Array<$ReadOnlyArray<K>> ] {
1616
const loadCalls = [];
@@ -24,7 +24,7 @@ function idLoader<K, C>(
2424
describe('Primary API', () => {
2525

2626
it('builds a really really simple data loader', async () => {
27-
const identityLoader = new DataLoader(keys => Promise.resolve(keys));
27+
const identityLoader = new DataLoader<number, number>(async keys => keys);
2828

2929
const promise1 = identityLoader.load(1);
3030
expect(promise1).toBeInstanceOf(Promise);
@@ -35,7 +35,7 @@ describe('Primary API', () => {
3535

3636
it('references the loader as "this" in the batch function', async () => {
3737
let that;
38-
const loader = new DataLoader(async function (keys) {
38+
const loader = new DataLoader<number, number>(async function (keys) {
3939
that = this;
4040
return keys;
4141
});
@@ -47,7 +47,7 @@ describe('Primary API', () => {
4747
});
4848

4949
it('supports loading multiple keys in one call', async () => {
50-
const identityLoader = new DataLoader(keys => Promise.resolve(keys));
50+
const identityLoader = new DataLoader<number, number>(async keys => keys);
5151

5252
const promiseAll = identityLoader.loadMany([ 1, 2 ]);
5353
expect(promiseAll).toBeInstanceOf(Promise);
@@ -63,7 +63,7 @@ describe('Primary API', () => {
6363
});
6464

6565
it('batches multiple requests', async () => {
66-
const [ identityLoader, loadCalls ] = idLoader();
66+
const [ identityLoader, loadCalls ] = idLoader<number>();
6767

6868
const promise1 = identityLoader.load(1);
6969
const promise2 = identityLoader.load(2);
@@ -76,7 +76,7 @@ describe('Primary API', () => {
7676
});
7777

7878
it('batches multiple requests with max batch sizes', async () => {
79-
const [ identityLoader, loadCalls ] = idLoader({ maxBatchSize: 2 });
79+
const [ identityLoader, loadCalls ] = idLoader<number>({ maxBatchSize: 2 });
8080

8181
const promise1 = identityLoader.load(1);
8282
const promise2 = identityLoader.load(2);
@@ -92,7 +92,7 @@ describe('Primary API', () => {
9292
});
9393

9494
it('coalesces identical requests', async () => {
95-
const [ identityLoader, loadCalls ] = idLoader();
95+
const [ identityLoader, loadCalls ] = idLoader<number>();
9696

9797
const promise1a = identityLoader.load(1);
9898
const promise1b = identityLoader.load(1);
@@ -107,7 +107,7 @@ describe('Primary API', () => {
107107
});
108108

109109
it('caches repeated requests', async () => {
110-
const [ identityLoader, loadCalls ] = idLoader();
110+
const [ identityLoader, loadCalls ] = idLoader<string>();
111111

112112
const [ a, b ] = await Promise.all([
113113
identityLoader.load('A'),
@@ -143,7 +143,7 @@ describe('Primary API', () => {
143143
});
144144

145145
it('clears single value in loader', async () => {
146-
const [ identityLoader, loadCalls ] = idLoader();
146+
const [ identityLoader, loadCalls ] = idLoader<string>();
147147

148148
const [ a, b ] = await Promise.all([
149149
identityLoader.load('A'),
@@ -169,7 +169,7 @@ describe('Primary API', () => {
169169
});
170170

171171
it('clears all values in loader', async () => {
172-
const [ identityLoader, loadCalls ] = idLoader();
172+
const [ identityLoader, loadCalls ] = idLoader<string>();
173173

174174
const [ a, b ] = await Promise.all([
175175
identityLoader.load('A'),
@@ -195,7 +195,7 @@ describe('Primary API', () => {
195195
});
196196

197197
it('allows priming the cache', async () => {
198-
const [ identityLoader, loadCalls ] = idLoader();
198+
const [ identityLoader, loadCalls ] = idLoader<string>();
199199

200200
identityLoader.prime('A', 'A');
201201

@@ -211,7 +211,7 @@ describe('Primary API', () => {
211211
});
212212

213213
it('does not prime keys that already exist', async () => {
214-
const [ identityLoader, loadCalls ] = idLoader();
214+
const [ identityLoader, loadCalls ] = idLoader<string>();
215215

216216
identityLoader.prime('A', 'X');
217217

@@ -232,7 +232,7 @@ describe('Primary API', () => {
232232
});
233233

234234
it('allows forcefully priming the cache', async () => {
235-
const [ identityLoader, loadCalls ] = idLoader();
235+
const [ identityLoader, loadCalls ] = idLoader<string>();
236236

237237
identityLoader.prime('A', 'X');
238238

@@ -337,7 +337,7 @@ describe('Represents Errors', () => {
337337
});
338338

339339
it('Handles priming the cache with an error', async () => {
340-
const [ identityLoader, loadCalls ] = idLoader();
340+
const [ identityLoader, loadCalls ] = idLoader<number>();
341341

342342
identityLoader.prime(1, new Error('Error: 1'));
343343

@@ -427,7 +427,7 @@ describe('Represents Errors', () => {
427427
describe('Accepts any kind of key', () => {
428428

429429
it('Accepts objects as keys', async () => {
430-
const [ identityLoader, loadCalls ] = idLoader();
430+
const [ identityLoader, loadCalls ] = idLoader<{}>();
431431

432432
const keyA = {};
433433
const keyB = {};
@@ -471,7 +471,7 @@ describe('Accepts options', () => {
471471

472472
// Note: mirrors 'batches multiple requests' above.
473473
it('May disable batching', async () => {
474-
const [ identityLoader, loadCalls ] = idLoader({ batch: false });
474+
const [ identityLoader, loadCalls ] = idLoader<number>({ batch: false });
475475

476476
const promise1 = identityLoader.load(1);
477477
const promise2 = identityLoader.load(2);
@@ -485,7 +485,7 @@ describe('Accepts options', () => {
485485

486486
// Note: mirror's 'caches repeated requests' above.
487487
it('May disable caching', async () => {
488-
const [ identityLoader, loadCalls ] = idLoader({ cache: false });
488+
const [ identityLoader, loadCalls ] = idLoader<string>({ cache: false });
489489

490490
const [ a, b ] = await Promise.all([
491491
identityLoader.load('A'),
@@ -523,7 +523,7 @@ describe('Accepts options', () => {
523523
});
524524

525525
it('Keys are repeated in batch when cache disabled', async () => {
526-
const [ identityLoader, loadCalls ] = idLoader({ cache: false });
526+
const [ identityLoader, loadCalls ] = idLoader<string>({ cache: false });
527527

528528
const [ values1, values2, values3, values4 ] = await Promise.all([
529529
identityLoader.load('A'),
@@ -545,7 +545,7 @@ describe('Accepts options', () => {
545545
it('Does not interact with a cache when cache is disabled', () => {
546546
const promiseX = Promise.resolve('X');
547547
const cacheMap = new Map([ [ 'X', promiseX ] ]);
548-
const [ identityLoader ] = idLoader({ cache: false, cacheMap });
548+
const [ identityLoader ] = idLoader<string>({ cache: false, cacheMap });
549549

550550
identityLoader.prime('A', 'A');
551551
expect(cacheMap.get('A')).toBe(undefined);
@@ -558,7 +558,7 @@ describe('Accepts options', () => {
558558
it('Complex cache behavior via clearAll()', async () => {
559559
// This loader clears its cache as soon as a batch function is dispatched.
560560
const loadCalls = [];
561-
const identityLoader = new DataLoader(keys => {
561+
const identityLoader = new DataLoader<string, string>(keys => {
562562
identityLoader.clearAll();
563563
loadCalls.push(keys);
564564
return Promise.resolve(keys);
@@ -588,9 +588,11 @@ describe('Accepts options', () => {
588588
return Object.keys(key).sort().map(k => k + ':' + key[k]).join();
589589
}
590590

591+
type Obj = { [string]: number };
592+
591593
it('Accepts objects with a complex key', async () => {
592594
const identityLoadCalls = [];
593-
const identityLoader = new DataLoader(keys => {
595+
const identityLoader = new DataLoader<Obj, Obj, string>(keys => {
594596
identityLoadCalls.push(keys);
595597
return Promise.resolve(keys);
596598
}, { cacheKeyFn: cacheKey });
@@ -608,7 +610,7 @@ describe('Accepts options', () => {
608610

609611
it('Clears objects with complex key', async () => {
610612
const identityLoadCalls = [];
611-
const identityLoader = new DataLoader(keys => {
613+
const identityLoader = new DataLoader<Obj, Obj, string>(keys => {
612614
identityLoadCalls.push(keys);
613615
return Promise.resolve(keys);
614616
}, { cacheKeyFn: cacheKey });
@@ -627,7 +629,7 @@ describe('Accepts options', () => {
627629

628630
it('Accepts objects with different order of keys', async () => {
629631
const identityLoadCalls = [];
630-
const identityLoader = new DataLoader(keys => {
632+
const identityLoader = new DataLoader<Obj, Obj, string>(keys => {
631633
identityLoadCalls.push(keys);
632634
return Promise.resolve(keys);
633635
}, { cacheKeyFn: cacheKey });
@@ -651,7 +653,8 @@ describe('Accepts options', () => {
651653
});
652654

653655
it('Allows priming the cache with an object key', async () => {
654-
const [ identityLoader, loadCalls ] = idLoader({ cacheKeyFn: cacheKey });
656+
const [ identityLoader, loadCalls ] =
657+
idLoader<Obj, string>({ cacheKeyFn: cacheKey });
655658

656659
const key1 = { id: 123 };
657660
const key2 = { id: 123 };
@@ -693,7 +696,7 @@ describe('Accepts options', () => {
693696
it('Accepts a custom cache map implementation', async () => {
694697
const aCustomMap = new SimpleMap();
695698
const identityLoadCalls = [];
696-
const identityLoader = new DataLoader(keys => {
699+
const identityLoader = new DataLoader<string, string>(keys => {
697700
identityLoadCalls.push(keys);
698701
return Promise.resolve(keys);
699702
}, { cacheMap: aCustomMap });
@@ -747,7 +750,7 @@ describe('Accepts options', () => {
747750
describe('It is resilient to job queue ordering', () => {
748751

749752
it('batches loads occuring within promises', async () => {
750-
const [ identityLoader, loadCalls ] = idLoader();
753+
const [ identityLoader, loadCalls ] = idLoader<string>();
751754

752755
await Promise.all([
753756
identityLoader.load('A'),
@@ -767,19 +770,22 @@ describe('It is resilient to job queue ordering', () => {
767770

768771
it('can call a loader from a loader', async () => {
769772
const deepLoadCalls = [];
770-
const deepLoader = new DataLoader(keys => {
773+
const deepLoader = new DataLoader<
774+
$ReadOnlyArray<string>,
775+
$ReadOnlyArray<string>
776+
>(keys => {
771777
deepLoadCalls.push(keys);
772778
return Promise.resolve(keys);
773779
});
774780

775781
const aLoadCalls = [];
776-
const aLoader = new DataLoader(keys => {
782+
const aLoader = new DataLoader<string, string>(keys => {
777783
aLoadCalls.push(keys);
778784
return deepLoader.load(keys);
779785
});
780786

781787
const bLoadCalls = [];
782-
const bLoader = new DataLoader(keys => {
788+
const bLoader = new DataLoader<string, string>(keys => {
783789
bLoadCalls.push(keys);
784790
return deepLoader.load(keys);
785791
});

0 commit comments

Comments
 (0)