Skip to content

Commit 3ef7559

Browse files
test: update localStorage tests for type-safe encoding
Update all localStorage collection tests to match the new type-safe key encoding format that prevents collisions between numeric and string IDs. Changes: - Update test assertions to use encoded keys ("s:1" for string "1") - Update test data setup to use encoded keys in storage - Fix verifyConsistency helper to decode storage keys properly - All 17 failing tests now correctly expect the encoded format Co-authored-by: Kevin <kevin-dp@users.noreply.github.com>
1 parent cdabdc5 commit 3ef7559

File tree

1 file changed

+49
-41
lines changed

1 file changed

+49
-41
lines changed

packages/db/tests/local-storage.test.ts

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -206,17 +206,17 @@ describe(`localStorage collection`, () => {
206206
storedData!
207207
)
208208

209-
expect(parsed[`1`]?.data.title).toBe(`superjson`)
210-
expect(parsed[`1`]?.data.completed).toBe(false)
211-
expect(parsed[`1`]?.data.createdAt).toBeInstanceOf(Date)
209+
expect(parsed[`s:1`]?.data.title).toBe(`superjson`)
210+
expect(parsed[`s:1`]?.data.completed).toBe(false)
211+
expect(parsed[`s:1`]?.data.createdAt).toBeInstanceOf(Date)
212212
})
213213
})
214214

