base-styles.client.spec.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. /** Shell base styles stay independent from the dynamically loaded theme bundle. */
  2. import { readFileSync } from 'node:fs'
  3. import { fileURLToPath } from 'node:url'
  4. import { describe, expect, it } from 'vitest'
  5. const THEME_PACKAGE = '@deepseek-ai/dsh-client-ui-theme'
  6. const baseCss = readFileSync(fileURLToPath(new URL('../src/base.css', import.meta.url)), 'utf8')
  7. /**
  8. * Import specifiers of the sheet, in source order. Quote style and surrounding
  9. * whitespace are intentionally irrelevant; duplicate imports remain visible.
  10. * @param css - stylesheet text.
  11. * @returns import specifiers in declaration order.
  12. */
  13. function importOrder(css: string): string[] {
  14. return [...css.matchAll(/@import\s+['"]([^'"]+)['"]/g)].map(([, specifier = '']) => specifier)
  15. }
  16. const imports = importOrder(baseCss)
  17. const normalizedCss = baseCss
  18. .replaceAll(/\/\*[\s\S]*?\*\//g, '')
  19. .replaceAll(/\s+/g, ' ')
  20. const literalContentSelectors = [
  21. 'code',
  22. 'pre',
  23. '[data-diff]',
  24. '[data-read]',
  25. '[data-search]',
  26. '[data-terminal]',
  27. ]
  28. describe('web shell base.css', () => {
  29. it('leaves theme styles to the dynamic ui-theme client entry', () => {
  30. expect(imports).toEqual([])
  31. expect(baseCss).not.toContain(THEME_PACKAGE)
  32. })
  33. it('auto-spaces prose while preserving literal content', () => {
  34. expect(baseCss).toMatch(/body\s*\{[^}]*text-autospace:\s*normal;/)
  35. expect(normalizedCss).toContain(
  36. `${literalContentSelectors.join(', ')} { text-autospace: no-autospace; }`,
  37. )
  38. })
  39. })