@pyreon/compiler 0.24.4 → 0.24.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -13
- package/src/defer-inline.ts +0 -686
- package/src/event-names.ts +0 -65
- package/src/index.ts +0 -61
- package/src/island-audit.ts +0 -675
- package/src/jsx.ts +0 -2792
- package/src/load-native.ts +0 -156
- package/src/lpih.ts +0 -270
- package/src/manifest.ts +0 -280
- package/src/project-scanner.ts +0 -214
- package/src/pyreon-intercept.ts +0 -1029
- package/src/react-intercept.ts +0 -1217
- package/src/reactivity-lens.ts +0 -190
- package/src/ssg-audit.ts +0 -513
- package/src/test-audit.ts +0 -435
- package/src/tests/backend-parity-r7-r9.test.ts +0 -91
- package/src/tests/backend-prop-derived-callback-divergence.test.ts +0 -74
- package/src/tests/collapse-bail-census.test.ts +0 -330
- package/src/tests/collapse-key-source-hygiene.test.ts +0 -88
- package/src/tests/component-child-no-wrap.test.ts +0 -204
- package/src/tests/defer-inline.test.ts +0 -387
- package/src/tests/depth-stress.test.ts +0 -16
- package/src/tests/detector-tag-consistency.test.ts +0 -101
- package/src/tests/dynamic-collapse-detector.test.ts +0 -164
- package/src/tests/dynamic-collapse-emit.test.ts +0 -192
- package/src/tests/dynamic-collapse-scan.test.ts +0 -111
- package/src/tests/element-valued-const-child.test.ts +0 -61
- package/src/tests/falsy-child-characterization.test.ts +0 -48
- package/src/tests/island-audit.test.ts +0 -524
- package/src/tests/jsx.test.ts +0 -2908
- package/src/tests/load-native.test.ts +0 -53
- package/src/tests/lpih.test.ts +0 -404
- package/src/tests/malformed-input-resilience.test.ts +0 -50
- package/src/tests/manifest-snapshot.test.ts +0 -55
- package/src/tests/native-equivalence.test.ts +0 -924
- package/src/tests/partial-collapse-detector.test.ts +0 -121
- package/src/tests/partial-collapse-emit.test.ts +0 -104
- package/src/tests/partial-collapse-robustness.test.ts +0 -53
- package/src/tests/project-scanner.test.ts +0 -269
- package/src/tests/prop-derived-shadow.test.ts +0 -96
- package/src/tests/pure-call-reactive-args.test.ts +0 -50
- package/src/tests/pyreon-intercept.test.ts +0 -816
- package/src/tests/r13-callback-stmt-equivalence.test.ts +0 -58
- package/src/tests/r14-ssr-mode-parity.test.ts +0 -51
- package/src/tests/r15-elemconst-propderived.test.ts +0 -47
- package/src/tests/r19-defer-inline-robust.test.ts +0 -54
- package/src/tests/r20-backend-equivalence-sweep.test.ts +0 -50
- package/src/tests/react-intercept.test.ts +0 -1104
- package/src/tests/reactivity-lens.test.ts +0 -170
- package/src/tests/rocketstyle-collapse.test.ts +0 -208
- package/src/tests/runtime/control-flow.test.ts +0 -159
- package/src/tests/runtime/dom-properties.test.ts +0 -138
- package/src/tests/runtime/events.test.ts +0 -301
- package/src/tests/runtime/harness.ts +0 -94
- package/src/tests/runtime/pr-352-shapes.test.ts +0 -121
- package/src/tests/runtime/reactive-props.test.ts +0 -81
- package/src/tests/runtime/signals.test.ts +0 -129
- package/src/tests/runtime/whitespace.test.ts +0 -106
- package/src/tests/signal-autocall-shadow.test.ts +0 -86
- package/src/tests/sourcemap-fidelity.test.ts +0 -77
- package/src/tests/ssg-audit.test.ts +0 -402
- package/src/tests/static-text-baking.test.ts +0 -64
- package/src/tests/test-audit.test.ts +0 -549
- package/src/tests/transform-state-isolation.test.ts +0 -49
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compiler hardening — Round 13 (REAL JS↔Rust divergence, FIXED + bisect).
|
|
3
|
-
*
|
|
4
|
-
* R7 (#687) taught the native `collect_prop_derived_idents` to recurse into
|
|
5
|
-
* callback bodies — but its `collect_pd_in_stmt` only handled
|
|
6
|
-
* Expression/Return/VarDecl/If/Block, with `_ => {}` skipping
|
|
7
|
-
* For/While/DoWhile/Switch/Try/Labeled. So a prop-derived const used inside a
|
|
8
|
-
* callback whose body is one of those shapes still lost reactivity in the
|
|
9
|
-
* NATIVE backend (preferred in prod) while the JS backend inlined it — the
|
|
10
|
-
* exact R7 reactivity-loss class, narrower shapes (e.g. `try { return <li
|
|
11
|
-
* class={c}/> } catch …` in a render callback — plausible defensive render).
|
|
12
|
-
*
|
|
13
|
-
* Fix: native/src/lib.rs `collect_pd_in_stmt` now also handles
|
|
14
|
-
* For/ForIn/ForOf/While/DoWhile/Switch/Try/Labeled, with the SAME
|
|
15
|
-
* `pd_minus`/`collect_bind_pattern_names` shadow-filter discipline as the
|
|
16
|
-
* Block/If arms (so loop/catch-param bindings shadow correctly and the
|
|
17
|
-
* over-substitution clobber is NOT re-introduced — verified by the
|
|
18
|
-
* catch-param spec).
|
|
19
|
-
*
|
|
20
|
-
* Bisect: replace the new arms with `_ => {}` + `bun scripts/build-native.ts`
|
|
21
|
-
* → these specs fail (Rust emits `class={c}`, JS `class={(p.x+'-b')}`).
|
|
22
|
-
* Restore + rebuild → all pass. The 180 native-equivalence tests + full
|
|
23
|
-
* suite remain green (no regression).
|
|
24
|
-
*/
|
|
25
|
-
import { describe, expect, it } from 'vitest'
|
|
26
|
-
import { transformJSX, transformJSX_JS } from '../jsx'
|
|
27
|
-
|
|
28
|
-
const j = (c: string): string => transformJSX_JS(c, 'c.tsx').code ?? ''
|
|
29
|
-
const r = (c: string): string => transformJSX(c, 'c.tsx').code ?? ''
|
|
30
|
-
|
|
31
|
-
const CASES: Array<[string, string]> = [
|
|
32
|
-
['while', `function C(p){ const c=p.x+'-b'; return <ul>{p.i.map(i => { while(i){ return <li class={c}/> } })}</ul> }`],
|
|
33
|
-
['switch', `function C(p){ const c=p.x+'-b'; return <ul>{p.i.map(i => { switch(i){ default: return <li class={c}/> } })}</ul> }`],
|
|
34
|
-
['labeled', `function C(p){ const c=p.x+'-b'; return <ul>{p.i.map(i => { lbl: { return <li class={c}/> } })}</ul> }`],
|
|
35
|
-
['try-catch', `function C(p){ const c=p.x+'-b'; return <ul>{p.i.map(i => { try { return <li class={c}/> } catch { return null } })}</ul> }`],
|
|
36
|
-
['for', `function C(p){ const c=p.x+'-b'; return <ul>{p.i.map(i => { for(let k=0;k<i;k++){ return <li class={c}/> } })}</ul> }`],
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
describe('Round 13 — prop-derived inlining inside callback statement shapes is JS≡Rust', () => {
|
|
40
|
-
for (const [name, src] of CASES) {
|
|
41
|
-
it(`${name}: native backend matches JS (inlines the prop-derived const)`, () => {
|
|
42
|
-
expect(r(src)).toBe(j(src))
|
|
43
|
-
expect(r(src)).toContain("class={(p.x+'-b')}")
|
|
44
|
-
})
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
it('catch-param shadowing is NOT clobbered (filter discipline, both backends)', () => {
|
|
48
|
-
const src = `function C(p){ const e=p.x+'-b'; return <ul>{p.i.map(i => { try {} catch (e) { return <li class={e}/> } })}</ul> }`
|
|
49
|
-
expect(r(src)).toBe(j(src))
|
|
50
|
-
expect(r(src)).not.toContain("class={(p.x+'-b')}") // `e` is the catch param
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('nested const inside a while body shadowing the prop-derived is NOT clobbered (no R2 regression)', () => {
|
|
54
|
-
const src = `function C(p){ const c=p.x; return <ul>{p.i.map(i => { while(i){ const c=2; return <li>{c}</li> } })}</ul> }`
|
|
55
|
-
expect(r(src)).toBe(j(src))
|
|
56
|
-
expect(r(src)).not.toContain('{(p.x)}') // inner `const c=2` shadows — must stay `{c}`
|
|
57
|
-
})
|
|
58
|
-
})
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compiler hardening — Round 14 (SSR-mode robustness; no bug found).
|
|
3
|
-
*
|
|
4
|
-
* Rounds 1–13 were all client-mode. SSR mode (`{ ssr: true }`) disables
|
|
5
|
-
* template emission (`if (ssr) return false`) and leaves JSX as
|
|
6
|
-
* accessor-wrapped expressions for the SSR renderer. Probed 8 adversarial
|
|
7
|
-
* shapes — all emit parseable code, and the correctness-critical contracts
|
|
8
|
-
* hold in SSR exactly as in client mode: prop-derived consts still inline,
|
|
9
|
-
* signals still auto-call, and the R11 shadow fix still suppresses a
|
|
10
|
-
* destructured callback param. This locks SSR-mode parity for the bug fixes
|
|
11
|
-
* so a future SSR-path change can't silently regress them.
|
|
12
|
-
*/
|
|
13
|
-
import { parseSync } from 'oxc-parser'
|
|
14
|
-
import { describe, expect, it } from 'vitest'
|
|
15
|
-
import { transformJSX_JS } from '../jsx'
|
|
16
|
-
|
|
17
|
-
const ssr = (c: string): string => transformJSX_JS(c, 'c.tsx', { ssr: true }).code ?? ''
|
|
18
|
-
const parses = (o: string): boolean => {
|
|
19
|
-
try {
|
|
20
|
-
return (parseSync('o.tsx', o).errors?.length ?? 0) === 0
|
|
21
|
-
} catch {
|
|
22
|
-
return false
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
describe('Round 14 — SSR-mode codegen parity', () => {
|
|
27
|
-
it('SSR never throws / always emits parseable code (8 adversarial shapes)', () => {
|
|
28
|
-
const shapes = [
|
|
29
|
-
`function C(p){ return <div class={p.c}>{p.t}</div> }`,
|
|
30
|
-
`function C(p){ return <div {...p}>{p.k}</div> }`,
|
|
31
|
-
`function C(p){ return <>{p.a}<span>{p.b}</span></> }`,
|
|
32
|
-
`function C(){ const h=<h1>T</h1>; return <div>{h}<p>x</p></div> }`,
|
|
33
|
-
`function C(p){ return <section><h1>{p.t}</h1><p>{p.b}</p></section> }`,
|
|
34
|
-
]
|
|
35
|
-
for (const s of shapes) expect(parses(ssr(s)), s).toBe(true)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('prop-derived const still inlines in SSR (R2/R7 parity)', () => {
|
|
39
|
-
expect(ssr(`function C(p){ const c=p.x+'-b'; return <ul>{p.i.map(i=><li class={c}>{i}</li>)}</ul> }`))
|
|
40
|
-
.toContain("class={(p.x+'-b')}")
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('signal still auto-calls in SSR', () => {
|
|
44
|
-
expect(ssr(`function C(){ const s=signal(0); return <div>{s}</div> }`)).toContain('s()')
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('R11 shadow fix applies in SSR (destructured param NOT auto-called)', () => {
|
|
48
|
-
expect(ssr(`function C(){ const x=signal(0); return <ul>{[{x:1}].map(({x})=><li>{x}</li>)}</ul> }`))
|
|
49
|
-
.not.toContain('{x()}')
|
|
50
|
-
})
|
|
51
|
-
})
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compiler hardening — Round 15 (element-const that references a prop-derived
|
|
3
|
-
* var) — consolidated, deterministic JS-backend characterization.
|
|
4
|
-
*
|
|
5
|
-
* Original finding: `const cls = props.x + '-b'; const el = <i class={cls}/>;`
|
|
6
|
-
* used as a bare `{el}` child sat at the intersection of R2 (prop-derived
|
|
7
|
-
* inlining) and R9 (element-const → `_mountSlot`). The JS backend substitutes
|
|
8
|
-
* the element-const's whole initializer into the mount call with the
|
|
9
|
-
* prop-derived part inlined reactively:
|
|
10
|
-
* `_mountSlot((<i class={(props.x + '-b')}/>), …)`
|
|
11
|
-
*
|
|
12
|
-
* It was previously tracked by two duplicate, environment-fragile `it.fails`
|
|
13
|
-
* JS↔Rust divergence locks. The R13 gate/collector fix
|
|
14
|
-
* (`accesses_props` now recurses arrow/JSX → the element-const's prop-derived
|
|
15
|
-
* ref is collected) realigned the native backend with JS — so the locks
|
|
16
|
-
* correctly auto-flipped and were removed (lock→resolved, same lifecycle as
|
|
17
|
-
* R7/R11/R13). JS↔Rust byte-equivalence is now gated generally by the R20
|
|
18
|
-
* sweep + R13's own contract; this file keeps only the DETERMINISTIC,
|
|
19
|
-
* native-independent JS-backend assertions (no `transformJSX` native call →
|
|
20
|
-
* no build-artifact fragility, stable on every runner).
|
|
21
|
-
*/
|
|
22
|
-
import { describe, expect, it } from 'vitest'
|
|
23
|
-
import { transformJSX_JS } from '../jsx'
|
|
24
|
-
|
|
25
|
-
const emit = (c: string): string => transformJSX_JS(c, 'c.tsx').code ?? ''
|
|
26
|
-
|
|
27
|
-
const PD_ELEM = `function C(p){ const cls=p.x+'-b'; const el=<i class={cls}/>; return <div>{el}<span class={cls}/></div> }`
|
|
28
|
-
const SIMPLE = `function C(){ const h=<h1>T</h1>; return <div>{h}<p>x</p></div> }`
|
|
29
|
-
const REUSED = `function C(){ const ic=<svg/>; return <div>{ic}<span>{ic}</span></div> }`
|
|
30
|
-
|
|
31
|
-
describe('Round 15 — element-const × prop-derived (JS backend characterization)', () => {
|
|
32
|
-
it('JS inlines a prop-derived-referencing element-const into _mountSlot with a reactive class', () => {
|
|
33
|
-
const out = emit(PD_ELEM)
|
|
34
|
-
expect(out).toContain("_mountSlot((<i class={(p.x+'-b')}/>)")
|
|
35
|
-
// the prop-derived class is the reactive form, not the frozen const ref
|
|
36
|
-
expect(out).not.toMatch(/_mountSlot\(\s*el\b/)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('a simple element-const child routes through _mountSlot (R9 baseline)', () => {
|
|
40
|
-
expect(emit(SIMPLE)).toContain('_mountSlot(h')
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('an element-const reused at two sites routes both through _mountSlot', () => {
|
|
44
|
-
const out = emit(REUSED)
|
|
45
|
-
expect(out).toMatch(/_mountSlot\(\s*ic\b/)
|
|
46
|
-
})
|
|
47
|
-
})
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compiler hardening — Round 19 (defer-inline robustness; no bug found).
|
|
3
|
-
*
|
|
4
|
-
* `transformDeferInline` (a separate compiler entry, unprobed in rounds
|
|
5
|
-
* 1–18) rewrites `<Defer when={…}><X/></Defer>` to inline its children.
|
|
6
|
-
* Probed 10 valid shapes (no-children, multi-child, expr/text child, nested
|
|
7
|
-
* Defer, self-closing, spread child, comment child, passthrough) + a
|
|
8
|
-
* malformed input — all valid cases emit parseable code, and malformed input
|
|
9
|
-
* is passed through unchanged without throwing (same resilience contract as
|
|
10
|
-
* Round 10). This locks the surface.
|
|
11
|
-
*/
|
|
12
|
-
import { parseSync } from 'oxc-parser'
|
|
13
|
-
import { describe, expect, it } from 'vitest'
|
|
14
|
-
import { transformDeferInline } from '../defer-inline'
|
|
15
|
-
|
|
16
|
-
const run = (c: string): string => {
|
|
17
|
-
const r = transformDeferInline(c, 'c.tsx') as { code?: string }
|
|
18
|
-
return r?.code ?? ''
|
|
19
|
-
}
|
|
20
|
-
const parses = (o: string): boolean => {
|
|
21
|
-
try {
|
|
22
|
-
return (parseSync('o.tsx', o).errors?.length ?? 0) === 0
|
|
23
|
-
} catch {
|
|
24
|
-
return false
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const VALID: Array<[string, string]> = [
|
|
29
|
-
['basic', `import { Modal } from './M'\nfunction C(){ const o=signal(0); return <Defer when={o()}><Modal title="hi"/></Defer> }`],
|
|
30
|
-
['passthrough', `function C(){ return <div>{x}</div> }`],
|
|
31
|
-
['no-children', `function C(){ return <Defer when={a}></Defer> }`],
|
|
32
|
-
['multi-child', `import {A,B} from './x'\nfunction C(){ return <Defer when={c}><A/><B/></Defer> }`],
|
|
33
|
-
['expr-child', `function C(){ return <Defer when={c}>{val}</Defer> }`],
|
|
34
|
-
['nested-defer', `import {A} from './x'\nfunction C(){ return <Defer when={a}><Defer when={b}><A/></Defer></Defer> }`],
|
|
35
|
-
['text-child', `function C(){ return <Defer when={c}>plain text</Defer> }`],
|
|
36
|
-
['self-closing', `function C(){ return <Defer when={c}/> }`],
|
|
37
|
-
['spread-child', `import {A} from './x'\nfunction C(p){ return <Defer when={c}><A {...p}/></Defer> }`],
|
|
38
|
-
['comment-child', `function C(){ return <Defer when={c}>{/* x */}</Defer> }`],
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
describe('Round 19 — transformDeferInline robustness', () => {
|
|
42
|
-
for (const [name, src] of VALID) {
|
|
43
|
-
it(`emits parseable code: ${name}`, () => {
|
|
44
|
-
let out = ''
|
|
45
|
-
expect(() => {
|
|
46
|
-
out = run(src)
|
|
47
|
-
}).not.toThrow()
|
|
48
|
-
expect(parses(out)).toBe(true)
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
it('malformed input is passed through without throwing (resilience)', () => {
|
|
52
|
-
expect(() => run(`function C(){ return <Defer when={</Defer> }`)).not.toThrow()
|
|
53
|
-
})
|
|
54
|
-
})
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compiler hardening — Round 20 (JS↔Rust equivalence sweep, R11–R19 corpus).
|
|
3
|
-
*
|
|
4
|
-
* The dual backends MUST emit byte-identical output. This sweep locks the
|
|
5
|
-
* adversarial corpus surfaced in rounds 11–19 where BOTH backends agree, so a
|
|
6
|
-
* future one-backend change that introduces a divergence (the recurring
|
|
7
|
-
* R7/R13/R15 one-backend-change failure mode) is caught immediately. R11's
|
|
8
|
-
* and R13's fixes CONVERGED the backends (R11 brought JS onto the
|
|
9
|
-
* already-correct Rust; R13's gate/collector fix realigned native with JS,
|
|
10
|
-
* which also resolved the R15 element-const×prop-derived divergence) — those
|
|
11
|
-
* shapes must now stay identical, asserted here. The earlier self-
|
|
12
|
-
* discriminating `it.fails` divergence locks auto-flipped on resolution and
|
|
13
|
-
* were removed; R15's residual is a deterministic JS-backend
|
|
14
|
-
* characterization (r15-elemconst-propderived.test.ts).
|
|
15
|
-
*/
|
|
16
|
-
import { describe, expect, it } from 'vitest'
|
|
17
|
-
import { transformJSX, transformJSX_JS } from '../jsx'
|
|
18
|
-
|
|
19
|
-
const EQUIVALENT: Array<[string, string]> = [
|
|
20
|
-
// R11 — signal-auto-call shadowing (JS converged to Rust)
|
|
21
|
-
['r11-destructured-param', `function C(){ const x = signal(0); return <ul>{[{x:1}].map(({x}) => <li>{x}</li>)}</ul> }`],
|
|
22
|
-
['r11-filter-obj-param', `function C(){ const id = signal(0); return <ul>{[{id:1}].filter(({id}) => id > 0).map(r => <li>{r}</li>)}</ul> }`],
|
|
23
|
-
['r11-plain-param-shadow', `function C(){ const s = signal(0); return <ul>{[1].map(s => <li>{s}</li>)}</ul> }`],
|
|
24
|
-
['r11-direct-signal', `function C(){ const s = signal(0); return <div>{s}</div> }`],
|
|
25
|
-
['r11-signal-shadow-sibling', `function C(){ const s = signal(0); return <div>{[1].map(s => <i>{s}</i>)}<b>{s}</b></div> }`],
|
|
26
|
-
// R16 — knownSignals (cross-module signal) path
|
|
27
|
-
['r16-knownsignal-shadow', `function C(){ return <ul>{[{count:1}].map(({count}) => <li>{count}</li>)}</ul> }`],
|
|
28
|
-
// R15 — element-const interactions that DO converge
|
|
29
|
-
['r15-simple-elem-const', `function C(){ const h=<h1>T</h1>; return <div>{h}<p>x</p></div> }`],
|
|
30
|
-
['r15-elem-const-reused', `function C(){ const ic=<svg/>; return <div>{ic}<span>{ic}</span></div> }`],
|
|
31
|
-
// R17 — spread depth
|
|
32
|
-
['r17-root-spread-reactive', `function C(p){ const s=signal(0); return <div {...p} onClick={()=>s.set(1)}>{s}</div> }`],
|
|
33
|
-
['r17-component-spread-pd', `function C(p){ const c=p.x+'-b'; return <Comp {...p} class={c}/> }`],
|
|
34
|
-
['r17-double-spread', `function C(p){ return <div {...p.a} {...p.b}>{p.c}</div> }`],
|
|
35
|
-
// R18 — hoisting × elementVars
|
|
36
|
-
['r18-hoist-vs-elemconst', `function C(){ const e=<b>x</b>; return <div>{<i/>}{e}</div> }`],
|
|
37
|
-
['r18-elemconst-reused-3x', `function C(){ const e=<hr/>; return <div>{e}{e}{e}</div> }`],
|
|
38
|
-
// R13 — the convergent control (return-body callback)
|
|
39
|
-
['r13-return-cb', `function C(p){ const c=p.x+'-b'; return <ul>{p.i.map(i => { return <li class={c}>{i}</li> })}</ul> }`],
|
|
40
|
-
// general
|
|
41
|
-
['mixed', `function C(p){ const a=p.x; return <section><h1>{a}</h1>{p.i.map(i=><p key={i.id}>{i.t}</p>)}</section> }`],
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
describe('Round 20 — JS↔Rust byte-equivalence (R11–R19 corpus)', () => {
|
|
45
|
-
for (const [name, code] of EQUIVALENT) {
|
|
46
|
-
it(`${name}: JS ≡ Rust`, () => {
|
|
47
|
-
expect(transformJSX(code, 'c.tsx').code).toBe(transformJSX_JS(code, 'c.tsx').code)
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
})
|