lib/zen/src/diagram/test.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 const std = @import("std");
  2 const subject = @import("root.zig");
  3 const ascii_test = @import("ascii/test.zig");
  4 const document_test = @import("document/test.zig");
  5 const ego_test = @import("ego/test.zig");
  6 const Document = subject.Document;
  7 const AsciiRenderPlan = subject.AsciiRenderPlan;
  8 const AsciiRenderCapacity = subject.AsciiRenderCapacity;
  9 const AsciiRenderStorage = subject.AsciiRenderStorage;
 10 const DocumentPlan = subject.DocumentPlan;
 11 const DocumentCapacity = subject.DocumentCapacity;
 12 const DocumentStorage = subject.DocumentStorage;
 13 const parse = subject.parse;
 14 const renderAsciiOwned = subject.renderAsciiOwned;
 15 const renderAsciiDocument = subject.renderAsciiDocument;
 16 
 17 test "diagram root exposes bounded ASCII rendering controls" {
 18     comptime {
 19         @stardustClaim(
 20             @import("alloc_phase").capacity.witness(@import("./ascii/root.zig").RenderStorage, "zen_ascii_render_root"),
 21             null,
 22             null,
 23             null,
 24             null,
 25             null,
 26             null,
 27         );
 28     }
 29 
 30     var empty_document = Document{ .allocator = std.testing.allocator };
 31     defer empty_document.deinit();
 32     const plan = try AsciiRenderPlan.inspect(&empty_document, .{ .width = 24, .height = 8 });
 33     var storage = try AsciiRenderStorage.init(std.testing.allocator, plan.exactLimits());
 34     defer storage.deinit(std.testing.allocator);
 35     storage.activate();
 36     const output = try renderAsciiDocument(&storage, &empty_document, .{ .width = 24, .height = 8 });
 37     defer storage.reset();
 38     try std.testing.expectEqual(@as(usize, 8), std.mem.count(u8, output, "\n"));
 39     try std.testing.expectEqual(
 40         (try AsciiRenderCapacity.derive(plan.exactLimits())).storage_bytes,
 41         storage.status().storage_bytes,
 42     );
 43 }
 44 
 45 test "diagram root exposes bounded Document parsing controls" {
 46     comptime {
 47         @stardustClaim(
 48             @import("alloc_phase").capacity.witness(@import("./document/root.zig").Storage, "zen_diagram_document_root"),
 49             null,
 50             null,
 51             null,
 52             null,
 53             null,
 54             null,
 55         );
 56     }
 57 
 58     const jsonl = "{\"kind\":\"point\",\"x\":1,\"y\":2}";
 59     var storage = try DocumentStorage.initExact(std.testing.allocator, jsonl);
 60     defer storage.deinit(std.testing.allocator);
 61     storage.activate();
 62     const parsed = try parse(&storage, jsonl);
 63     defer storage.reset();
 64     try std.testing.expectEqual(@as(usize, 1), parsed.marks.items.len);
 65     try std.testing.expectEqual(
 66         (try DocumentCapacity.derive(storage.capacity.limits)).storage_bytes,
 67         storage.status().storage_bytes,
 68     );
 69 }
 70 
 71 fn expectBoundedDocumentError(jsonl: []const u8, expected: anyerror) !void {
 72     var storage = DocumentStorage.initExact(std.testing.allocator, jsonl) catch |err| {
 73         try std.testing.expectEqualStrings(@errorName(expected), @errorName(err));
 74         return;
 75     };
 76     defer storage.deinit(std.testing.allocator);
 77     storage.activate();
 78     _ = parse(&storage, jsonl) catch |err| {
 79         try std.testing.expectEqualStrings(@errorName(expected), @errorName(err));
 80         return;
 81     };
 82     storage.reset();
 83     return error.TestUnexpectedResult;
 84 }
 85 
 86 fn expectDocumentParity(jsonl: []const u8) !void {
 87     const scratch_bytes = try DocumentPlan.requiredLineScratchBytes(jsonl);
 88     const scratch = try std.testing.allocator.alloc(u8, scratch_bytes);
 89     defer std.testing.allocator.free(scratch);
 90     var raw = Document.parse(std.testing.allocator, scratch, jsonl) catch |err| {
 91         return expectBoundedDocumentError(jsonl, err);
 92     };
 93     defer raw.deinit();
 94 
 95     var storage = try DocumentStorage.initExact(std.testing.allocator, jsonl);
 96     defer storage.deinit(std.testing.allocator);
 97     storage.activate();
 98     const bounded = try parse(&storage, jsonl);
 99     defer storage.reset();
100 
101     var raw_rendered = try renderAsciiOwned(
102         std.testing.allocator,
103         &raw,
104         .{ .width = 48, .height = 14 },
105     );
106     defer raw_rendered.deinit(std.testing.allocator);
107     var bounded_rendered = try renderAsciiOwned(
108         std.testing.allocator,
109         bounded,
110         .{ .width = 48, .height = 14 },
111     );
112     defer bounded_rendered.deinit(std.testing.allocator);
113     try std.testing.expectEqualStrings(raw_rendered.output, bounded_rendered.output);
114     try std.testing.expectEqualStrings(raw.frame.title, bounded.frame.title);
115     try std.testing.expectEqualStrings(raw.frame.x_label, bounded.frame.x_label);
116     try std.testing.expectEqualStrings(raw.frame.y_label, bounded.frame.y_label);
117     try std.testing.expectEqualStrings(raw.frame.background, bounded.frame.background);
118     try std.testing.expectEqualStrings(raw.scales.x.label, bounded.scales.x.label);
119     try std.testing.expectEqualStrings(raw.scales.y.label, bounded.scales.y.label);
120     try std.testing.expectEqual(raw.transforms.items.len, bounded.transforms.items.len);
121     try std.testing.expectEqual(raw.data.items.len, bounded.data.items.len);
122     try std.testing.expectEqual(raw.marks.items.len, bounded.marks.items.len);
123     for (raw.data.items, bounded.data.items) |raw_row, bounded_row| {
124         try std.testing.expectEqualStrings(raw_row.name, bounded_row.name);
125         try std.testing.expectEqual(raw_row.fields.items.len, bounded_row.fields.items.len);
126         for (raw_row.fields.items, bounded_row.fields.items) |raw_field, bounded_field| {
127             try std.testing.expectEqualStrings(raw_field.name, bounded_field.name);
128         }
129     }
130 }
131 
132 test "bounded and raw diagram parsing preserve output bytes and errors" {
133     comptime {
134         @stardustClaim(
135             @import("alloc_phase").capacity.witness(@import("./document/root.zig").Storage, "zen_diagram_document_differential"),
136             null,
137             null,
138             null,
139             null,
140             null,
141             null,
142         );
143     }
144 
145     const cases = [_][]const u8{
146         "",
147         "{\"kind\":\"point\",\"x\":1,\"y\":2,\"label\":\"one\"}\n",
148         "{\"kind\":\"frame\",\"title\":\"Bytes <&>\",\"x_label\":\"phase\",\"y_label\":\"count\",\"background\":\"#ffffff\"}\n" ++
149             "{\"kind\":\"scale\",\"axis\":\"y\",\"type\":\"linear\",\"min\":1,\"max\":100,\"label\":\"events\"}\n" ++
150             "{\"kind\":\"transform\",\"op\":\"stack\",\"mark\":\"bar\"}\n" ++
151             "{\"kind\":\"bar\",\"x\":\"a\",\"y\":10,\"series\":\"first\",\"label\":\"A\"}\n" ++
152             "{\"kind\":\"rule\",\"x1\":0,\"y1\":1,\"x2\":2,\"y2\":1,\"label\":\"limit\"}\n",
153         "{\"kind\":\"data\",\"name\":\"d\",\"x\":\"alpha\",\"y\":3,\"label\":\"A\",\"enabled\":true}\n" ++
154             "{\"kind\":\"mark\",\"type\":\"bar\",\"data\":\"d\",\"x\":\"x\",\"y\":\"y\",\"label\":\"label\"}\n",
155         "not json",
156         "{\"x\":1}",
157         "[1,2]",
158         "{\"kind\":\"unknown\"}",
159         "{\"kind\":\"bar\",\"x\":\"a\"}",
160         "{\"kind\":\"bar\",\"x\":\"a\",\"y\":1,\"fill\":\"url(x)\"}",
161         "{\"kind\":\"scale\",\"axis\":\"y\",\"type\":\"log\",\"min\":0}",
162         "{\"kind\":\"mark\",\"type\":\"bar\",\"data\":\"missing\",\"x\":\"x\",\"y\":\"y\"}",
163     };
164     for (cases) |jsonl| try expectDocumentParity(jsonl);
165 }
166 
167 test {
168     std.testing.refAllDecls(subject);
169     std.testing.refAllDecls(ascii_test);
170     std.testing.refAllDecls(document_test);
171     std.testing.refAllDecls(ego_test);
172 }