This commit is contained in:
2026-09-12 14:15:26 +08:00
commit 9c06d3f4be
99 changed files with 41853 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
// Stage 7 tests: editor-theme.js
//
// 覆盖:
// - pickEditorTheme 按 body[data-theme] 返回对应的 extensions 数组
// - 暗色叠加 oneDark亮色只用自己的覆盖
// - backgroundColor / color 必须带 !importantoneDark 后续注入的同 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 下设 #528bffoneDark 的 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/);
});
});