clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

jsonl consistency fix

Dami committed db27b89
commit
db27b8913f992160fb3b7f1c7f23eb720387ba10
parent
d5dce2873385e4a3fbecbe1d35945f08d2085e40
author
Dami <dami.etoile@gmail.com>
2 files changed, +91 -9
Mpdfexport/jsonl.go27+++++++----
Mpdfexport/jsonl_test.go73++++++++++++++++++++++++++++++
M pdfexport/jsonl.go +18 -9
@@ -85,15 +85,6 @@ func ParseJSONLFile(path string) (PackDocument, error) {
8585 return PackDocument{}, fmt.Errorf("%s:%d: unsupported schema %q", path, lineNo, record.Schema)8686 }8787 88- if doc.Metadata.GeneratedRaw == "" {89- doc.Metadata.GeneratedRaw = record.Pack.Generated90- doc.Metadata.Version = record.Pack.Version91- doc.Metadata.Category = record.Pack.Category92- doc.Metadata.ModeSelection = record.Pack.ModeSelection93- doc.Metadata.Count = record.Pack.Count94- doc.Metadata.Seed = record.Pack.Seed95- }96-9788 category := strings.TrimSpace(record.Puzzle.Game)9889 if category == "" {9990 category = strings.TrimSpace(record.Pack.Category)
@@ -126,6 +117,24 @@ func ParseJSONLFile(path string) (PackDocument, error) {
126117 }127118 p.PrintPayload = payload128119 120+ // Metadata should reflect the first printable record, not merely the121+ // first syntactically valid line in the file.122+ if doc.Metadata.GeneratedRaw == "" {123+ doc.Metadata.GeneratedRaw = record.Pack.Generated124+ doc.Metadata.Version = record.Pack.Version125+ doc.Metadata.Count = record.Pack.Count126+ doc.Metadata.Seed = record.Pack.Seed127+128+ doc.Metadata.Category = strings.TrimSpace(p.Category)129+ if doc.Metadata.Category == "" {130+ doc.Metadata.Category = record.Pack.Category131+ }132+ doc.Metadata.ModeSelection = strings.TrimSpace(p.ModeSelection)133+ if doc.Metadata.ModeSelection == "" {134+ doc.Metadata.ModeSelection = record.Pack.ModeSelection135+ }136+ }137+129138 puzzles = append(puzzles, p)130139 }131140
M pdfexport/jsonl_test.go +73 -0
@@ -352,6 +352,79 @@ func TestParseJSONLFileSilentlySkipsUnsupportedGame(t *testing.T) {
352352 }353353 }354354 355+func TestParseJSONLFileMetadataFromFirstPrintableRecord(t *testing.T) {356+ path := filepath.Join(t.TempDir(), "mixed.jsonl")357+358+ records := []JSONLRecord{359+ {360+ Schema: ExportSchemaV1,361+ Pack: JSONLPackMeta{362+ Generated: "2026-02-22T10:00:00Z",363+ Version: "v-test",364+ Category: "Lights Out",365+ ModeSelection: "Standard",366+ Count: 2,367+ Seed: "seed-unsupported",368+ },369+ Puzzle: JSONLPuzzle{370+ Index: 1,371+ Name: "glow-shore",372+ Game: "Lights Out",373+ Mode: "Standard",374+ Save: json.RawMessage(`{"size":5}`),375+ },376+ },377+ {378+ Schema: ExportSchemaV1,379+ Pack: JSONLPackMeta{380+ Generated: "2026-02-22T10:00:00Z",381+ Version: "v-test",382+ Category: "Sudoku",383+ ModeSelection: "Easy",384+ Count: 2,385+ Seed: "seed-supported",386+ },387+ Puzzle: JSONLPuzzle{388+ Index: 2,389+ Name: "moss-pine",390+ Game: "Sudoku",391+ Mode: "Easy",392+ Save: json.RawMessage(`{"provided":[{"x":0,"y":0,"v":5}]}`),393+ },394+ },395+ }396+397+ var lines []byte398+ for _, record := range records {399+ line, err := json.Marshal(record)400+ if err != nil {401+ t.Fatal(err)402+ }403+ lines = append(lines, line...)404+ lines = append(lines, '\n')405+ }406+ if err := os.WriteFile(path, lines, 0o644); err != nil {407+ t.Fatal(err)408+ }409+410+ doc, err := ParseJSONLFile(path)411+ if err != nil {412+ t.Fatalf("expected parse success, got: %v", err)413+ }414+ if got, want := len(doc.Puzzles), 1; got != want {415+ t.Fatalf("puzzles = %d, want %d", got, want)416+ }417+ if got, want := doc.Metadata.Category, "Sudoku"; got != want {418+ t.Fatalf("metadata category = %q, want %q", got, want)419+ }420+ if got, want := doc.Metadata.ModeSelection, "Easy"; got != want {421+ t.Fatalf("metadata mode = %q, want %q", got, want)422+ }423+ if got, want := doc.Metadata.Seed, "seed-supported"; got != want {424+ t.Fatalf("metadata seed = %q, want %q", got, want)425+ }426+}427+355428 func writeSingleJSONLRecord(t *testing.T, path string, record JSONLRecord) {356429 t.Helper()357430 data, err := json.Marshal(record)