code-block.spec.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. // @vitest-environment jsdom
  2. // CodeBlock + the shiki singleton: registered grammars highlight into token
  3. // spans colored by --shiki-* custom properties; unknown/absent languages take
  4. // the identical-geometry plain arm; aliases resolve; the trailing newline is
  5. // display-trimmed. MarkdownText's fence route is pinned in markdown.spec.tsx
  6. // alongside the rest of the markdown family.
  7. import { describe, expect, it } from 'vitest'
  8. import { cleanup, render } from '@testing-library/react'
  9. import { afterEach } from 'vitest'
  10. import { CodeBlock } from '../src/markdown/CodeBlock.tsx'
  11. import { highlightToHtml } from '../src/markdown/highlight.ts'
  12. afterEach(cleanup)
  13. describe('highlightToHtml', () => {
  14. it('highlights a registered grammar into css-variables token spans', () => {
  15. const html = highlightToHtml('const x: number = 1', 'typescript')
  16. expect(html).toContain('pre class="shiki css-variables"')
  17. expect(html).toContain('var(--shiki-')
  18. })
  19. it.each([['ts'], ['js'], ['bash'], ['sh'], ['jsonc']])('resolves the %s alias', (alias) => {
  20. expect(highlightToHtml('x', alias)).toContain('shiki')
  21. })
  22. it('returns undefined for unknown or absent languages', () => {
  23. expect(highlightToHtml('x', 'cobol')).toBeUndefined()
  24. expect(highlightToHtml('x', undefined)).toBeUndefined()
  25. })
  26. })
  27. describe('CodeBlock', () => {
  28. it('renders the highlighted tree for TypeScript', () => {
  29. const view = render(<CodeBlock code={'const a = 1\n'} lang="ts" />)
  30. const pre = view.container.querySelector('pre.shiki')
  31. expect(pre).not.toBeNull()
  32. expect(pre!.textContent).toBe('const a = 1')
  33. expect(pre!.querySelectorAll('span[style]').length).toBeGreaterThan(1)
  34. })
  35. it('renders the plain arm for an unknown language with the text verbatim', () => {
  36. const view = render(<CodeBlock code={'IDENTIFICATION DIVISION.'} lang="cobol" />)
  37. expect(view.container.querySelector('pre.shiki')).toBeNull()
  38. expect(view.getByText('IDENTIFICATION DIVISION.')).toBeTruthy()
  39. })
  40. it('renders the plain arm when no language is given', () => {
  41. const view = render(<CodeBlock code="plain text" />)
  42. expect(view.container.querySelector('pre.shiki')).toBeNull()
  43. expect(view.getByText('plain text')).toBeTruthy()
  44. })
  45. })