Both settings lived in the browser's localStorage, so they did not travel with the project and differed per machine. They now belong to the project like the symbol scale. There is no migration, old projects load with the defaults. - New module src/core/model/playSettings.ts reads playFrom and gameScale on load. Unknown or missing values fall back to the start scene and 100%. - src/editor/settings.ts is gone. - Play starts in the project settings dialog is an undo step (SetPlayFromCommand). It is only recorded on a real change. - The game view scale is saved with the project but is no undo step, so Ctrl+Z never undoes a zoom. A scale picked during play is written to the stored project and survives Stop. - Save states of persistent Variables assets (saves.ts) stay in the browser on purpose. They are runtime data of the game, not settings. Tests: - 6 new unit tests in tests/editor/play-settings.test.ts: defaults, save and load, broken JSON, undo of Play starts, scale without undo step, scale picked during play survives Stop. - e2e 03g checks the value in the project, nothing in localStorage and no new undo step. 35f also checks project.playFrom. No new checks, the sum stays at 1375. - Counter checks: no write to the stored project in play, no read on load, and an undo step for the scale each fail exactly their test. - ./check.sh: 158 files, 2332 tests, CHECK EXIT 0 - e2e 1-17,28,30,35,38-40,46: ALL PASSED, 752 checks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
/**
|
|
* Which scene Play starts and the game view scale (#226): both live in the project now, not in the
|
|
* browser. The start-scene switch is an undo step like every other project setting; the scale is
|
|
* saved but never lands on the undo stack.
|
|
*/
|
|
import { describe, expect, it } from 'vitest';
|
|
import { SetPlayFromCommand } from '../../src/core/commands/projectCommands';
|
|
import { gameScaleOf, playFromOf } from '../../src/core/model/playSettings';
|
|
import { createEmptyProject } from '../../src/core/model/Project';
|
|
import { deserializeProject, serializeProject } from '../../src/core/store/serialize';
|
|
import { EditorState } from '../../src/editor/state';
|
|
|
|
function loaded() {
|
|
const state = new EditorState();
|
|
state.loadProject(createEmptyProject('p', 'P'), 1);
|
|
return state;
|
|
}
|
|
|
|
describe('play settings in the project', () => {
|
|
it('start from the start scene at 100% in a new project and in one written before there were any', () => {
|
|
const fresh = createEmptyProject('p', 'P');
|
|
const old = deserializeProject({ id: 'p', name: 'P', assets: [] });
|
|
expect([fresh.playFrom, fresh.gameScale]).toEqual(['start', 1]);
|
|
expect([old.playFrom, old.gameScale]).toEqual(['start', 1]);
|
|
});
|
|
|
|
it('survive a save and a load', () => {
|
|
const project = {
|
|
...createEmptyProject('p', 'P'),
|
|
playFrom: 'active' as const,
|
|
gameScale: 'auto' as const,
|
|
};
|
|
const back = deserializeProject(serializeProject(project));
|
|
expect([back.playFrom, back.gameScale]).toEqual(['active', 'auto']);
|
|
});
|
|
|
|
it('read untrusted JSON as the defaults unless it is one of the choices', () => {
|
|
expect(playFromOf({ playFrom: 'active' })).toBe('active');
|
|
expect(playFromOf({ playFrom: 'elsewhere' })).toBe('start');
|
|
expect(playFromOf(null)).toBe('start');
|
|
expect(gameScaleOf({ gameScale: 'fit' })).toBe('fit');
|
|
expect(gameScaleOf({ gameScale: 0.25 })).toBe(0.25);
|
|
expect(gameScaleOf({ gameScale: 3 })).toBe(1);
|
|
expect(gameScaleOf({ gameScale: '2' })).toBe(1);
|
|
});
|
|
|
|
it('make the start-scene switch one undo step', () => {
|
|
const state = loaded();
|
|
state.execute(new SetPlayFromCommand('active'));
|
|
expect(state.playFrom).toBe('active');
|
|
expect(state.saveStatus).toBe('dirty');
|
|
state.undo();
|
|
expect(state.playFrom).toBe('start');
|
|
});
|
|
|
|
it('save the game view scale without an undo step', () => {
|
|
const state = loaded();
|
|
state.setGameScale(4);
|
|
expect(state.project.gameScale).toBe(4);
|
|
expect(state.saveStatus).toBe('dirty');
|
|
expect(state.commands.canUndo).toBe(false);
|
|
});
|
|
|
|
it('keep a scale picked while playing after Stop', () => {
|
|
const state = loaded();
|
|
state.enterPlay();
|
|
state.setGameScale('fit');
|
|
expect(state.gameScale).toBe('fit');
|
|
state.exitPlay();
|
|
expect(state.gameScale).toBe('fit');
|
|
expect(state.saveStatus).toBe('dirty');
|
|
});
|
|
});
|