/**
* Ported from `packages/adapter-xslate/src/__tests__/xslate-counter.test.ts`.
*
* Only the FIRST (structural "compiles to a template") test is ported here.
* Xslate's second test renders the compiled template through REAL
* Text::Xslate via a `renderXslateComponent`-equivalent test-render harness
* (`Bun.spawn(['perl', ...])`). The Jinja analog of that harness
* (`renderJinjaComponent`, spawning `python3` against the bundled Python
* runtime) is `src/test-render.ts` — explicitly workstream C, not written
* here (see `packages/adapter-jinja/CHANGELOG.md` / the task's workstream
* split). Once `test-render.ts` lands, a real-render counterpart to this
* test belongs in the conformance test file, not here.
*/
import { test, expect } from 'bun:test'
import { compileJSX } from '@barefootjs/jsx'
import { JinjaAdapter } from '../adapter'
const COUNTER_SRC = `"use client"
import { createSignal } from '@barefootjs/client'
export function Counter({ initial = 0 }: { initial?: number }) {
const [count, setCount] = createSignal(initial)
const doubled = () => count() * 2
return (
count: {count()}
doubled: {doubled()}
)
}`
test('Counter compiles to a Jinja .jinja template', () => {
const result = compileJSX(COUNTER_SRC, 'Counter.tsx', {
adapter: new JinjaAdapter(),
outputIR: true,
})
const errors = result.errors.filter(e => e.severity === 'error')
expect(errors).toEqual([])
const tpl = result.files.find(f => f.type === 'markedTemplate')
expect(tpl).toBeDefined()
const content = tpl!.content
// Script registration as `{% set %}` statements (Jinja's `{% %}` tag never
// prints, so — unlike Kolon's bare `:` line — no throwaway-bind trick is
// needed to suppress a leaked return value; see `jinja-adapter.ts`'s
// `generateScriptRegistrations`).
expect(content).toContain(`bf.register_script('/static/components/barefoot.js')`)
expect(content).toContain(`bf.register_script('/static/components/Counter.client.js')`)
// Hydration markers
expect(content).toContain(`bf-s="{{ bf.scope_attr() }}"`)
expect(content).toContain(`{{ bf.hydration_attrs() | safe }}`)
expect(content).toContain(`{{ bf.props_attr() | safe }}`)
// Text slots — every text interpolation routes through `bf.string(...)`
// (divergence 2: Python's default stringification diverges from JS's
// further than Perl's does, so this port wraps every text-position value,
// unlike the Kolon port's bare `<: $count :>`).
expect(content).toContain(`{{ bf.text_start("s0") | safe }}{{ bf.string(count) }}{{ bf.text_end() | safe }}`)
expect(content).toContain(`{{ bf.text_start("s2") | safe }}{{ bf.string(doubled) }}{{ bf.text_end() | safe }}`)
// Button stays a plain element (onClick is client-only)
expect(content).toContain(`+1`)
})