From d966b231148d76a9700b13b421d521c1b4f7650b Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Mon, 29 Aug 2022 21:56:26 +0530 Subject: [PATCH] Unit tests for history --- .vscode/settings.json | 5 +- src/lib/components/history/history.test.ts | 119 +++++++++++++++++++++ src/lib/util/migrations.test.ts | 34 ++++++ 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 src/lib/components/history/history.test.ts create mode 100644 src/lib/util/migrations.test.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index cd3023f6..1403e65a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { "editor.formatOnSave": true, - "cSpell.words": ["pako", "Serde", "serdes"] + "cSpell.words": ["pako", "Serde", "serdes"], + "vitest.commandLine": "yarn test:unit", + "vitest.enable": true, + "testing.autoRun.mode": "rerun" } diff --git a/src/lib/components/history/history.test.ts b/src/lib/components/history/history.test.ts new file mode 100644 index 00000000..3fbca5a5 --- /dev/null +++ b/src/lib/components/history/history.test.ts @@ -0,0 +1,119 @@ +import type { HistoryEntry } from '$lib/types'; +import { describe, it, expect, beforeEach } from 'vitest'; +import { + addHistoryEntry, + injectHistoryIDs, + clearHistoryData, + historyModeStore, + historyStore +} from './history'; +import { defaultState } from '../../util/state'; +import { get } from 'svelte/store'; + +describe('history', () => { + it('should handle saving individual history entry', () => { + expect(window.localStorage.getItem('manualHistoryStore')).toBe('[]'); + expect(window.localStorage.getItem('autoHistoryStore')).toBe('[]'); + + addHistoryEntry({ + state: defaultState, + time: 12345, + type: 'manual' + }); + + const [manualEntry]: HistoryEntry[] = JSON.parse( + window.localStorage.getItem('manualHistoryStore') + ); + + expect(manualEntry.time).toBe(12345); + expect(manualEntry.type).toBe('manual'); + expect(manualEntry.name).not.toBeNull(); + expect(manualEntry.state).not.toBeNull(); + + addHistoryEntry({ + state: defaultState, + time: 54321, + type: 'auto' + }); + + const [autoEntry]: HistoryEntry[] = JSON.parse(window.localStorage.getItem('autoHistoryStore')); + + expect(autoEntry.time).toBe(54321); + expect(autoEntry.type).toBe('auto'); + expect(autoEntry.name).not.toBeNull(); + expect(autoEntry.state).not.toBeNull(); + + historyModeStore.set('manual'); + clearHistoryData(); + historyModeStore.set('auto'); + clearHistoryData(); + expect(window.localStorage.getItem('manualHistoryStore')).toBe('[]'); + expect(window.localStorage.getItem('autoHistoryStore')).toBe('[]'); + }); + + it('should clear history entries', () => { + addHistoryEntry({ + state: defaultState, + time: 12345, + type: 'manual' + }); + addHistoryEntry({ + state: { ...defaultState, code: 'graph TD\\n A[Christmas] -->|Get money| B(Go shopping)' }, + time: 123456, + type: 'manual' + }); + addHistoryEntry({ + state: defaultState, + time: 54321, + type: 'auto' + }); + addHistoryEntry({ + state: { ...defaultState, code: 'graph TD\\n A[Christmas] -->|Get money| B(Go shopping)' }, + time: 654321, + type: 'auto' + }); + + const store: HistoryEntry[] = get(historyStore); + expect(store.length).toBe(2); + clearHistoryData(store[1].id); + expect(get(historyStore).length).toBe(1); + clearHistoryData(); + expect(get(historyStore).length).toBe(0); + + historyModeStore.set('auto'); + expect(get(historyStore).length).toBe(2); + clearHistoryData(); + expect(get(historyStore).length).toBe(0); + // Test calling when history is empty + clearHistoryData(); + expect(get(historyStore).length).toBe(0); + }); +}); + +describe('history migration', () => { + it('should inject history IDs as migration', () => { + window.localStorage.setItem( + 'manualHistoryStore', + '[{"state":{"code":"graph TD\\n A[Halloween] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":false,"autoSync":true,"updateDiagram":false},"time":0,"type":"manual","name":"hollow-art"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":true,"autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"helpful-ocean"}]' + ); + window.localStorage.setItem( + 'autoHistoryStore', + '[{"state":{"code":"graph TD\\n A[New Year] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":false,"autoSync":true,"updateDiagram":false},"time":0,"type":"auto","name":"barking-dog"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":true,"autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"needy-mosquito"}]' + ); + let manualHistoryStore: HistoryEntry[] = JSON.parse( + window.localStorage.getItem('manualHistoryStore') + ); + let autoHistoryStore: HistoryEntry[] = JSON.parse( + window.localStorage.getItem('autoHistoryStore') + ); + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + + injectHistoryIDs(); + + manualHistoryStore = JSON.parse(window.localStorage.getItem('manualHistoryStore')); + autoHistoryStore = JSON.parse(window.localStorage.getItem('autoHistoryStore')); + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + }); +}); diff --git a/src/lib/util/migrations.test.ts b/src/lib/util/migrations.test.ts new file mode 100644 index 00000000..9702c658 --- /dev/null +++ b/src/lib/util/migrations.test.ts @@ -0,0 +1,34 @@ +import type { HistoryEntry } from '$lib/types'; +import { describe, it, expect, beforeEach } from 'vitest'; + +describe('migrations', () => { + beforeEach(() => { + window.localStorage.setItem( + 'manualHistoryStore', + '[{"state":{"code":"graph TD\\n A[Halloween] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":false,"autoSync":true,"updateDiagram":false},"time":0,"type":"manual","name":"hollow-art"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":true,"autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"helpful-ocean"}]' + ); + window.localStorage.setItem( + 'autoHistoryStore', + '[{"state":{"code":"graph TD\\n A[New Year] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":false,"autoSync":true,"updateDiagram":false},"time":0,"type":"auto","name":"barking-dog"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","updateEditor":true,"autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"needy-mosquito"}]' + ); + }); + + it('should migrate from v0 to v1', async () => { + const { applyMigrations } = await import('./migrations'); + let manualHistoryStore: HistoryEntry[] = JSON.parse( + window.localStorage.getItem('manualHistoryStore') + ); + let autoHistoryStore: HistoryEntry[] = JSON.parse( + window.localStorage.getItem('autoHistoryStore') + ); + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + + applyMigrations(); + + manualHistoryStore = JSON.parse(window.localStorage.getItem('manualHistoryStore')); + autoHistoryStore = JSON.parse(window.localStorage.getItem('autoHistoryStore')); + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + }); +});