diff --git a/packages/superdoc/src/assets/styles/helpers/compat.test.ts b/packages/superdoc/src/assets/styles/helpers/compat.test.ts index 46238e5163..ff8efe1144 100644 --- a/packages/superdoc/src/assets/styles/helpers/compat.test.ts +++ b/packages/superdoc/src/assets/styles/helpers/compat.test.ts @@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const variablesCss = readFileSync(resolve(__dirname, 'variables.css'), 'utf-8'); const compatCss = readFileSync(resolve(__dirname, 'compat.css'), 'utf-8'); +const themesCss = readFileSync(resolve(__dirname, 'themes.css'), 'utf-8'); /** Extract all --sd-* variable declarations from a CSS string. */ const extractDeclaredVars = (css: string): Set => { @@ -130,4 +131,39 @@ describe('backward compatibility', () => { } }); }); + + describe('preset themes', () => { + /** Extract variables declared inside each .sd-theme-* block. */ + const extractThemeBlocks = (css: string): Map> => { + const themes = new Map>(); + const blockRegex = /\.(sd-theme-[\w-]+)\s*\{([^}]+)\}/g; + for (const match of css.matchAll(blockRegex)) { + const vars = new Set(); + for (const decl of match[2].matchAll(/(--sd-[\w-]+)\s*:/g)) { + vars.add(decl[1]); + } + themes.set(match[1], vars); + } + return themes; + }; + + const themeBlocks = extractThemeBlocks(themesCss); + + it('contains all expected preset themes', () => { + expect([...themeBlocks.keys()].sort()).toEqual(['sd-theme-blueprint', 'sd-theme-docs', 'sd-theme-word']); + }); + + it('every theme variable is declared in variables.css', () => { + const declaredInVariables = extractDeclaredVars(variablesCss); + const broken: string[] = []; + for (const [theme, vars] of themeBlocks) { + for (const v of vars) { + if (!declaredInVariables.has(v)) { + broken.push(`${theme}: ${v}`); + } + } + } + expect(broken, `Theme variables not in variables.css: ${broken.join(', ')}`).toEqual([]); + }); + }); }); diff --git a/packages/superdoc/tests/consumer-types/test.ts b/packages/superdoc/tests/consumer-types/test.ts index bbf568afda..75f4706be0 100644 --- a/packages/superdoc/tests/consumer-types/test.ts +++ b/packages/superdoc/tests/consumer-types/test.ts @@ -10,6 +10,7 @@ // Main entry point import type { SuperDoc } from 'superdoc'; +import { createTheme, buildTheme } from 'superdoc'; // Super-editor entry point import type { EditorView, EditorState, Transaction, Schema } from 'superdoc/super-editor'; @@ -17,7 +18,13 @@ import type { EditorView, EditorState, Transaction, Schema } from 'superdoc/supe // Types entry point import type { ProseMirrorJSON, NodeConfig, MarkConfig } from 'superdoc/types'; -// Verify the types are usable (not just importable) -type _AssertSuperDoc = SuperDoc extends object ? true : never; -type _AssertEditorView = EditorView extends object ? true : never; -type _AssertJSON = ProseMirrorJSON extends object ? true : never; +// Verify the types are usable (not just importable). +// AssertExtends is a compile error, so signature mismatches fail the build. +type AssertExtends = T; +type _AssertSuperDoc = AssertExtends; +type _AssertEditorView = AssertExtends; +type _AssertJSON = AssertExtends; +type _AssertCreateTheme = AssertExtends string ? true : false>; +type _AssertBuildTheme = AssertExtends< + typeof buildTheme extends (...args: any[]) => { className: string; css: string } ? true : false +>;