Files
hackerspace.sh/__tests__/markdown-anchors.test.ts
Moheeb ZaraandClaude Opus 4.8 b1edb5c460 types: clear remaining tsc errors across 41 files (76→14, behavior-preserving)
Per-file type-only fixes surfaced after the Supabase client was correctly
typed. All fixes preserve runtime behavior; no any/ts-ignore/ts-expect-error.

- lib/supabase/client.ts: annotate the browser client as SupabaseClient<Database>
  (same ssr/js drift as server.ts; fixes it centrally for all callers).
- Supabase embedded-select joins whose FK metadata is missing from the
  generated types are bridged with `as unknown as <target>` + a TODO to remove
  after regenerating types/database.ts.
- setState optimistic-update variance and raw <select> enum values cast to the
  precise element/union type; .insert payload fields (Json, enums) given the
  precise column type via satisfies/field casts.
- Added narrowing guards where a value was legitimately nullable (comms channel,
  public form page) without changing the intended path.

The 14 remaining errors are confined to the four files fixed in Phase B (real
bugs + the tautological actions.test rewrite). 639 tests still green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-01 18:56:11 -07:00

59 lines
1.9 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import type { ReactNode } from 'react'
import {
headingText,
slugifyHeading,
makeHeadingSlugger,
isInDocumentHref,
} from '@/lib/markdown-anchors'
describe('headingText', () => {
it('reads strings and numbers', () => {
expect(headingText('Hello')).toBe('Hello')
expect(headingText(42)).toBe('42')
})
it('flattens arrays and element children', () => {
expect(headingText(['Get ', 'started'])).toBe('Get started')
expect(headingText({ props: { children: ['Bold ', { props: { children: 'bit' } }] } } as ReactNode)).toBe('Bold bit')
})
it('ignores null/boolean', () => {
expect(headingText(null)).toBe('')
expect(headingText(true)).toBe('')
})
})
describe('slugifyHeading', () => {
it('lowercases, strips punctuation, hyphenates', () => {
expect(slugifyHeading('Overview')).toBe('overview')
expect(slugifyHeading(' Getting Started! ')).toBe('getting-started')
expect(slugifyHeading('A & B / C')).toBe('a-b-c')
})
it('collapses repeats and trims hyphens', () => {
expect(slugifyHeading('-- weird spacing --')).toBe('weird-spacing')
})
})
describe('makeHeadingSlugger', () => {
it('dedupes repeated headings within a document', () => {
const slug = makeHeadingSlugger()
expect(slug('Setup')).toBe('setup')
expect(slug('Setup')).toBe('setup-1')
expect(slug('Setup')).toBe('setup-2')
expect(slug('Other')).toBe('other')
})
it('falls back to "section" for empty headings', () => {
const slug = makeHeadingSlugger()
expect(slug('')).toBe('section')
expect(slug(' ')).toBe('section-1')
})
})
describe('isInDocumentHref', () => {
it('is true only for hash links', () => {
expect(isInDocumentHref('#overview')).toBe(true)
expect(isInDocumentHref('https://example.com')).toBe(false)
expect(isInDocumentHref('/ops')).toBe(false)
expect(isInDocumentHref(undefined)).toBe(false)
})
})