lib/zen/src/diagram/document/test.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const subject = @import("root.zig");
3 const Document = subject.Document;
4 const Plan = subject.Plan;
5 const Storage = subject.Storage;
6 const parse = subject.parse;
7
8 test "diagram Document storage rejects both exact-region max plus one limits" {
9 comptime {
10 @stardustClaim(
11 @import("alloc_phase").capacity.witness(@import("./root.zig").Storage, "zen_diagram_document_boundaries"),
12 null,
13 null,
14 null,
15 null,
16 null,
17 null,
18 );
19 }
20
21 const jsonl = "{\"kind\":\"point\",\"x\":1,\"y\":2}";
22 const line_scratch_bytes = try Plan.requiredLineScratchBytes(jsonl);
23 const line_scratch = try std.testing.allocator.alloc(u8, line_scratch_bytes);
24 defer std.testing.allocator.free(line_scratch);
25 const plan = try Plan.inspect(line_scratch, jsonl);
26
27 var short_scratch = try Storage.init(std.testing.allocator, .{
28 .max_line_scratch_bytes = plan.line_scratch_bytes - 1,
29 .max_document_bytes = plan.document_bytes,
30 });
31 defer short_scratch.deinit(std.testing.allocator);
32 short_scratch.activate();
33 const scratch_document_hash = std.hash.Wyhash.hash(0, short_scratch.document_bytes);
34 try std.testing.expectError(
35 error.DiagramLineScratchCapacityExceeded,
36 parse(&short_scratch, jsonl),
37 );
38 try std.testing.expectEqual(
39 scratch_document_hash,
40 std.hash.Wyhash.hash(0, short_scratch.document_bytes),
41 );
42
43 var short_document = try Storage.init(std.testing.allocator, .{
44 .max_line_scratch_bytes = plan.line_scratch_bytes,
45 .max_document_bytes = plan.document_bytes - 1,
46 });
47 defer short_document.deinit(std.testing.allocator);
48 short_document.activate();
49 const short_document_hash = std.hash.Wyhash.hash(0, short_document.document_bytes);
50 try std.testing.expectError(
51 error.DiagramDocumentCapacityExceeded,
52 parse(&short_document, jsonl),
53 );
54 try std.testing.expectEqual(
55 short_document_hash,
56 std.hash.Wyhash.hash(0, short_document.document_bytes),
57 );
58 }
59
60 test "diagram Document storage reuses stable regions after success and drop" {
61 comptime {
62 @stardustClaim(
63 @import("alloc_phase").capacity.witness(@import("./root.zig").Storage, "zen_diagram_document_reuse"),
64 null,
65 null,
66 null,
67 null,
68 null,
69 null,
70 );
71 }
72
73 const first_jsonl =
74 \\{"kind":"frame","title":"First"}
75 \\{"kind":"bar","x":"a","y":1}
76 ;
77 var storage = try Storage.initExact(std.testing.allocator, first_jsonl);
78 defer storage.deinit(std.testing.allocator);
79 const line_address = @intFromPtr(storage.line_scratch.ptr);
80 const document_address = @intFromPtr(storage.document_bytes.ptr);
81 storage.activate();
82
83 const first = try parse(&storage, first_jsonl);
84 try std.testing.expectEqualStrings("First", first.frame.title);
85 try std.testing.expectError(
86 error.DiagramDocumentStorageInUse,
87 parse(&storage, first_jsonl),
88 );
89 storage.reset();
90 try std.testing.expectError(error.InvalidJsonl, parse(&storage, "invalid"));
91 const second = try parse(&storage, first_jsonl);
92 try std.testing.expectEqualStrings("First", second.frame.title);
93 try std.testing.expectEqual(line_address, @intFromPtr(storage.line_scratch.ptr));
94 try std.testing.expectEqual(document_address, @intFromPtr(storage.document_bytes.ptr));
95 storage.reset();
96
97 const status = storage.status();
98 try std.testing.expect(!status.in_use);
99 try std.testing.expectEqual(@as(u64, 2), status.rejected_document_count);
100 try std.testing.expect(status.high_water_line_scratch_bytes > 0);
101 try std.testing.expect(status.high_water_document_bytes > 0);
102 }
103
104 test "activated diagram Document parsing performs no backing allocation" {
105 comptime {
106 @stardustClaim(
107 @import("alloc_phase").capacity.witness(@import("./root.zig").Storage, "zen_diagram_document_sealed"),
108 null,
109 null,
110 null,
111 null,
112 null,
113 null,
114 );
115 }
116
117 const jsonl =
118 \\{"kind":"frame","title":"Sealed"}
119 \\{"kind":"point","x":1,"y":2,"label":"ready"}
120 ;
121 var phase_allocator = try @import("alloc_phase").SealedPhaseAllocator.init(
122 std.testing.allocator,
123 );
124 var maybe_storage: ?Storage = null;
125 defer {
126 if (phase_allocator.phase() == .initialization) {
127 phase_allocator.abortInitialization();
128 }
129 if (phase_allocator.phase() == .steady) phase_allocator.beginTeardown();
130 if (maybe_storage) |*storage| {
131 if (storage.in_use) storage.reset();
132 if (storage.phase != .teardown) {
133 storage.deinit(phase_allocator.teardownAllocator());
134 }
135 }
136 phase_allocator.deinit();
137 }
138
139 maybe_storage = try Storage.initExact(
140 phase_allocator.initializationAllocator(),
141 jsonl,
142 );
143 phase_allocator.seal();
144 const storage = &maybe_storage.?;
145 storage.activate();
146 const document = try parse(storage, jsonl);
147 try std.testing.expectEqualStrings("Sealed", document.frame.title);
148 storage.reset();
149 try std.testing.expectError(error.InvalidJsonl, parse(storage, "invalid"));
150 const reused = try parse(storage, jsonl);
151 try std.testing.expectEqualStrings("ready", reused.marks.items[0].point.label);
152 storage.reset();
153 }