Skip to content

Commit bd5f8a2

Browse files
stainluclaude
andcommitted
test: TS emitter handles chat fixture (discriminated unions) tsc-clean
Verified that the v0.1 TS emitter — scoped to OneBusAway-style schemas — also generates tsc-clean output for the chat fixture (oneOf discriminated unions + JSON request body) AND the full public openai- openapi spec (162 paths, 983 schemas, 22 resources). The scope is substantially broader than initially planned for a v0.1 slice. What's covered by the v0.1 TS emitter: - Simple types (primitives, arrays, maps, enums, unions, nulls, refs) - Object types (interfaces with dot-quoted property names where the wire key isn't a TS identifier) - HTTP methods: GET / POST / PUT / PATCH / DELETE - Path params + query params + JSON request/response bodies - Nested subresources (constructor-initialized fields) - Per-resource files, types module, full vendored runtime - Typed error hierarchy re-exported from package root - tsc strict mode passes on OneBusAway + chat fixture + openai spec Caveats (deferred to v0.2-TS): - Streaming methods generate as if non-streaming (return the JSON response type; no Stream<Event> overload) - Discriminated unions render as plain `T1 | T2 | T3` (no runtime discriminator-based parse — works for tsc; not for runtime validation of an unknown JSON payload) - Multipart, binary, pagination, webhook unwrap — all not yet wired - MCP-from-TS — deferred (Python MCP works with the Python SDK today; a TS MCP server is a separate undertaking) - 1 new regression test (`test_chat_fixture_tsc_clean`): chat fixture → tsc-clean - 129 tests green; ruff clean Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 976798b commit bd5f8a2

1 file changed

Lines changed: 28 additions & 8 deletions

File tree

tests/test_typescript_slice.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,11 @@ def _has_npm() -> bool:
102102
return shutil.which("npm") is not None and shutil.which("node") is not None
103103

104104

105-
@pytest.mark.skipif(not _has_npm(), reason="npm/node not available")
106-
def test_generated_sdk_tsc_clean(tmp_path):
107-
"""The whole package type-checks cleanly under TS strict mode. This
108-
is the actual quality bar for the slice."""
109-
root = _gen(tmp_path)
110-
# Install TypeScript locally for this check.
105+
def _tsc_clean(root: Path) -> None:
106+
"""Install TypeScript locally and `tsc --noEmit` the generated SDK.
107+
Raises an assertion error if tsc reports any diagnostics."""
111108
subprocess.run(
112-
["npm", "init", "-y"], cwd=root, check=True,
113-
capture_output=True,
109+
["npm", "init", "-y"], cwd=root, check=True, capture_output=True,
114110
)
115111
subprocess.run(
116112
["npm", "install", "--save-dev", "--no-audit", "--no-fund",
@@ -124,3 +120,27 @@ def test_generated_sdk_tsc_clean(tmp_path):
124120
assert result.returncode == 0, (
125121
f"tsc reported errors:\n{result.stdout}\n{result.stderr}"
126122
)
123+
124+
125+
@pytest.mark.skipif(not _has_npm(), reason="npm/node not available")
126+
def test_generated_sdk_tsc_clean(tmp_path):
127+
"""OneBusAway → tsc-clean TS. This is the actual quality bar for
128+
the v0.1 slice."""
129+
_tsc_clean(_gen(tmp_path))
130+
131+
132+
@pytest.mark.skipif(not _has_npm(), reason="npm/node not available")
133+
def test_chat_fixture_tsc_clean(tmp_path):
134+
"""The chat fixture exercises `oneOf` discriminated unions (events)
135+
and JSON request bodies — broader than OneBusAway's read-only GETs.
136+
Same emitter must handle it tsc-cleanly."""
137+
api = build_ir(
138+
load_spec(str(
139+
Path(__file__).parent / "fixtures" / "chat" / "openapi.yml"
140+
)),
141+
load_config(str(
142+
Path(__file__).parent / "fixtures" / "chat" / "stainless-config.yml"
143+
)),
144+
)
145+
emit_ts(api, str(tmp_path))
146+
_tsc_clean(tmp_path / "chat")

0 commit comments

Comments
 (0)