129 lines
5.4 KiB
JavaScript
129 lines
5.4 KiB
JavaScript
// Stage 7 tests: editor-theme.js
|
||
//
|
||
// 覆盖:
|
||
// - pickEditorTheme 按 body[data-theme] 返回对应的 extensions 数组
|
||
// - 暗色叠加 oneDark;亮色只用自己的覆盖
|
||
// - backgroundColor / color 必须带 !important(oneDark 后续注入的同 specificity
|
||
// 规则会赢,必须用 important 强制覆盖,否则编辑区会显示 #282c34 而不是 --bg-viewer)
|
||
//
|
||
// editorTheme / editorThemeLight 是 EditorView.theme() 返回的 extension 对象,
|
||
// 内部是 CM6 私有结构,不展开断言 —— 只验证 pickEditorTheme 的行为即可。
|
||
|
||
import { describe, it, expect } from 'vitest';
|
||
import { pickEditorTheme, editorTheme, editorThemeLight, __editorThemeSpecForTests } from '../../src/editor-theme.js';
|
||
|
||
describe('pickEditorTheme', () => {
|
||
it('theme === "light" → 只返回 editorThemeLight', () => {
|
||
const exts = pickEditorTheme('light');
|
||
expect(exts).toHaveLength(1);
|
||
expect(exts[0]).toBe(editorThemeLight);
|
||
});
|
||
|
||
it('theme === "dark" → 返回 [oneDark, editorTheme]', () => {
|
||
const exts = pickEditorTheme('dark');
|
||
expect(exts).toHaveLength(2);
|
||
expect(exts[1]).toBe(editorTheme);
|
||
});
|
||
|
||
it('theme === undefined → 当暗色处理', () => {
|
||
const exts = pickEditorTheme(undefined);
|
||
expect(exts).toHaveLength(2);
|
||
expect(exts[1]).toBe(editorTheme);
|
||
});
|
||
|
||
it('theme === "auto"(旧版本残留) → 当暗色处理(防御性)', () => {
|
||
const exts = pickEditorTheme('auto');
|
||
expect(exts).toHaveLength(2);
|
||
});
|
||
|
||
it('theme === ""(空字符串) → 当暗色处理', () => {
|
||
const exts = pickEditorTheme('');
|
||
expect(exts).toHaveLength(2);
|
||
});
|
||
|
||
it('theme === null → 当暗色处理', () => {
|
||
const exts = pickEditorTheme(null);
|
||
expect(exts).toHaveLength(2);
|
||
});
|
||
});
|
||
|
||
describe('editorThemeSpec background overrides (oneDark / base theme 互斥)', () => {
|
||
// oneDark 的 .cm-editor { background-color: #282c34 } 和 .cm-gutters 同色,
|
||
// 在 dark theme 下会导致编辑区底色跟 .editor-pane / .viewer 的 --bg-viewer 不一致。
|
||
// 必须用 !important 强制覆盖,否则 oneDark 后注入的同 specificity 规则会赢。
|
||
it('.cm-editor backgroundColor 必须是 var(--bg-viewer) !important', () => {
|
||
const v = __editorThemeSpecForTests.backgroundColor;
|
||
expect(v).toMatch(/var\(--bg-viewer\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
it('.cm-editor color 必须是 var(--fg-primary) !important', () => {
|
||
const v = __editorThemeSpecForTests.color;
|
||
expect(v).toMatch(/var\(--fg-primary\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
it('.cm-gutters backgroundColor 必须是 var(--bg-viewer) !important', () => {
|
||
const v = __editorThemeSpecForTests.gutterBackgroundColor;
|
||
expect(v).toMatch(/var\(--bg-viewer\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
it('.cm-gutters color 必须是 var(--fg-tertiary) !important', () => {
|
||
const v = __editorThemeSpecForTests.gutterColor;
|
||
expect(v).toMatch(/var\(--fg-tertiary\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
// @codemirror/view 的 base theme 用 `&light .cm-activeLineGutter` / `&dark` 规则
|
||
//(特异性 (0,2,0))给 active 行 gutter 涂硬编码色(亮 #e2f2ff / 暗 #222227)。
|
||
// 我们的 .cm-activeLineGutter 是 (0,1,0),必须用 !important 才能让 var(--bg-hover) 稳定生效。
|
||
// 否则亮色下「活动行 gutter 变浅蓝色块」就是这个原因。
|
||
it('.cm-activeLine backgroundColor 必须是 var(--bg-hover) !important', () => {
|
||
const v = __editorThemeSpecForTests.activeLineBackgroundColor;
|
||
expect(v).toMatch(/var\(--bg-hover\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
it('.cm-activeLineGutter backgroundColor 必须是 var(--bg-hover) !important', () => {
|
||
const v = __editorThemeSpecForTests.activeLineGutterBackgroundColor;
|
||
expect(v).toMatch(/var\(--bg-hover\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
it('.cm-activeLineGutter color 必须是 var(--fg-secondary) !important', () => {
|
||
const v = __editorThemeSpecForTests.activeLineGutterColor;
|
||
expect(v).toMatch(/var\(--fg-secondary\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
// base theme 给 .cm-cursor 设黑色,&dark 下设 #528bff(oneDark 的 cursor 蓝)。
|
||
// 我们用 var(--accent),需要 !important 才能不被覆盖。
|
||
it('.cm-cursor/.cm-dropCursor borderLeftColor 必须是 var(--accent) !important', () => {
|
||
const v = __editorThemeSpecForTests.cursorBorderLeftColor;
|
||
expect(v).toMatch(/var\(--accent\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
// .cm-content caretColor 同样被 base theme 影响 —— 加 !important 兜底。
|
||
it('.cm-content caretColor 必须是 var(--accent) !important', () => {
|
||
const v = __editorThemeSpecForTests.caretColor;
|
||
expect(v).toMatch(/var\(--accent\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
// base theme `&light .cm-panels { background: #f5f5f5; color: black }` /
|
||
// `&dark { background: #333338; color: white }` 会盖住搜索面板的颜色。
|
||
it('.cm-panels backgroundColor 必须是 var(--bg-elevated) !important', () => {
|
||
const v = __editorThemeSpecForTests.panelsBackgroundColor;
|
||
expect(v).toMatch(/var\(--bg-elevated\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
|
||
it('.cm-panels color 必须是 var(--fg-primary) !important', () => {
|
||
const v = __editorThemeSpecForTests.panelsColor;
|
||
expect(v).toMatch(/var\(--fg-primary\)/);
|
||
expect(v).toMatch(/!important/);
|
||
});
|
||
});
|