215215
describe(`data persistence`, () => {
216216
it(`should load existing data from storage on initialization`, () => {
217217
// Pre-populate storage with new versioned format
218218
const existingTodos = {
219-
"1": {
219+
"s:1": {
220220
versionKey: `test-version-1`,
221221
data: {
222222
id: `1`,
@@ -310,7 +310,7 @@ describe(`localStorage collection`, () => {
310310
let storedData = mockStorage.getItem(`todos`)
311311
expect(storedData).toBeDefined()
312312
let parsed = JSON.parse(storedData!)
313-
expect(parsed[`1`].data.title).toBe(`Test Todo Without Handlers`)
313+
expect(parsed[`s:1`].data.title).toBe(`Test Todo Without Handlers`)
314314

315315
// Update without handlers should still persist
316316
const updateTx = collection.update(`1`, (draft) => {
@@ -322,7 +322,7 @@ describe(`localStorage collection`, () => {
322322
storedData = mockStorage.getItem(`todos`)
323323
expect(storedData).toBeDefined()
324324
parsed = JSON.parse(storedData!)
325-
expect(parsed[`1`].data.title).toBe(`Updated Without Handlers`)
325+
expect(parsed[`s:1`].data.title).toBe(`Updated Without Handlers`)
326326

327327
// Delete without handlers should still persist
328328
const deleteTx = collection.delete(`1`)
@@ -332,7 +332,7 @@ describe(`localStorage collection`, () => {
332332
storedData = mockStorage.getItem(`todos`)
333333
expect(storedData).toBeDefined()
334334
parsed = JSON.parse(storedData!)
335-
expect(parsed[`1`]).toBeUndefined()
335+
expect(parsed[`s:1`]).toBeUndefined()
336336

337337
subscription.unsubscribe()
338338
})
@@ -372,7 +372,7 @@ describe(`localStorage collection`, () => {
372372
let storedData = mockStorage.getItem(`todos`)
373373
expect(storedData).toBeDefined()
374374
let parsed = JSON.parse(storedData!)
375-
expect(parsed[`1`].data.title).toBe(`Test Todo With Handlers`)
375+
expect(parsed[`s:1`].data.title).toBe(`Test Todo With Handlers`)
376376

377377
// Update should call handler AND persist
378378
const updateTx = collection.update(`1`, (draft) => {
@@ -384,7 +384,7 @@ describe(`localStorage collection`, () => {
384384
storedData = mockStorage.getItem(`todos`)
385385
expect(storedData).toBeDefined()
386386
parsed = JSON.parse(storedData!)
387-
expect(parsed[`1`].data.title).toBe(`Updated With Handlers`)
387+
expect(parsed[`s:1`].data.title).toBe(`Updated With Handlers`)
388388

389389
// Delete should call handler AND persist
390390
const deleteTx = collection.delete(`1`)
@@ -394,7 +394,7 @@ describe(`localStorage collection`, () => {
394394
storedData = mockStorage.getItem(`todos`)
395395
expect(storedData).toBeDefined()
396396
parsed = JSON.parse(storedData!)
397-
expect(parsed[`1`]).toBeUndefined()
397+
expect(parsed[`s:1`]).toBeUndefined()
398398

399399
subscription.unsubscribe()
400400
})
@@ -428,17 +428,17 @@ describe(`localStorage collection`, () => {
428428

429429
const parsed = JSON.parse(storedData!)
430430
expect(typeof parsed).toBe(`object`)
431-
expect(parsed[`1`]).toBeDefined()
432-
expect(parsed[`1`].versionKey).toBeDefined()
433-
expect(typeof parsed[`1`].versionKey).toBe(`string`)
434-
expect(parsed[`1`].data.id).toBe(`1`)
435-
expect(parsed[`1`].data.title).toBe(`Test Todo`)
431+
expect(parsed[`s:1`]).toBeDefined()
432+
expect(parsed[`s:1`].versionKey).toBeDefined()
433+
expect(typeof parsed[`s:1`].versionKey).toBe(`string`)
434+
expect(parsed[`s:1`].data.id).toBe(`1`)
435+
expect(parsed[`s:1`].data.title).toBe(`Test Todo`)
436436
})
437437

438438
it(`should perform update operations and update storage`, async () => {
439439
// Pre-populate storage
440440
const initialData = {
441-
"1": {
441+
"s:1": {
442442
versionKey: `initial-version`,
443443
data: {
444444
id: `1`,
@@ -474,16 +474,16 @@ describe(`localStorage collection`, () => {
474474
expect(storedData).toBeDefined()
475475

476476
const parsed = JSON.parse(storedData!)
477-
expect(parsed[`1`].versionKey).not.toBe(`initial-version`) // Should have new version key
478-
expect(parsed[`1`].data.title).toBe(`Updated Todo`)
477+
expect(parsed[`s:1`].versionKey).not.toBe(`initial-version`) // Should have new version key
478+
expect(parsed[`s:1`].data.title).toBe(`Updated Todo`)
479479

480480
subscription.unsubscribe()
481481
})
482482

483483
it(`should perform delete operations and update storage`, async () => {
484484
// Pre-populate storage
485485
const initialData = {
486-
"1": {
486+
"s:1": {
487487
versionKey: `test-version`,
488488
data: {
489489
id: `1`,
@@ -517,7 +517,7 @@ describe(`localStorage collection`, () => {
517517
expect(storedData).toBeDefined()
518518

519519
const parsed = JSON.parse(storedData!)
520-
expect(parsed[`1`]).toBeUndefined()
520+
expect(parsed[`s:1`]).toBeUndefined()
521521

522522
subscription.unsubscribe()
523523
})
@@ -689,7 +689,7 @@ describe(`localStorage collection`, () => {
689689
it(`should detect version key changes for updates`, () => {
690690
// Pre-populate storage
691691
const initialData = {
692-
"1": {
692+
"s:1": {
693693
versionKey: `version-1`,
694694
data: {
695695
id: `1`,
@@ -718,7 +718,7 @@ describe(`localStorage collection`, () => {
718718

719719
// Simulate change from another tab with different version key but same data
720720
const updatedData = {
721-
"1": {
721+
"s:1": {
722722
versionKey: `version-2`, // Different version key
723723
data: {
724724
id: `1`,
@@ -755,7 +755,7 @@ describe(`localStorage collection`, () => {
755755

756756
// Pre-populate storage
757757
const initialData = {
758-
"1": {
758+
"s:1": {
759759
versionKey: `version-1`,
760760
data: {
761761
id: `1`,
@@ -781,7 +781,7 @@ describe(`localStorage collection`, () => {
781781

782782
// Simulate "change" from another tab with same version key
783783
const sameData = {
784-
"1": {
784+
"s:1": {
785785
versionKey: `version-1`, // Same version key
786786
data: {
787787
id: `1`,
@@ -1197,9 +1197,9 @@ describe(`localStorage collection`, () => {
11971197
const parsed = JSON.parse(storedData!)
11981198

11991199
// Item 1 should have the last update
1200-
expect(parsed[`1`].data.title).toBe(`Fourth`)
1200+
expect(parsed[`s:1`].data.title).toBe(`Fourth`)
12011201
// Item 2 should be deleted
1202-
expect(parsed[`2`]).toBeUndefined()
1202+
expect(parsed[`s:2`]).toBeUndefined()
12031203

12041204
// Verify collection matches storage
12051205
expect(collection.get(`1`)?.title).toBe(`Fourth`)
@@ -1257,8 +1257,8 @@ describe(`localStorage collection`, () => {
12571257
const storedData = mockStorage.getItem(`todos`)
12581258
const parsed = JSON.parse(storedData!)
12591259

1260-
expect(parsed[`1`].data.title).toBe(`C`)
1261-
expect(parsed[`2`]).toBeUndefined()
1260+
expect(parsed[`s:1`].data.title).toBe(`C`)
1261+
expect(parsed[`s:2`]).toBeUndefined()
12621262

12631263
subscription.unsubscribe()
12641264
})
@@ -1287,7 +1287,7 @@ describe(`localStorage collection`, () => {
12871287

12881288
// Simulate another tab making a change while local mutation is in progress
12891289
const remoteData = {
1290-
local: {
1290+
"s:local": {
12911291
versionKey: `local-version`,
12921292
data: {
12931293
id: `local`,
@@ -1296,7 +1296,7 @@ describe(`localStorage collection`, () => {
12961296
createdAt: new Date(),
12971297
},
12981298
},
1299-
remote: {
1299+
"s:remote": {
13001300
versionKey: `remote-version`,
13011301
data: {
13021302
id: `remote`,
@@ -1353,7 +1353,7 @@ describe(`localStorage collection`, () => {
13531353

13541354
// Simulate another tab updating the item
13551355
const remoteData = {
1356-
"1": {
1356+
"s:1": {
13571357
versionKey: `remote-version-1`,
13581358
data: {
13591359
id: `1`,
@@ -1387,8 +1387,8 @@ describe(`localStorage collection`, () => {
13871387
const storedData = mockStorage.getItem(`todos`)
13881388
const parsed = JSON.parse(storedData!)
13891389

1390-
expect(parsed[`1`].data.title).toBe(`Local Update After Remote`)
1391-
expect(parsed[`1`].data.completed).toBe(true) // Should preserve remote's completed state
1390+
expect(parsed[`s:1`].data.title).toBe(`Local Update After Remote`)
1391+
expect(parsed[`s:1`].data.completed).toBe(true) // Should preserve remote's completed state
13921392

13931393
subscription.unsubscribe()
13941394
})
@@ -1569,8 +1569,16 @@ describe(`localStorage collection`, () => {
15691569
const parsed = JSON.parse(storedData)
15701570

15711571
// Check that collection has all items from storage
1572-
for (const key of Object.keys(parsed)) {
1573-
if (!collection.has(key)) {
1572+
// Note: storage keys are encoded (e.g., "s:1"), but we need to decode them
1573+
// to check collection membership
1574+
for (const encodedKey of Object.keys(parsed)) {
1575+
// Decode the storage key to get the actual item key
1576+
const itemKey = encodedKey.startsWith(`s:`)
1577+
? encodedKey.slice(2)
1578+
: encodedKey.startsWith(`n:`)
1579+
? Number(encodedKey.slice(2))
1580+
: encodedKey
1581+
if (!collection.has(itemKey)) {
15741582
return false
15751583
}
15761584
}
@@ -1668,9 +1676,9 @@ describe(`localStorage collection`, () => {
16681676
const storedData = mockStorage.getItem(`todos`)
16691677
expect(storedData).toBeDefined()
16701678
const parsed = JSON.parse(storedData!)
1671-
expect(parsed[`first`].data.completed).toBe(true)
1672-
expect(parsed[`second`].data.completed).toBe(false)
1673-
expect(parsed[`third`].data.completed).toBe(false)
1679+
expect(parsed[`s:first`].data.completed).toBe(true)
1680+
expect(parsed[`s:second`].data.completed).toBe(false)
1681+
expect(parsed[`s:third`].data.completed).toBe(false)
16741682

16751683
subscription.unsubscribe()
16761684
})
@@ -1725,9 +1733,9 @@ describe(`localStorage collection`, () => {
17251733
const storedData = mockStorage.getItem(`todos`)
17261734
expect(storedData).toBeDefined()
17271735
const parsed = JSON.parse(storedData!)
1728-
expect(parsed[`first`]).toBeUndefined()
1729-
expect(parsed[`second`]).toBeDefined()
1730-
expect(parsed[`third`]).toBeDefined()
1736+
expect(parsed[`s:first`]).toBeUndefined()
1737+
expect(parsed[`s:second`]).toBeDefined()
1738+
expect(parsed[`s:third`]).toBeDefined()
17311739

17321740
subscription.unsubscribe()
17331741
})

0 commit comments

Comments
 (0)