Skip to content

Commit fd01fb5

Browse files
committed
tests: improve tests
1 parent e46e8c6 commit fd01fb5

File tree

20 files changed

+643
-468
lines changed

20 files changed

+643
-468
lines changed
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
import type { AsyncStorage } from "@react-native-async-storage/async-storage";
2+
import { type TestRunner, useTests } from "../useTests";
3+
4+
export function useBasicTest(storage: AsyncStorage): TestRunner {
5+
const test = useTests();
6+
7+
const testSingles = async () => {
8+
try {
9+
test.clear();
10+
await storage.clear();
11+
const key = "single-set";
12+
let value = `value-${Math.round(Math.random() * 1000)}`;
13+
test.assert(
14+
undefined,
15+
await storage.setItem(key, value),
16+
`saved ${key} with value ${value}`
17+
);
18+
test.assert(value, await storage.getItem(key), "retrieves stored value");
19+
20+
test.assert(
21+
undefined,
22+
await storage.removeItem(key),
23+
`removed ${key} from storage`
24+
);
25+
test.assert(
26+
null,
27+
await storage.getItem(key),
28+
`gets null for previously stored value`
29+
);
30+
31+
value = `value-${Math.round(Math.random() * 1000)}`;
32+
test.assert(
33+
undefined,
34+
await storage.setItem(key, value),
35+
`saved value for the key: ${value}`
36+
);
37+
test.assert(
38+
value,
39+
await storage.getItem(key),
40+
`reads ${value} for the key`
41+
);
42+
43+
value = `value-${Math.round(Math.random() * 1000)}`;
44+
test.assert(
45+
undefined,
46+
await storage.setItem(key, value),
47+
`overrides key with value: ${value}`
48+
);
49+
test.assert(
50+
value,
51+
await storage.getItem(key),
52+
`successfully overridden the value`
53+
);
54+
} catch (e) {
55+
test.report(e);
56+
}
57+
};
58+
59+
const testMultiplies = async () => {
60+
try {
61+
test.clear();
62+
await storage.clear();
63+
const entry1 = { key1: "value1" };
64+
const entry2 = { key2: "value2" };
65+
const entry3 = { key3: "value3" };
66+
67+
const entries = { ...entry1, ...entry2, ...entry3 };
68+
test.assert(
69+
undefined,
70+
await storage.setMany(entries),
71+
"sets multiple entries"
72+
);
73+
74+
test.assert(
75+
entries,
76+
await storage.getMany(["key1", "key2", "key3"]),
77+
"reads stored values"
78+
);
79+
80+
test.assert(
81+
undefined,
82+
await storage.removeMany(["key1", "key2"]),
83+
"removed key1 and key2"
84+
);
85+
test.assert(
86+
["key3"],
87+
await storage.getAllKeys(),
88+
"only key3 remains after removal"
89+
);
90+
91+
const afterRemove = await storage.getMany(["key1", "key2", "key3"]);
92+
test.assert(
93+
{ key1: null, key2: null, key3: "value3" },
94+
afterRemove,
95+
"reads all requested values"
96+
);
97+
98+
test.assert(
99+
undefined,
100+
await storage.setMany(entries),
101+
"sets multiple entries again"
102+
);
103+
test.assert(
104+
entries,
105+
await storage.getMany(["key1", "key2", "key3"]),
106+
"checked stored values"
107+
);
108+
109+
const overridden = {
110+
key1: "new-value-1",
111+
key2: "new-value-2",
112+
key3: "new-value-3",
113+
};
114+
test.assert(
115+
undefined,
116+
await storage.setMany(overridden),
117+
"overriding stored entries"
118+
);
119+
test.assert(
120+
overridden,
121+
await storage.getMany(["key1", "key2", "key3"]),
122+
"confirms overriden values"
123+
);
124+
} catch (e) {
125+
test.report(e);
126+
}
127+
};
128+
129+
const testClearingStorage = async () => {
130+
try {
131+
test.clear();
132+
await storage.clear();
133+
test.assert([], await storage.getAllKeys(), "confirms empty storage");
134+
135+
test.assert(
136+
undefined,
137+
await storage.setItem("i should be here", "my item"),
138+
"stores single value"
139+
);
140+
test.assert(
141+
["i should be here"],
142+
await storage.getAllKeys(),
143+
"reads the single value"
144+
);
145+
test.assert(undefined, await storage.clear(), "clears all storage");
146+
test.assert(
147+
[],
148+
await storage.getAllKeys(),
149+
"confirms single key is gone"
150+
);
151+
152+
test.assert(
153+
undefined,
154+
await storage.setMany({
155+
newKey1: "heheh",
156+
"other-key": "123",
157+
heheh: "324",
158+
}),
159+
"stores multiple values"
160+
);
161+
test.assert(
162+
["newKey1", "other-key", "heheh"].sort(),
163+
(await storage.getAllKeys()).sort(),
164+
"confirms values are there"
165+
);
166+
test.assert(undefined, await storage.clear(), "clears all storage");
167+
test.assert([], await storage.getAllKeys(), "confirms entries are gone");
168+
} catch (e) {
169+
test.report(e);
170+
}
171+
};
172+
173+
const testEdgeCases = async () => {
174+
try {
175+
test.clear();
176+
await storage.clear();
177+
test.assert([], await storage.getAllKeys(), "confirms storage is empty");
178+
test.assert(
179+
undefined,
180+
await storage.removeMany(["missing1", "missing2"]),
181+
"gracefully handles removing of non-existing keys"
182+
);
183+
test.assert(
184+
[],
185+
await storage.getAllKeys(),
186+
"confirmed no keys are stored"
187+
);
188+
189+
test.assert(
190+
undefined,
191+
await storage.setItem("item1", ""),
192+
"stores an empty string"
193+
);
194+
test.assert(
195+
"",
196+
await storage.getItem("item1"),
197+
"confirms empty string is saved"
198+
);
199+
} catch (e) {
200+
test.report(e);
201+
}
202+
};
203+
204+
const testConcurrentSetAndGet = async () => {
205+
try {
206+
test.clear();
207+
await storage.clear();
208+
209+
const key1 = "concurrent1";
210+
const key2 = "concurrent2";
211+
const key3 = "concurrent3";
212+
const key4 = "concurrent4";
213+
const key5 = "concurrent5";
214+
215+
test.info("Setting multiple keys concurrently");
216+
await Promise.all([
217+
storage.setItem(key1, key1),
218+
storage.setItem(key2, key2),
219+
storage.setItem(key3, key3),
220+
storage.setItem(key4, key4),
221+
storage.setItem(key5, key5),
222+
]);
223+
224+
const values = await storage.getMany([key1, key2, key3, key4, key5]);
225+
test.assert(
226+
{
227+
[key1]: key1,
228+
[key2]: key2,
229+
[key3]: key3,
230+
[key4]: key4,
231+
[key5]: key5,
232+
},
233+
values,
234+
"Concurrent set/get works"
235+
);
236+
} catch (e) {
237+
test.report(e);
238+
}
239+
};
240+
241+
return {
242+
logs: test.logs,
243+
clearLogs: test.clear,
244+
tests: [
245+
{
246+
name: "Single crud",
247+
run: testSingles,
248+
},
249+
{
250+
name: "Multi crud",
251+
run: testMultiplies,
252+
},
253+
{
254+
name: "Storage clearance",
255+
run: testClearingStorage,
256+
},
257+
{
258+
name: "Edge cases?",
259+
run: testEdgeCases,
260+
},
261+
{
262+
name: "Concurrency",
263+
run: testConcurrentSetAndGet,
264+
},
265+
],
266+
};
267+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import type { AsyncStorage } from "@react-native-async-storage/async-storage";
2+
import { type TestRunner, useTests } from "../useTests";
3+
4+
export function usePerformanceTest(storage: AsyncStorage): TestRunner {
5+
const tests = useTests();
6+
7+
const testSavingBigData = async () => {
8+
try {
9+
tests.clear();
10+
const key = "big-data";
11+
const data = JSON.stringify(new Array(500_000).fill("a"));
12+
tests.info(`Saving ${key} with data size ${data.length}`);
13+
const timeNow = +Date.now();
14+
await storage.setItem(key, data);
15+
tests.info(`saving took ${+Date.now() - timeNow}ms`);
16+
17+
tests.info(`reading ${key}`);
18+
const res = await storage.getItem(key);
19+
tests.assert(res?.length, data.length, "restored data is same size");
20+
} catch (e) {
21+
tests.report(e);
22+
}
23+
};
24+
25+
const testLargeNumberOfKeys = async () => {
26+
try {
27+
tests.clear();
28+
await storage.clear();
29+
30+
const entries: Record<string, string> = {};
31+
for (let i = 0; i < 1000; i++) {
32+
entries[`key-${i}`] = `value-${i}`;
33+
}
34+
35+
tests.info("Saving 1000 keys at once");
36+
const timeNow = +Date.now();
37+
await storage.setMany(entries);
38+
tests.info(`saving took ${+Date.now() - timeNow}ms`);
39+
40+
const keys = await storage.getAllKeys();
41+
tests.assert(
42+
Object.keys(entries).sort(),
43+
keys.sort(),
44+
"All keys are stored"
45+
);
46+
47+
const fetched = await storage.getMany(Object.keys(entries));
48+
tests.assert(entries, fetched, "All values match");
49+
} catch (e) {
50+
tests.report(e);
51+
}
52+
};
53+
54+
return {
55+
logs: tests.logs,
56+
clearLogs: tests.clear,
57+
tests: [
58+
{
59+
name: "Big data set",
60+
run: testSavingBigData,
61+
},
62+
{
63+
name: "Large number of keys",
64+
run: testLargeNumberOfKeys,
65+
},
66+
],
67+
};
68+
}

examples/common-tests/src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
export { useBasicTest } from "./tests/BasicTests";
1+
export { useBasicTest } from "./cases/basic";
2+
export { usePerformanceTest } from "./cases/performance";
3+
export type { TestRunner } from "./useTests";
4+
export { useTestStorage } from "./useTestStorage";

0 commit comments

Comments
 (0)