- текстура, чёткость, дымка, виньетка и зерно в неразрушающем редакторе - живой WebGL2-предпросмотр эффектов и CPU-фолбэк - секции редактора свёрнуты по умолчанию, состояние в localStorage - вкладка «Редактирование» доступна только из просмотрщика
82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
defaultSectionCollapse,
|
|
EDITOR_SECTIONS_KEY,
|
|
loadSectionCollapse,
|
|
normalizeSectionCollapse,
|
|
saveSectionCollapse
|
|
} from './editor-sections';
|
|
|
|
function memoryStorage(initial: Record<string, string> = {}) {
|
|
const data = new Map(Object.entries(initial));
|
|
return {
|
|
data,
|
|
getItem(key: string) {
|
|
return data.has(key) ? data.get(key)! : null;
|
|
},
|
|
setItem(key: string, value: string) {
|
|
data.set(key, value);
|
|
}
|
|
};
|
|
}
|
|
|
|
describe('секции редактора', () => {
|
|
it('по умолчанию все секции свёрнуты', () => {
|
|
const state = defaultSectionCollapse();
|
|
for (const section of [
|
|
'light',
|
|
'curve',
|
|
'color',
|
|
'mixer',
|
|
'pointColor',
|
|
'correction',
|
|
'effects'
|
|
] as const) {
|
|
expect(state[section]).toBe(true);
|
|
}
|
|
expect(loadSectionCollapse(null)).toEqual(defaultSectionCollapse());
|
|
});
|
|
|
|
it('читает сохранённое состояние и восстанавливает недостающие ключи', () => {
|
|
const storage = memoryStorage({
|
|
[EDITOR_SECTIONS_KEY]: JSON.stringify({ effects: false, light: false, unknown: false })
|
|
});
|
|
const state = loadSectionCollapse(storage);
|
|
expect(state.effects).toBe(false);
|
|
expect(state.light).toBe(false);
|
|
expect(state.color).toBe(true);
|
|
expect('unknown' in state).toBe(false);
|
|
});
|
|
|
|
it('игнорирует невалидный JSON и небулевы значения', () => {
|
|
expect(
|
|
loadSectionCollapse(memoryStorage({ [EDITOR_SECTIONS_KEY]: '{oops' }))
|
|
).toEqual(defaultSectionCollapse());
|
|
expect(normalizeSectionCollapse({ effects: 'no', color: 1 })).toEqual(
|
|
defaultSectionCollapse()
|
|
);
|
|
expect(normalizeSectionCollapse(null)).toEqual(defaultSectionCollapse());
|
|
});
|
|
|
|
it('сохраняет состояние в хранилище', () => {
|
|
const storage = memoryStorage();
|
|
const state = { ...defaultSectionCollapse(), effects: false, curve: false };
|
|
saveSectionCollapse(state, storage);
|
|
expect(storage.data.get(EDITOR_SECTIONS_KEY)).toBe(JSON.stringify(state));
|
|
expect(loadSectionCollapse(storage)).toEqual(state);
|
|
});
|
|
|
|
it('переживает недоступное хранилище', () => {
|
|
const broken = {
|
|
getItem() {
|
|
throw new Error('denied');
|
|
},
|
|
setItem() {
|
|
throw new Error('denied');
|
|
}
|
|
};
|
|
expect(loadSectionCollapse(broken)).toEqual(defaultSectionCollapse());
|
|
expect(() => saveSectionCollapse(defaultSectionCollapse(), broken)).not.toThrow();
|
|
});
|
|
});
|