86 lines
3.4 KiB
TypeScript
86 lines
3.4 KiB
TypeScript
|
|
// @vitest-environment jsdom
|
||
|
|
/**
|
||
|
|
* Regression test for the bug where switching between a board-less example
|
||
|
|
* (analog / digital SPICE-only) and a board-based example (Arduino Uno) left
|
||
|
|
* the editor showing the OLD file's content (or nothing at all).
|
||
|
|
*
|
||
|
|
* Root cause: `loadExample.ts` single-board path called
|
||
|
|
* `useEditorStore.setCode()`, which writes to whatever file `activeFileId`
|
||
|
|
* happens to point at. But after a board-less example removed every board,
|
||
|
|
* its file group was deleted — and `activeFileId` still pointed at the now-
|
||
|
|
* orphan ID, so `setCode` was a silent no-op against the freshly-recreated
|
||
|
|
* Arduino file group.
|
||
|
|
*/
|
||
|
|
import { describe, it, expect, beforeEach } from 'vitest';
|
||
|
|
import { useEditorStore } from '../store/useEditorStore';
|
||
|
|
import { useSimulatorStore } from '../store/useSimulatorStore';
|
||
|
|
import { useElectricalStore } from '../store/useElectricalStore';
|
||
|
|
import { loadExample } from '../utils/loadExample';
|
||
|
|
import { exampleProjects } from '../data/examples';
|
||
|
|
|
||
|
|
function resetStores() {
|
||
|
|
// Clear all boards completely (also clears the file groups they own).
|
||
|
|
const sim = useSimulatorStore.getState();
|
||
|
|
const ids = sim.boards.map((b) => b.id);
|
||
|
|
for (const id of ids) sim.removeBoard(id);
|
||
|
|
useElectricalStore.getState().setPaused(false);
|
||
|
|
}
|
||
|
|
|
||
|
|
function findExample(id: string) {
|
||
|
|
const e = exampleProjects.find((x) => x.id === id);
|
||
|
|
if (!e) throw new Error(`Example not found: ${id}`);
|
||
|
|
return e;
|
||
|
|
}
|
||
|
|
|
||
|
|
function activeSketchContent(): string | undefined {
|
||
|
|
const { files, activeFileId } = useEditorStore.getState();
|
||
|
|
return files.find((f) => f.id === activeFileId)?.content;
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('loadExample — board-less → board-based transition', () => {
|
||
|
|
beforeEach(() => {
|
||
|
|
resetStores();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('loads Arduino Uno code into the editor after a board-less ANALOG example', async () => {
|
||
|
|
// 1. Board-less analog circuit
|
||
|
|
await loadExample(findExample('an-voltage-divider'));
|
||
|
|
expect(useSimulatorStore.getState().boards.length).toBe(0);
|
||
|
|
|
||
|
|
// 2. Now load an Arduino Uno example
|
||
|
|
const uno = findExample('blink-led');
|
||
|
|
await loadExample(uno);
|
||
|
|
|
||
|
|
expect(useSimulatorStore.getState().boards.length).toBeGreaterThanOrEqual(1);
|
||
|
|
|
||
|
|
const code = activeSketchContent();
|
||
|
|
expect(code, 'editor content after Uno load').toBeDefined();
|
||
|
|
expect(code, 'editor must contain the Uno example body').toContain(uno.code.slice(0, 40));
|
||
|
|
});
|
||
|
|
|
||
|
|
it('loads Arduino Uno code into the editor after a board-less DIGITAL example', async () => {
|
||
|
|
await loadExample(findExample('digital-and-two-switches'));
|
||
|
|
expect(useSimulatorStore.getState().boards.length).toBe(0);
|
||
|
|
|
||
|
|
const uno = findExample('blink-led');
|
||
|
|
await loadExample(uno);
|
||
|
|
|
||
|
|
const code = activeSketchContent();
|
||
|
|
expect(code, 'editor content after Uno load').toBeDefined();
|
||
|
|
expect(code, 'editor must contain the Uno example body').toContain(uno.code.slice(0, 40));
|
||
|
|
});
|
||
|
|
|
||
|
|
it('switching between two board-less examples does not break a later board load', async () => {
|
||
|
|
await loadExample(findExample('an-voltage-divider'));
|
||
|
|
await loadExample(findExample('digital-xor-difference'));
|
||
|
|
await loadExample(findExample('an-rc-low-pass'));
|
||
|
|
|
||
|
|
const uno = findExample('blink-led');
|
||
|
|
await loadExample(uno);
|
||
|
|
|
||
|
|
const code = activeSketchContent();
|
||
|
|
expect(code, 'editor content after 3 board-less → Uno load').toBeDefined();
|
||
|
|
expect(code, 'editor must contain the Uno example body').toContain(uno.code.slice(0, 40));
|
||
|
|
});
|
||
|
|
});
|