goal-command-input-styles.client.spec.ts 1.4 KB

12345678910111213141516171819202122232425262728293031
  1. /**
  2. * The command-input bubble's typography as CSS text. jsdom has no layout, so
  3. * this reads the declarations that make the bubble share the user bubble's
  4. * face and size axis: the shared projection sets the `/goal` chip in the code
  5. * face, so the bubble itself must not pin a different family.
  6. */
  7. import { readFileSync } from 'node:fs'
  8. import { fileURLToPath } from 'node:url'
  9. import { describe, expect, it } from 'vitest'
  10. const css = readFileSync(
  11. fileURLToPath(new URL('../src/client/GoalCommandInputView.module.css', import.meta.url)),
  12. 'utf8',
  13. ).replace(/\/\*[\s\S]*?\*\//g, ' ')
  14. function declarations(selector: string): string[] {
  15. const rule = new RegExp(`(?:^|\\})\\s*${selector.replace(/[.[\]():*+^$\\]/g, '\\$&')}\\s*\\{([^{}]*)\\}`).exec(css)
  16. if (rule === null) throw new Error(`GoalCommandInputView.module.css has no \`${selector}\` rule`)
  17. return (rule[1] ?? '').split(';').map(part => part.trim()).filter(Boolean)
  18. }
  19. describe('GoalCommandInputView.module.css typography', () => {
  20. it('types the command bubble like the user bubble: no family override, same size axis', () => {
  21. const bubble = declarations('.bubble')
  22. expect(bubble.some(declaration => /^font(-family)?:/.test(declaration))).toBe(false)
  23. expect(bubble).toEqual(expect.arrayContaining([
  24. 'font-size: var(--dsh-content-font-size, 14px)',
  25. 'line-height: calc(22px + var(--dsh-content-font-delta, 0px))',
  26. ]))
  27. })
  28. })