// SPDX-License-Identifier: MIT package expr import ( "os" "path/filepath" "strings" "testing" ) // TestToJSONGolden checks toJSON(fromJSON(x)) against the output of the // reference implementation for each testdata/tojson/NAME.json. The .golden // files are generated by gen/golden.mjs. func TestToJSONGolden(t *testing.T) { inputs, err := filepath.Glob("testdata/tojson/*.json") if err != nil || len(inputs) < 30 { t.Fatalf("golden inputs: %v (%d found)", err, len(inputs)) } for _, in := range inputs { name := strings.TrimSuffix(filepath.Base(in), ".json") t.Run(name, func(t *testing.T) { text, err := os.ReadFile(in) if err != nil { t.Fatal(err) } // NAME.golden is the answer of the JavaScript reference. Where // the C# runner answers differently, NAME.runner holds its // answer and is what this package follows (see PORTING.md). want, err := os.ReadFile(strings.TrimSuffix(in, ".json") + ".runner") fromRunner := err == nil if os.IsNotExist(err) { want, err = os.ReadFile(strings.TrimSuffix(in, ".json") + ".golden") } if err != nil { t.Fatal(err) } v, err := FromJSON(text) if err != nil { t.Fatal(err) } if got := ToJSON(v); got != string(want) { t.Errorf("toJSON mismatch\n got: %q\nwant: %q", got, want) } if fromRunner { // The runner's output is not JSON in general: numbers have 15 // significant digits and NaN and Infinity are bare words. return } // The golden output is itself JSON that must round-trip. v2, err := FromJSON(want) if err != nil { t.Fatalf("golden output does not parse: %v", err) } if got := ToJSON(v2); got != string(want) { t.Errorf("toJSON is not stable\n got: %q\nwant: %q", got, want) } }) } }