47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
import { get } from 'svelte/store';
|
|
import { persisted } from '$state';
|
|
|
|
beforeEach(() => localStorage.clear());
|
|
|
|
describe('persisted', () => {
|
|
it('uses the initial value when storage is empty', () => {
|
|
const s = persisted('k1', 42);
|
|
expect(get(s)).toBe(42);
|
|
});
|
|
it('writes updates to localStorage', () => {
|
|
const s = persisted('k2', { n: 1 });
|
|
s.set({ n: 2 });
|
|
expect(JSON.parse(localStorage.getItem('k2')!)).toEqual({ n: 2 });
|
|
});
|
|
it('rehydrates a value written by a previous instance', () => {
|
|
persisted('k3', 'a').set('b');
|
|
const s2 = persisted('k3', 'a');
|
|
expect(get(s2)).toBe('b');
|
|
});
|
|
|
|
/**
|
|
* Regression: constructing a store used to broadcast the value it had just
|
|
* read, so opening a second tab pushed its stale snapshot over the first one.
|
|
*/
|
|
it('does not broadcast the value read at construction', () => {
|
|
const posted: unknown[] = [];
|
|
class SpyChannel {
|
|
onmessage: ((e: { data: unknown }) => void) | null = null;
|
|
postMessage(v: unknown) {
|
|
posted.push(v);
|
|
}
|
|
}
|
|
vi.stubGlobal('BroadcastChannel', SpyChannel);
|
|
|
|
localStorage.setItem('k4', JSON.stringify({ n: 1 }));
|
|
const s = persisted('k4', { n: 0 });
|
|
expect(get(s)).toEqual({ n: 1 });
|
|
expect(posted).toEqual([]); // nothing announced merely by mounting
|
|
|
|
s.set({ n: 2 });
|
|
expect(posted).toEqual([{ n: 2 }]); // local changes still propagate
|
|
|
|
vi.unstubAllGlobals();
|
|
});
|
|
});
|