Purpose: Ensure the same proto definitions produce semantically identical JSON across go-http, go-client, ts-client, and OpenAPI. The server must serialize what clients expect, and OpenAPI must document what both produce. This is the final validation for Phase 6.
Output: Cross-generator consistency tests that verify JSON output matches between generators, TypeScript types match Go serialization, and OpenAPI schemas accurately reflect the serialization behavior.
<execution_context> @/Users/sebastienmelki/.claude/get-shit-done/workflows/execute-plan.md @/Users/sebastienmelki/.claude/get-shit-done/templates/summary.md </execution_context>
Existing consistency test patterns from Phase 4 and 5 to follow exactly
@internal/httpgen/encoding_consistency_test.go @internal/httpgen/nullable_consistency_test.go @internal/httpgen/empty_behavior_consistency_test.go
The test file should contain these test functions (following the split-test pattern from D-04-05-01):
-
TestGoGeneratorsProduceIdenticalTimestampFormat -- Compare golden files:
- Read httpgen golden file:
testdata/golden/timestamp_format_timestamp_format.pb.go - Read clientgen golden file:
../clientgen/testdata/golden/timestamp_format_timestamp_format.pb.go - Normalize generator comments using normalizeGeneratorComment (from encoding_consistency_test.go)
- Assert byte-level equality after normalization
- Read httpgen golden file:
-
TestTimestampFormatTypeScriptTypes -- Verify TS type mapping:
- Read tsclientgen golden file for timestamp_format
- Verify UNIX_SECONDS and UNIX_MILLIS fields use
numbertype - Verify RFC3339 and DATE fields use
stringtype - Verify default (unannotated) Timestamp fields use
stringtype
-
TestTimestampFormatOpenAPISchemas -- Verify OpenAPI schemas:
- Read openapiv3 golden file for timestamp_format
- Verify UNIX_SECONDS field has
type: integer, format: unix-timestamp - Verify UNIX_MILLIS field has
type: integer, format: unix-timestamp-ms - Verify DATE field has
type: string, format: date - Verify RFC3339/default fields have
type: string, format: date-time
-
TestTimestampFormatCrossGeneratorAgreement -- Cross-check all generators agree:
- For each timestamp format variant, verify:
- Go type in generated code matches TS type expectation
- OpenAPI schema type matches what Go will actually produce
- Table-driven test with one row per format:
testCases := []struct { format string goProducesType string // "integer" or "string" tsType string // "number" or "string" openapiType string // "integer" or "string" openapiFormat string // "unix-timestamp", "date-time", etc. }{ {"UNIX_SECONDS", "integer", "number", "integer", "unix-timestamp"}, {"UNIX_MILLIS", "integer", "number", "integer", "unix-timestamp-ms"}, {"DATE", "string", "string", "string", "date"}, {"RFC3339", "string", "string", "string", "date-time"}, {"default", "string", "string", "string", "date-time"}, } - Parse golden files to extract actual types and formats per field
- Compare against expected values
- For each timestamp format variant, verify:
Implementation approach: Read golden files from disk (same as existing consistency tests). Parse Go golden for MarshalJSON patterns, TS golden for type declarations, OpenAPI golden for schema definitions. Use string matching and regex patterns.
go test -v -run TestTimestampFormat ./internal/httpgen/...
make lint-fix-
TestGoGeneratorsProduceIdenticalBytesEncoding -- Compare golden files:
- Read httpgen golden file:
testdata/golden/bytes_encoding_bytes_encoding.pb.go - Read clientgen golden file:
../clientgen/testdata/golden/bytes_encoding_bytes_encoding.pb.go - Normalize generator comments
- Assert byte-level equality after normalization
- Read httpgen golden file:
-
TestBytesEncodingTypeScriptTypes -- Verify TS types:
- Read tsclientgen golden file for bytes_encoding
- Verify ALL bytes encoding variants produce
stringtype in TypeScript - No encoding variant should produce any type other than string
-
TestBytesEncodingOpenAPISchemas -- Verify OpenAPI schemas:
- Read openapiv3 golden file for bytes_encoding
- Verify HEX field has
format: hexandpattern: ^[0-9a-fA-F]*$ - Verify BASE64_RAW has
format: bytewith description about no padding - Verify BASE64URL has
format: base64url - Verify BASE64URL_RAW has
format: base64urlwith description about no padding - Verify default/BASE64 has
format: byte
-
TestBytesEncodingCrossGeneratorAgreement -- Cross-check all generators agree:
- Table-driven test with one row per encoding:
testCases := []struct { encoding string tsType string // always "string" openapiType string // always "string" openapiFormat string // "byte", "hex", "base64url" }{ {"HEX", "string", "string", "hex"}, {"BASE64_RAW", "string", "string", "byte"}, {"BASE64URL", "string", "string", "base64url"}, {"BASE64URL_RAW", "string", "string", "base64url"}, {"BASE64", "string", "string", "byte"}, {"default", "string", "string", "byte"}, } - Parse golden files to extract actual types and formats
- Compare against expected values
- Table-driven test with one row per encoding:
Implementation approach: Same as timestamp_format -- read golden files, parse patterns, compare.
go test -v -run TestBytesEncoding ./internal/httpgen/...
make lint-fix- All existing tests still pass (zero regression)
- All new consistency tests pass
- All golden files are up to date
- Lint is clean
# Full test suite
go test ./...
# Specific generator tests
go test -v ./internal/httpgen/... ./internal/clientgen/... ./internal/tsclientgen/... ./internal/openapiv3/...
# Golden file tests
go test -v -run TestExhaustiveGoldenFiles ./internal/...
# All consistency tests (Phase 4, 5, and 6)
go test -v -run "Consistency|Identical" ./internal/httpgen/...
# Lint check
make lint-fixVerify that:
- timestamp_format and bytes_encoding golden files exist for all 4 generators
- Generated code matches expected golden output
- Cross-generator consistency verified for all data encoding combinations
- No regressions in any Phase 4 or Phase 5 tests
If any test fails, debug and fix. The consistency tests are the final gate ensuring Phase 6 success criteria 6 is met.
go test ./...
make lint-fixAll tests pass, lint clean, no regressions.
- All 4 generators produce consistent output for timestamp_format fields
- All 4 generators produce consistent output for bytes_encoding fields
- go-http and go-client produce byte-identical encoding code for both features
- TypeScript types match Go serialization for all format/encoding combinations
- OpenAPI schemas match Go serialization for all format/encoding combinations
- All Phase 4 and Phase 5 consistency tests still pass (zero regression)
- Full test suite passes
- Lint clean
<success_criteria>
- go-http and go-client produce byte-identical code for timestamp_format and bytes_encoding
- All 4 timestamp formats produce correct types in all 4 generators
- All 5 bytes encodings produce correct formats in all 4 generators
- OpenAPI format field accurately reflects the wire encoding
- Zero regressions in existing tests (Phase 1-5)
- Phase 6 success criterion 6 met: cross-generator consistency test confirms agreement </success_criteria>
