ReviewOS

stacks/stx

test(stx-native): 8,012 lines and zero tests — the compiler's IR output is unprotected

#1986
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Summary

packages/stx-native is 8,012 lines with no tests. The compiler works — it is the most valuable thing in the package — and nothing protects it.

Evidence

$ find packages/stx-native -name "*.test.ts" -not -path "*/node_modules/*" | wc -l
0

Line counts:

FileLines
src/renderers/android.kt1,305
src/cli/index.ts799
src/renderers/ios.swift765
src/compiler/parser.ts742
src/compiler/headwind-to-style.ts708
src/bridge/protocol.ts682
src/bridge/android-bridge.kt627
src/hot-reload/client.ts547
src/components/primitives.ts491
src/bridge/ios-bridge.swift484
src/runtime/index.ts361
src/compiler/ir.ts319

Untested code that has never run is not a head start; it is inventory. The CLI's syntax error is the proof — it sat in the repo because nothing executed it.

What to test first

compileSTX produces correct IR today, and its output is a JSON tree — ideal for golden tests. A verified starting fixture:

<View class="flex-1 flex-col justify-center items-center p-4 bg-blue-500">
  <Text class="text-white text-lg font-bold">Wildloop</Text>
</View>
{ "type": "View", "style": { "flex": 1, "flexDirection": "column", "justifyContent": "center",
  "alignItems": "center", "padding": 16, "backgroundColor": "#3b82f6" }, "children": [
  { "type": "Text", "style": { "color": "#ffffff", "fontSize": 18, "fontWeight": "bold" } } ] }

Ask

  1. Golden tests over compileHeadwindToStyle for each supported class family — spacing, flex, colour, radius, typography. This is the part a refactor breaks silently.
  2. Golden tests over compileSTX for a handful of representative trees, asserting the IR shape.
  3. A test that every component type in mapToNativeComponent has a renderer branch in both ios.swift and android.kt, so the two platforms cannot drift apart unnoticed.
9 days ago

Part of #1992 (stx-native: native views for wildloop).

9 days ago

Done in 24128af — 49 tests over the three asks, and the third one found two real gaps on its first run.

First, a correction to the premise

"Zero tests" is no longer true — cli.test.ts, capability-protocol.test.ts and bridge-protocol.test.ts landed with the typed-capability work. But they cover the CLI and the bridge, so the compiler was still untested, which is the part this issue is actually about. The line count holds: ~8,600 across TypeScript, Kotlin and Swift.

1 & 2 — style and IR goldens

24 style cases, one per family and spelling (spacing all-sides / axis / single-edge, flex grow / direction / justify / align, colour background and text, typography size and both weight spellings, radius, percentage and scale sizing, opacity, position, display), plus merging across families, last-wins on a repeated family, and an unknown class producing {} rather than throwing or inventing a property.

The reference tree from the issue is pinned exactly as given, along with _classes and _source — the metadata that turns a wrong style into a findable line.

3 — renderer coverage, which found the drift

Reading the dispatch out of each renderer:

types
iOSView, Text, Button, TextInput, Image, ScrollView, TouchableOpacity, Switch, ActivityIndicator, SafeAreaView
Androidthe same ten, plus FlatList, Modal, Slider

So a template using <list>, <modal> or <slider> renders on Android and silently does not on iOS. That is a difference only a device shows, which is exactly why it went unnoticed and exactly what this ask was for.

Second gap, which I did not expect: Picker is rendered by neither platform, yet mapToNativeComponent maps both <picker> and <select> to it. A form written with <select> compiles to a node nothing can draw, anywhere.

Both are named in the test rather than asserted away, so the lists can only shrink — adding a renderer makes the test fail until the name comes off it. New drift fails immediately.

What I did not do

I did not write the three missing Swift renderers or the two Picker ones. That is real platform work, and nothing in this repo can execute Swift or Kotlin, so I would be shipping code no test here can run — which is the failure mode this issue opens with. Worth its own issue; the test now says precisely what is missing.

Full suite 14765 pass.

9 days ago

Extended in 32c6075 with the half the original asks could not reach, then closing this.

Ask 3 was "every component type in mapToNativeComponent has a renderer branch in both" — which caught the component drift (iOS missing FlatList, Modal, Slider; Picker rendered by neither). But a component gap at least falls through a switch. The style equivalent cannot announce itself at all: a property the compiler emits and a renderer does not read is simply absent, because Swift's Codable ignores unknown keys. It decodes into nothing and the view lays out as though the class had never been written.

style properties
IR declares80
android.kt refers to68
ios.swift declares52

28 dropped on iOS, including lineHeight, letterSpacing, fontFamily, overflow, zIndex, transform, aspectRatio and every per-edge border. Pinned in both directions now — a field declared on iOS that the compiler cannot emit would be dead weight or a one-sided rename, and that direction is clean today.

52 tests total on the compiler. Closing: the three asks are covered, and the drift they exist to catch is now named rather than latent.

Sign in to comment on this issue.