@voxgig/sdkgen 4.8.3 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/package.json +1 -1
  3. package/project/.sdk/model/target/zig.aon +9 -0
  4. package/project/.sdk/src/cmp/zig/Package_zig.ts +15 -11
  5. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +3 -3
  6. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +3 -3
  7. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +3 -3
  8. package/project/.sdk/src/cmp/zig/utility_zig.ts +50 -1
  9. package/project/.sdk/tm/c/tests/vendor/omni/json.c +2 -2
  10. package/project/.sdk/tm/c/tests/vendor/omni/omni.h +2 -2
  11. package/project/.sdk/tm/c/tests/vendor/omni/runner.c +2 -2
  12. package/project/.sdk/tm/c/tests/vendor/omni/util.c +2 -2
  13. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +2 -2
  14. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +2 -2
  15. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +2 -2
  16. package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +2 -2
  17. package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +2 -2
  18. package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +2 -2
  19. package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +2 -2
  20. package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +2 -2
  21. package/project/.sdk/tm/csharp/utility/struct/Struct.cs +1 -1
  22. package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +2 -2
  23. package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +2 -2
  24. package/project/.sdk/tm/dart/test/vendor/omni/util.dart +2 -2
  25. package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +2 -2
  26. package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +2 -2
  27. package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +2 -2
  28. package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +1 -1
  29. package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +1 -1
  30. package/project/.sdk/tm/go/feature/secrets/plugin/config.go +1 -1
  31. package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +1 -1
  32. package/project/.sdk/tm/go/feature/secrets/plugin/env.go +1 -1
  33. package/project/.sdk/tm/go/feature/secrets/plugin/export.go +1 -1
  34. package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +1 -1
  35. package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1 -1
  36. package/project/.sdk/tm/go/feature/secrets/plugin/order.go +1 -1
  37. package/project/.sdk/tm/go/feature/secrets/plugin/point.go +1 -1
  38. package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +1 -1
  39. package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +1 -1
  40. package/project/.sdk/tm/go/feature/secrets/plugin/types.go +1 -1
  41. package/project/.sdk/tm/go/feature/secrets/plugin/util.go +1 -1
  42. package/project/.sdk/tm/go/feature/secrets/plugin/version.go +1 -1
  43. package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +4 -4
  44. package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +2 -2
  45. package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +2 -2
  46. package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +2 -2
  47. package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +2 -2
  48. package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +2 -2
  49. package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +4 -5
  50. package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +3 -3
  51. package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +3 -4
  52. package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +2 -2
  53. package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +2 -2
  54. package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +2 -2
  55. package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +5 -2
  56. package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +31 -2
  57. package/project/.sdk/tm/go/test/omni/omni.go +8 -3
  58. package/project/.sdk/tm/go/test/omni/util.go +25 -4
  59. package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +1 -1
  60. package/project/.sdk/tm/java/test/vendor/omni/Json.java +2 -2
  61. package/project/.sdk/tm/java/test/vendor/omni/Runner.java +2 -2
  62. package/project/.sdk/tm/java/test/vendor/omni/Util.java +2 -2
  63. package/project/.sdk/tm/java/utility/struct/Struct.java +1 -1
  64. package/project/.sdk/tm/js/src/utility/StructUtility.js +2 -2
  65. package/project/.sdk/tm/js/test/vendor/omni/index.js +1 -1
  66. package/project/.sdk/tm/js/test/vendor/omni/runner.js +18 -3
  67. package/project/.sdk/tm/js/test/vendor/omni/util.js +25 -8
  68. package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +2 -2
  69. package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +2 -2
  70. package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +2 -2
  71. package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +1 -1
  72. package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +2 -2
  73. package/project/.sdk/tm/lua/test/vendor/omni/json.lua +2 -2
  74. package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +2 -2
  75. package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +2 -2
  76. package/project/.sdk/tm/lua/test/vendor/omni/util.lua +2 -2
  77. package/project/.sdk/tm/lua/utility/struct/regex.lua +1 -1
  78. package/project/.sdk/tm/lua/utility/struct/struct.lua +1 -1
  79. package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +2 -2
  80. package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +1 -1
  81. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +1 -1
  82. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +1 -1
  83. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +1 -1
  84. package/project/.sdk/tm/php/test/vendor/omni/Runner.php +2 -2
  85. package/project/.sdk/tm/php/test/vendor/omni/Util.php +2 -2
  86. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +1 -1
  87. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +1 -1
  88. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +1 -1
  89. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +1 -1
  90. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +1 -1
  91. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +1 -1
  92. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +1 -1
  93. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +1 -1
  94. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1 -1
  95. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +1 -1
  96. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +1 -1
  97. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +1 -1
  98. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +1 -1
  99. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +1 -1
  100. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +1 -1
  101. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +3 -1
  102. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +1 -1
  103. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +3 -3
  104. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +1 -1
  105. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +1 -1
  106. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +1 -1
  107. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +1 -1
  108. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +3 -4
  109. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +1 -1
  110. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +4 -6
  111. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +1 -1
  112. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +1 -1
  113. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +1 -1
  114. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +1 -1
  115. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +21 -1
  116. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +1 -1
  117. package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +1 -1
  118. package/project/.sdk/tm/py/test/voxgig_omni/runner.py +16 -2
  119. package/project/.sdk/tm/py/test/voxgig_omni/util.py +27 -12
  120. package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +2 -2
  121. package/project/.sdk/tm/rb/test/vendor/omni/util.rb +2 -2
  122. package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +2 -2
  123. package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +2 -2
  124. package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +2 -2
  125. package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +2 -2
  126. package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +2 -2
  127. package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +2 -2
  128. package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +2 -2
  129. package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +2 -2
  130. package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +2 -2
  131. package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +2 -2
  132. package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +2 -2
  133. package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +2 -2
  134. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +1 -1
  135. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +1 -1
  136. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +1 -1
  137. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +1 -1
  138. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +1 -1
  139. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +1 -1
  140. package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +1 -1
  141. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +1 -1
  142. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1 -1
  143. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +1 -1
  144. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +1 -1
  145. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +1 -1
  146. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +1 -1
  147. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +1 -1
  148. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +1 -1
  149. package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +1 -1
  150. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +1 -1
  151. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +1 -1
  152. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/aws.ts +1 -1
  153. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/azuresecrets.ts +1 -1
  154. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/boru.ts +1 -1
  155. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/doppler.ts +1 -1
  156. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/gcpsecrets.ts +1 -1
  157. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/hashicorp.ts +1 -1
  158. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +1 -1
  159. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/infisical.ts +1 -1
  160. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/onepassword.ts +1 -1
  161. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +1 -1
  162. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/sigv4.ts +1 -1
  163. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +1 -1
  164. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +1 -1
  165. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +1 -1
  166. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +1 -1
  167. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +1 -1
  168. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +1 -1
  169. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +1 -1
  170. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +2 -2
  171. package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +1 -1
  172. package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +1 -1
  173. package/project/.sdk/tm/ts/test/vendor/omni/index.ts +1 -1
  174. package/project/.sdk/tm/zig/Makefile +15 -1
  175. package/project/.sdk/tm/zig/build.zig +23 -5
  176. package/project/.sdk/tm/zig/core/helpers.zig +52 -11
  177. package/project/.sdk/tm/zig/core/mem.zig +17 -1
  178. package/project/.sdk/tm/zig/core/utility.zig +23 -19
  179. package/project/.sdk/tm/zig/feature/audit.zig +2 -2
  180. package/project/.sdk/tm/zig/feature/cache.zig +2 -2
  181. package/project/.sdk/tm/zig/feature/debug.zig +5 -5
  182. package/project/.sdk/tm/zig/feature/netsim.zig +2 -2
  183. package/project/.sdk/tm/zig/feature/paging.zig +2 -2
  184. package/project/.sdk/tm/zig/feature/proxy.zig +15 -8
  185. package/project/.sdk/tm/zig/feature/streaming.zig +5 -5
  186. package/project/.sdk/tm/zig/feature/support.zig +3 -3
  187. package/project/.sdk/tm/zig/feature/telemetry.zig +5 -5
  188. package/project/.sdk/tm/zig/feature/test.zig +10 -5
  189. package/project/.sdk/tm/zig/test/fh.zig +10 -10
  190. package/project/.sdk/tm/zig/test/gotcha_test.zig +5 -5
  191. package/project/.sdk/tm/zig/test/omniresolver.zig +515 -0
  192. package/project/.sdk/tm/zig/test/omnismoke_test.zig +284 -0
  193. package/project/.sdk/tm/zig/test/pipeline_test.zig +8 -8
  194. package/project/.sdk/tm/zig/test/primary_utility_test.zig +144 -154
  195. package/project/.sdk/tm/zig/test/struct_corpus.zig +264 -187
  196. package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +1314 -0
  197. package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +446 -0
  198. package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +7 -4
  199. package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +356 -157
  200. package/project/sdkgen-package.json +1 -1
  201. package/project/.sdk/tm/zig/test/struct_runner.zig +0 -465
@@ -1,14 +1,18 @@
1
1
  // RUN: zig build test
2
2
  // RUN-SOME: zig build test 2>&1 | head
3
3
 
4
- // Test structure mirrors ts/test/utility/StructUtility.test.ts
5
- // Uses shared spec from build/test/test.json via runner.
4
+ // The struct corpus, driven by the VENDORED omni engine through
5
+ // test/omniresolver.zig (see its header for the adapter decisions). Test
6
+ // structure mirrors tm/ts/test/utility/StructUtility.test.ts, and the
7
+ // per-group `null_` flag is that file's, case for case - under omni the flag
8
+ // normalises nulls in the GROUP as well as in the result, so it is part of
9
+ // what a group tests rather than a local convenience.
6
10
 
7
11
  const std = @import("std");
8
12
  const testing = std.testing;
9
13
 
10
14
  const voxgig_struct = @import("voxgig-struct");
11
- const runner = @import("struct_runner.zig");
15
+ const omnirun = @import("omniresolver.zig");
12
16
 
13
17
  const Allocator = std.mem.Allocator;
14
18
  const JsonValue = voxgig_struct.JsonValue;
@@ -16,9 +20,13 @@ const StdJsonValue = std.json.Value;
16
20
 
17
21
  // NOTE: tests are (mostly) in order of increasing dependence.
18
22
 
19
- // Wrap library functions as runner.Subject (fn(StdJsonValue) StdJsonValue).
20
- // All wrappers now use AllocSubject (takes Allocator + our JsonValue).
21
- // The runner converts std.json JsonValue before calling, and back after.
23
+ // The subjects are omniresolver.Subject (Allocator + the struct port's
24
+ // JsonValue in, one JsonValue out); the resolver converts std.json ->
25
+ // JsonValue before the call and back after, and hands the converted-back
26
+ // argument to omni so `match: {args: ...}` can assert on it. A subject that
27
+ // can FAIL takes the extra `*?[]const u8` and is an
28
+ // omniresolver.FallibleSubject - `validate` and `transform` answer
29
+ // {out, err}, and 55 corpus entries assert on the message.
22
30
 
23
31
  fn wrap_isnode(_: Allocator, val: JsonValue) JsonValue {
24
32
  return .{ .bool = voxgig_struct.isnode(val) };
@@ -44,51 +52,42 @@ fn wrap_isfunc(_: Allocator, val: JsonValue) JsonValue {
44
52
  return .{ .bool = voxgig_struct.isfunc(val) };
45
53
  }
46
54
 
47
- // Helper: get a nested spec section (operates on std.json for the test runner).
48
- fn getMinorSpec(r: runner.RunPack, name: []const u8) !StdJsonValue {
49
- const minor = r.spec.get("minor") orelse return error.NoMinorSpec;
50
- return switch (minor) {
51
- .object => |obj| obj.get(name) orelse return error.NoSpec,
52
- else => return error.MinorNotObject,
53
- };
54
- }
55
-
56
55
  // ---- minor tests ----
57
56
 
58
57
  test "minor-isnode" {
59
- var r = try runner.makeRunner(testing.allocator);
58
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
60
59
  defer r.deinit();
61
- try r.runsetAlloc(try getMinorSpec(r, "isnode"), wrap_isnode);
60
+ try r.runsetflags(r.group("minor", "isnode"), .{ .name = "minor/isnode" }, wrap_isnode);
62
61
  }
63
62
 
64
63
  test "minor-ismap" {
65
- var r = try runner.makeRunner(testing.allocator);
64
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
66
65
  defer r.deinit();
67
- try r.runsetAlloc(try getMinorSpec(r, "ismap"), wrap_ismap);
66
+ try r.runsetflags(r.group("minor", "ismap"), .{ .name = "minor/ismap" }, wrap_ismap);
68
67
  }
69
68
 
70
69
  test "minor-islist" {
71
- var r = try runner.makeRunner(testing.allocator);
70
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
72
71
  defer r.deinit();
73
- try r.runsetAlloc(try getMinorSpec(r, "islist"), wrap_islist);
72
+ try r.runsetflags(r.group("minor", "islist"), .{ .name = "minor/islist" }, wrap_islist);
74
73
  }
75
74
 
76
75
  test "minor-iskey" {
77
- var r = try runner.makeRunner(testing.allocator);
76
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
78
77
  defer r.deinit();
79
- try r.runsetAllocFlags(try getMinorSpec(r, "iskey"), .{ .null_flag = false }, wrap_iskey);
78
+ try r.runsetflags(r.group("minor", "iskey"), .{ .name = "minor/iskey", .null_ = false }, wrap_iskey);
80
79
  }
81
80
 
82
81
  test "minor-isempty" {
83
- var r = try runner.makeRunner(testing.allocator);
82
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
84
83
  defer r.deinit();
85
- try r.runsetAllocFlags(try getMinorSpec(r, "isempty"), .{ .null_flag = false }, wrap_isempty);
84
+ try r.runsetflags(r.group("minor", "isempty"), .{ .name = "minor/isempty", .null_ = false }, wrap_isempty);
86
85
  }
87
86
 
88
87
  test "minor-isfunc" {
89
- var r = try runner.makeRunner(testing.allocator);
88
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
90
89
  defer r.deinit();
91
- try r.runsetAlloc(try getMinorSpec(r, "isfunc"), wrap_isfunc);
90
+ try r.runsetflags(r.group("minor", "isfunc"), .{ .name = "minor/isfunc" }, wrap_isfunc);
92
91
  }
93
92
 
94
93
  // ---- Allocator-aware wrappers for new functions ----
@@ -107,7 +106,7 @@ fn wrap_typify(allocator: Allocator, val: JsonValue) JsonValue {
107
106
  _ = allocator;
108
107
  // Handle UNDEF marker (missing input → T_noval)
109
108
  if (val == .string) {
110
- if (std.mem.eql(u8, val.string, runner.UNDEFMARK)) {
109
+ if (std.mem.eql(u8, val.string, omnirun.UNDEFMARK)) {
111
110
  return JsonValue{ .integer = @as(i64, voxgig_struct.T_noval) };
112
111
  }
113
112
  }
@@ -183,7 +182,7 @@ fn wrap_stringify_raw(allocator: Allocator, val: JsonValue) JsonValue {
183
182
  fn wrap_clone(allocator: Allocator, val: JsonValue) JsonValue {
184
183
  // Handle UNDEF marker - return empty object
185
184
  if (val == .string) {
186
- if (std.mem.eql(u8, val.string, runner.UNDEFMARK)) {
185
+ if (std.mem.eql(u8, val.string, omnirun.UNDEFMARK)) {
187
186
  return .null;
188
187
  }
189
188
  }
@@ -332,7 +331,7 @@ fn wrap_stringify(allocator: Allocator, val: JsonValue) JsonValue {
332
331
 
333
332
  // Handle __NULL__ as "null"
334
333
  if (v == .string) {
335
- if (std.mem.eql(u8, v.string, runner.NULLMARK)) {
334
+ if (std.mem.eql(u8, v.string, omnirun.NULLMARK)) {
336
335
  const result = voxgig_struct.stringify(allocator, JsonValue{ .string = "null" }, null) catch return JsonValue{ .string = voxgig_struct.S_MT };
337
336
  return JsonValue{ .string = result };
338
337
  }
@@ -356,8 +355,8 @@ fn wrap_pathify(allocator: Allocator, val: JsonValue) JsonValue {
356
355
  const m = val.object;
357
356
  const path = m.get("path") orelse {
358
357
  // No path field - return unknown-path
359
- var result = std.ArrayList(u8).init(allocator);
360
- result.appendSlice("<unknown-path>") catch return JsonValue{ .string = "<unknown-path>" };
358
+ var result: std.ArrayList(u8) = .empty;
359
+ result.appendSlice(allocator, "<unknown-path>") catch return JsonValue{ .string = "<unknown-path>" };
361
360
  return JsonValue{ .string = result.items };
362
361
  };
363
362
 
@@ -411,7 +410,7 @@ fn wrap_pad(allocator: Allocator, val: JsonValue) JsonValue {
411
410
  // at test-case end, so we don't need an explicit free here.
412
411
  const s: []const u8 = switch (v) {
413
412
  .string => |str| blk: {
414
- if (std.mem.eql(u8, str, runner.NULLMARK)) {
413
+ if (std.mem.eql(u8, str, omnirun.NULLMARK)) {
415
414
  break :blk voxgig_struct.stringify(allocator, JsonValue{ .null = {} }, null) catch str;
416
415
  }
417
416
  break :blk str;
@@ -443,154 +442,139 @@ fn wrap_pad(allocator: Allocator, val: JsonValue) JsonValue {
443
442
  // ---- Allocator-aware minor tests ----
444
443
 
445
444
  test "minor-typename" {
446
- var r = try runner.makeRunner(testing.allocator);
445
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
447
446
  defer r.deinit();
448
- try r.runsetAlloc(try getMinorSpec(r, "typename"), wrap_typename);
447
+ try r.runsetflags(r.group("minor", "typename"), .{ .name = "minor/typename" }, wrap_typename);
449
448
  }
450
449
 
451
450
  test "minor-typify" {
452
- var r = try runner.makeRunner(testing.allocator);
451
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
453
452
  defer r.deinit();
454
- try r.runsetAllocFlags(try getMinorSpec(r, "typify"), .{ .null_flag = false, .undef_as_null = false }, wrap_typify);
453
+ try r.runsetflags(r.group("minor", "typify"), .{ .name = "minor/typify", .null_ = false, .noval = true }, wrap_typify);
455
454
  }
456
455
 
457
456
  test "minor-size" {
458
- var r = try runner.makeRunner(testing.allocator);
457
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
459
458
  defer r.deinit();
460
- try r.runsetAllocFlags(try getMinorSpec(r, "size"), .{ .null_flag = false }, wrap_size);
459
+ try r.runsetflags(r.group("minor", "size"), .{ .name = "minor/size", .null_ = false }, wrap_size);
461
460
  }
462
461
 
463
462
  test "minor-strkey" {
464
- var r = try runner.makeRunner(testing.allocator);
463
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
465
464
  defer r.deinit();
466
- try r.runsetAllocFlags(try getMinorSpec(r, "strkey"), .{ .null_flag = false }, wrap_strkey);
465
+ try r.runsetflags(r.group("minor", "strkey"), .{ .name = "minor/strkey", .null_ = false }, wrap_strkey);
467
466
  }
468
467
 
469
468
  test "minor-keysof" {
470
- var r = try runner.makeRunner(testing.allocator);
469
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
471
470
  defer r.deinit();
472
- try r.runsetAllocFlags(try getMinorSpec(r, "keysof"), .{ .null_flag = false }, wrap_keysof);
471
+ try r.runsetflags(r.group("minor", "keysof"), .{ .name = "minor/keysof" }, wrap_keysof);
473
472
  }
474
473
 
475
474
  test "minor-haskey" {
476
- var r = try runner.makeRunner(testing.allocator);
475
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
477
476
  defer r.deinit();
478
- try r.runsetAllocFlags(try getMinorSpec(r, "haskey"), .{ .null_flag = false }, wrap_haskey);
477
+ try r.runsetflags(r.group("minor", "haskey"), .{ .name = "minor/haskey", .null_ = false }, wrap_haskey);
479
478
  }
480
479
 
481
480
  test "minor-items" {
482
- var r = try runner.makeRunner(testing.allocator);
481
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
483
482
  defer r.deinit();
484
- try r.runsetAllocFlags(try getMinorSpec(r, "items"), .{ .null_flag = false }, wrap_items);
483
+ try r.runsetflags(r.group("minor", "items"), .{ .name = "minor/items" }, wrap_items);
485
484
  }
486
485
 
487
486
  test "minor-getelem" {
488
- var r = try runner.makeRunner(testing.allocator);
487
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
489
488
  defer r.deinit();
490
- try r.runsetAllocFlags(try getMinorSpec(r, "getelem"), .{ .null_flag = false }, wrap_getelem);
489
+ try r.runsetflags(r.group("minor", "getelem"), .{ .name = "minor/getelem", .null_ = false }, wrap_getelem);
491
490
  }
492
491
 
493
492
  test "minor-getprop" {
494
- var r = try runner.makeRunner(testing.allocator);
493
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
495
494
  defer r.deinit();
496
- try r.runsetAllocFlags(try getMinorSpec(r, "getprop"), .{ .null_flag = false }, wrap_getprop);
495
+ try r.runsetflags(r.group("minor", "getprop"), .{ .name = "minor/getprop", .null_ = false }, wrap_getprop);
497
496
  }
498
497
 
499
498
  test "minor-clone" {
500
- var r = try runner.makeRunner(testing.allocator);
499
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
501
500
  defer r.deinit();
502
- try r.runsetAllocFlags(try getMinorSpec(r, "clone"), .{ .null_flag = false, .undef_as_null = false }, wrap_clone);
501
+ try r.runsetflags(r.group("minor", "clone"), .{ .name = "minor/clone", .noval = true }, wrap_clone);
503
502
  }
504
503
 
505
504
  test "minor-flatten" {
506
- var r = try runner.makeRunner(testing.allocator);
505
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
507
506
  defer r.deinit();
508
- try r.runsetAlloc(try getMinorSpec(r, "flatten"), wrap_flatten);
507
+ try r.runsetflags(r.group("minor", "flatten"), .{ .name = "minor/flatten" }, wrap_flatten);
509
508
  }
510
509
 
511
510
  test "minor-filter" {
512
- var r = try runner.makeRunner(testing.allocator);
511
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
513
512
  defer r.deinit();
514
- try r.runsetAlloc(try getMinorSpec(r, "filter"), wrap_filter);
513
+ try r.runsetflags(r.group("minor", "filter"), .{ .name = "minor/filter" }, wrap_filter);
515
514
  }
516
515
 
517
516
  test "minor-delprop" {
518
- var r = try runner.makeRunner(testing.allocator);
517
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
519
518
  defer r.deinit();
520
- try r.runsetAllocFlags(try getMinorSpec(r, "delprop"), .{ .null_flag = false }, wrap_delprop);
519
+ try r.runsetflags(r.group("minor", "delprop"), .{ .name = "minor/delprop" }, wrap_delprop);
521
520
  }
522
521
 
523
522
  test "minor-setprop" {
524
- var r = try runner.makeRunner(testing.allocator);
523
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
525
524
  defer r.deinit();
526
- try r.runsetAllocFlags(try getMinorSpec(r, "setprop"), .{ .null_flag = false }, wrap_setprop);
525
+ try r.runsetflags(r.group("minor", "setprop"), .{ .name = "minor/setprop" }, wrap_setprop);
527
526
  }
528
527
 
529
528
  test "minor-escre" {
530
- var r = try runner.makeRunner(testing.allocator);
529
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
531
530
  defer r.deinit();
532
- try r.runsetAlloc(try getMinorSpec(r, "escre"), wrap_escre);
531
+ try r.runsetflags(r.group("minor", "escre"), .{ .name = "minor/escre" }, wrap_escre);
533
532
  }
534
533
 
535
534
  test "minor-escurl" {
536
- var r = try runner.makeRunner(testing.allocator);
535
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
537
536
  defer r.deinit();
538
- try r.runsetAlloc(try getMinorSpec(r, "escurl"), wrap_escurl);
537
+ try r.runsetflags(r.group("minor", "escurl"), .{ .name = "minor/escurl" }, wrap_escurl);
539
538
  }
540
539
 
541
540
  test "minor-join" {
542
- var r = try runner.makeRunner(testing.allocator);
541
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
543
542
  defer r.deinit();
544
- try r.runsetAllocFlags(try getMinorSpec(r, "join"), .{ .null_flag = false }, wrap_join);
543
+ try r.runsetflags(r.group("minor", "join"), .{ .name = "minor/join", .null_ = false }, wrap_join);
545
544
  }
546
545
 
547
546
  test "minor-jsonify" {
548
- var r = try runner.makeRunner(testing.allocator);
547
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
549
548
  defer r.deinit();
550
- try r.runsetAlloc(try getMinorSpec(r, "jsonify"), wrap_jsonify);
549
+ try r.runsetflags(r.group("minor", "jsonify"), .{ .name = "minor/jsonify", .null_ = false }, wrap_jsonify);
551
550
  }
552
551
 
553
552
  test "minor-stringify" {
554
- var r = try runner.makeRunner(testing.allocator);
553
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
555
554
  defer r.deinit();
556
- try r.runsetAllocFlags(try getMinorSpec(r, "stringify"), .{ .null_flag = false }, wrap_stringify);
555
+ try r.runsetflags(r.group("minor", "stringify"), .{ .name = "minor/stringify" }, wrap_stringify);
557
556
  }
558
557
 
559
558
  test "minor-pathify" {
560
- var r = try runner.makeRunner(testing.allocator);
559
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
561
560
  defer r.deinit();
562
- try r.runsetAllocFlags(try getMinorSpec(r, "pathify"), .{ .null_flag = false }, wrap_pathify);
561
+ try r.runsetflags(r.group("minor", "pathify"), .{ .name = "minor/pathify", .null_ = false }, wrap_pathify);
563
562
  }
564
563
 
565
564
  test "minor-slice" {
566
- var r = try runner.makeRunner(testing.allocator);
565
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
567
566
  defer r.deinit();
568
- try r.runsetAllocFlags(try getMinorSpec(r, "slice"), .{ .null_flag = false }, wrap_slice);
567
+ try r.runsetflags(r.group("minor", "slice"), .{ .name = "minor/slice", .null_ = false }, wrap_slice);
569
568
  }
570
569
 
571
570
  test "minor-pad" {
572
- var r = try runner.makeRunner(testing.allocator);
571
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
573
572
  defer r.deinit();
574
- try r.runsetAllocFlags(try getMinorSpec(r, "pad"), .{ .null_flag = false }, wrap_pad);
573
+ try r.runsetflags(r.group("minor", "pad"), .{ .name = "minor/pad", .null_ = false }, wrap_pad);
575
574
  }
576
575
 
577
576
  // ---- Walk, Merge, and Transform helpers ----
578
577
 
579
- fn getSpec(r: runner.RunPack, name: []const u8) !JsonValue {
580
- return r.spec.get(name) orelse return error.NoSpec;
581
- }
582
-
583
- fn getSubSpec(r: runner.RunPack, section: []const u8, sub: []const u8) !StdJsonValue {
584
- // The SDK corpus (.sdk/test/test.json) may omit some sections that the
585
- // upstream struct corpus carries (e.g. `sentinels`). Skip rather than
586
- // fail when a section/sub is absent — the corpus is the contract.
587
- const sec = r.spec.get(section) orelse return error.SkipZigTest;
588
- return switch (sec) {
589
- .object => |obj| obj.get(sub) orelse return error.SkipZigTest,
590
- else => return error.SpecNotObject,
591
- };
592
- }
593
-
594
578
  // ---- Walk wrappers ----
595
579
 
596
580
  fn walkApplyBasic(_: Allocator, key: ?[]const u8, val: JsonValue, _: JsonValue, path: []const []const u8) !JsonValue {
@@ -602,12 +586,13 @@ fn walkApplyBasic(_: Allocator, key: ?[]const u8, val: JsonValue, _: JsonValue,
602
586
  for (path) |p| total_len += p.len;
603
587
  if (path.len > 1) total_len += path.len - 1; // dots between parts
604
588
 
605
- var buf = std.ArrayList(u8).init(std.heap.page_allocator);
606
- buf.appendSlice(val.string) catch return val;
607
- buf.append('~') catch return val;
589
+ var buf: std.ArrayList(u8) = .empty;
590
+ const bufa = std.heap.page_allocator;
591
+ buf.appendSlice(bufa, val.string) catch return val;
592
+ buf.append(bufa, '~') catch return val;
608
593
  for (path, 0..) |p, i| {
609
- if (i > 0) buf.append('.') catch {};
610
- buf.appendSlice(p) catch {};
594
+ if (i > 0) buf.append(bufa, '.') catch {};
595
+ buf.appendSlice(bufa, p) catch {};
611
596
  }
612
597
  return JsonValue{ .string = buf.items };
613
598
  }
@@ -619,14 +604,14 @@ fn walkApplyCopy(_: Allocator, _: ?[]const u8, val: JsonValue, _: JsonValue, _:
619
604
  }
620
605
 
621
606
  fn wrap_walk_basic(allocator: Allocator, val: JsonValue) JsonValue {
622
- if (val == .string and std.mem.eql(u8, val.string, runner.NULLMARK)) {
607
+ if (val == .string and std.mem.eql(u8, val.string, omnirun.NULLMARK)) {
623
608
  return .null;
624
609
  }
625
610
  return voxgig_struct.walk(allocator, val, walkApplyBasic, null, voxgig_struct.MAXDEPTH) catch return .null;
626
611
  }
627
612
 
628
613
  fn wrap_walk_copy(allocator: Allocator, val: JsonValue) JsonValue {
629
- if (val == .string and std.mem.eql(u8, val.string, runner.UNDEFMARK)) {
614
+ if (val == .string and std.mem.eql(u8, val.string, omnirun.UNDEFMARK)) {
630
615
  return .null;
631
616
  }
632
617
  return voxgig_struct.walk(allocator, val, walkApplyCopy, null, voxgig_struct.MAXDEPTH) catch return .null;
@@ -659,7 +644,7 @@ fn cloneWithDepth(allocator: Allocator, val: JsonValue, maxdepth: i32, depth: i3
659
644
  }
660
645
  if (voxgig_struct.ismap(val)) {
661
646
  const new_obj_ref = allocator.create(voxgig_struct.MapRef) catch return .null;
662
- new_obj_ref.* = .{ .data = voxgig_struct.MapData.init(allocator) };
647
+ new_obj_ref.* = .{ .data = .empty, .allocator = allocator };
663
648
  var it = val.object.iterator();
664
649
  while (it.next()) |kv| {
665
650
  try new_obj_ref.put(kv.key_ptr.*, try cloneWithDepth(allocator, kv.value_ptr.*, maxdepth, depth + 1));
@@ -716,73 +701,82 @@ fn wrap_merge_integrity(allocator: Allocator, val: JsonValue) JsonValue {
716
701
 
717
702
  // ---- Transform wrappers ----
718
703
 
719
- fn wrap_transform(allocator: Allocator, val: JsonValue) JsonValue {
704
+ // `transform` reports collected injection errors beside the value; `.out` is
705
+ // the value it used to return on its own. The corpus asserts on those
706
+ // messages (transform.apply carries three `err` entries, transform.format
707
+ // one), and the retired runner skipped every one of them - so the message is
708
+ // reported here rather than dropped.
709
+ fn wrap_transform(allocator: Allocator, val: JsonValue, errout: *?[]const u8) JsonValue {
720
710
  // in: { data?, spec? }
721
711
  if (val != .object) return .null;
722
712
  const m = val.object;
723
713
  const data = m.get("data") orelse .null;
724
714
  const spec = m.get("spec") orelse return .null;
725
- return voxgig_struct.transform(allocator, data, spec) catch return .null;
715
+ const tres = voxgig_struct.transform(allocator, data, spec) catch return .null;
716
+ if (tres.err) |message| {
717
+ errout.* = message;
718
+ }
719
+ return tres.out;
726
720
  }
727
721
 
728
722
  // ---- Walk tests ----
729
723
 
730
724
  test "walk-basic" {
731
- var r = try runner.makeRunner(testing.allocator);
725
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
732
726
  defer r.deinit();
733
- try r.runsetAllocFlags(try getSubSpec(r, "walk", "basic"), .{ .null_flag = false }, wrap_walk_basic);
727
+ try r.runsetflags(r.group("walk", "basic"), .{ .name = "walk/basic" }, wrap_walk_basic);
734
728
  }
735
729
 
736
730
  test "walk-copy" {
737
- var r = try runner.makeRunner(testing.allocator);
731
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
738
732
  defer r.deinit();
739
- try r.runsetAllocFlags(try getSubSpec(r, "walk", "copy"), .{ .null_flag = false, .undef_as_null = false }, wrap_walk_copy);
733
+ try r.runsetflags(r.group("walk", "copy"), .{ .name = "walk/copy", .noval = true }, wrap_walk_copy);
740
734
  }
741
735
 
742
736
  test "walk-depth" {
743
- var r = try runner.makeRunner(testing.allocator);
737
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
744
738
  defer r.deinit();
745
- try r.runsetAlloc(try getSubSpec(r, "walk", "depth"), wrap_walk_depth);
739
+ try r.runsetflags(r.group("walk", "depth"), .{ .name = "walk/depth", .null_ = false }, wrap_walk_depth);
746
740
  }
747
741
 
748
742
  // ---- Merge tests ----
749
743
 
750
744
  test "merge-cases" {
751
- var r = try runner.makeRunner(testing.allocator);
745
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
752
746
  defer r.deinit();
753
- try r.runsetAllocFlags(try getSubSpec(r, "merge", "cases"), .{ .null_flag = false }, wrap_merge_cases);
747
+ try r.runsetflags(r.group("merge", "cases"), .{ .name = "merge/cases" }, wrap_merge_cases);
754
748
  }
755
749
 
756
750
  test "merge-array" {
757
- var r = try runner.makeRunner(testing.allocator);
751
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
758
752
  defer r.deinit();
759
- try r.runsetAllocFlags(try getSubSpec(r, "merge", "array"), .{ .null_flag = false }, wrap_merge_array);
753
+ try r.runsetflags(r.group("merge", "array"), .{ .name = "merge/array" }, wrap_merge_array);
760
754
  }
761
755
 
762
756
  test "merge-integrity" {
763
- var r = try runner.makeRunner(testing.allocator);
757
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
764
758
  defer r.deinit();
765
- try r.runsetAllocFlags(try getSubSpec(r, "merge", "integrity"), .{ .null_flag = false }, wrap_merge_integrity);
759
+ try r.runsetflags(r.group("merge", "integrity"), .{ .name = "merge/integrity" }, wrap_merge_integrity);
766
760
  }
767
761
 
768
762
  test "merge-depth" {
769
- var r = try runner.makeRunner(testing.allocator);
763
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
770
764
  defer r.deinit();
771
- try r.runsetAllocFlags(try getSubSpec(r, "merge", "depth"), .{ .null_flag = false }, wrap_merge_depth);
765
+ try r.runsetflags(r.group("merge", "depth"), .{ .name = "merge/depth" }, wrap_merge_depth);
772
766
  }
773
767
 
774
768
  // ---- Transform tests ----
775
769
 
776
770
  test "transform-paths" {
777
- var r = try runner.makeRunner(testing.allocator);
771
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
778
772
  defer r.deinit();
779
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "paths"), .{ .null_flag = false }, wrap_transform);
773
+ try r.runseterr(r.group("transform", "paths"), .{ .name = "transform/paths" }, wrap_transform);
780
774
  }
781
775
 
782
776
  test "transform-cmds" {
783
- var r = try runner.makeRunner(testing.allocator);
777
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
784
778
  defer r.deinit();
785
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "cmds"), .{ .null_flag = false }, wrap_transform);
779
+ try r.runseterr(r.group("transform", "cmds"), .{ .name = "transform/cmds" }, wrap_transform);
786
780
  }
787
781
 
788
782
  // ---- SetPath tests ----
@@ -798,9 +792,9 @@ fn wrap_setpath(allocator: Allocator, val: JsonValue) JsonValue {
798
792
  }
799
793
 
800
794
  test "minor-setpath" {
801
- var r = try runner.makeRunner(testing.allocator);
795
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
802
796
  defer r.deinit();
803
- try r.runsetAllocFlags(try getMinorSpec(r, "setpath"), .{ .null_flag = false }, wrap_setpath);
797
+ try r.runsetflags(r.group("minor", "setpath"), .{ .name = "minor/setpath", .null_ = false }, wrap_setpath);
804
798
  }
805
799
 
806
800
  // ---- GetPath tests ----
@@ -837,7 +831,7 @@ fn wrap_getpath_relative(allocator: Allocator, val: JsonValue) JsonValue {
837
831
  }
838
832
  }
839
833
 
840
- var errs = std.ArrayList([]const u8).init(allocator);
834
+ var errs: std.array_list.Managed([]const u8) = .init(allocator);
841
835
  const init_keys = allocator.alloc([]const u8, 0) catch return .null;
842
836
  const init_path = allocator.alloc([]const u8, 0) catch return .null;
843
837
  const init_nodes = allocator.alloc(JsonValue, 0) catch return .null;
@@ -865,7 +859,7 @@ fn wrap_getpath_special(allocator: Allocator, val: JsonValue) JsonValue {
865
859
  const inj_spec = m.get("inj");
866
860
 
867
861
  if (inj_spec) |ij| {
868
- var errs = std.ArrayList([]const u8).init(allocator);
862
+ var errs: std.array_list.Managed([]const u8) = .init(allocator);
869
863
  var init_keys = allocator.alloc([]const u8, 0) catch return .null;
870
864
  var init_path = allocator.alloc([]const u8, 0) catch return .null;
871
865
  var init_nodes = allocator.alloc(JsonValue, 0) catch return .null;
@@ -899,30 +893,31 @@ fn wrap_getpath_special(allocator: Allocator, val: JsonValue) JsonValue {
899
893
  }
900
894
 
901
895
  test "getpath-basic" {
902
- var r = try runner.makeRunner(testing.allocator);
896
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
903
897
  defer r.deinit();
904
- try r.runsetAllocFlags(try getSubSpec(r, "getpath", "basic"), .{ .null_flag = false }, wrap_getpath_basic);
898
+ try r.runsetflags(r.group("getpath", "basic"), .{ .name = "getpath/basic" }, wrap_getpath_basic);
905
899
  }
906
900
 
907
901
  test "getpath-relative" {
908
- var r = try runner.makeRunner(testing.allocator);
902
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
909
903
  defer r.deinit();
910
- try r.runsetAllocFlags(try getSubSpec(r, "getpath", "relative"), .{ .null_flag = false }, wrap_getpath_relative);
904
+ try r.runsetflags(r.group("getpath", "relative"), .{ .name = "getpath/relative" }, wrap_getpath_relative);
911
905
  }
912
906
 
913
907
  test "getpath-special" {
914
- var r = try runner.makeRunner(testing.allocator);
908
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
915
909
  defer r.deinit();
916
- try r.runsetAllocFlags(try getSubSpec(r, "getpath", "special"), .{ .null_flag = false }, wrap_getpath_special);
910
+ try r.runsetflags(r.group("getpath", "special"), .{ .name = "getpath/special" }, wrap_getpath_special);
917
911
  }
918
912
 
919
913
  // ---- GetPath handler test ----
920
914
 
921
- fn fooHandlerCall(_: *anyopaque, _: Allocator, _: JsonValue) anyerror!JsonValue {
915
+ // A corpus `$FOO` handler: a plain JsonFunc, taking only the allocator. The
916
+ // SDK's own callables carry a captured context and are boxed into this slot by
917
+ // core/helpers.zig; the corpus needs neither.
918
+ fn fooHandler(_: Allocator) anyerror!JsonValue {
922
919
  return JsonValue{ .string = "foo" };
923
920
  }
924
- var foo_dummy: u8 = 0;
925
- const foo_callable = voxgig_struct.Callable{ .ctx = @ptrCast(&foo_dummy), .call = fooHandlerCall };
926
921
 
927
922
  fn wrap_getpath_handler(allocator: Allocator, val: JsonValue) JsonValue {
928
923
  // in: { path, store }
@@ -932,17 +927,17 @@ fn wrap_getpath_handler(allocator: Allocator, val: JsonValue) JsonValue {
932
927
 
933
928
  // Build a store that has $FOO as a function returning "foo".
934
929
  const handler_store = allocator.create(voxgig_struct.MapRef) catch return .null;
935
- handler_store.* = .{ .data = voxgig_struct.MapData.init(allocator) };
930
+ handler_store.* = .{ .data = .empty, .allocator = allocator };
936
931
  handler_store.put("$TOP", .null) catch {};
937
- handler_store.put("$FOO", JsonValue{ .function = &foo_callable }) catch {};
932
+ handler_store.put("$FOO", JsonValue{ .function = fooHandler }) catch {};
938
933
 
939
934
  return voxgig_struct.getpath(allocator, path_v, JsonValue{ .object = handler_store }) catch return .null;
940
935
  }
941
936
 
942
937
  test "getpath-handler" {
943
- var r = try runner.makeRunner(testing.allocator);
938
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
944
939
  defer r.deinit();
945
- try r.runsetAllocFlags(try getSubSpec(r, "getpath", "handler"), .{ .null_flag = false }, wrap_getpath_handler);
940
+ try r.runsetflags(r.group("getpath", "handler"), .{ .name = "getpath/handler" }, wrap_getpath_handler);
946
941
  }
947
942
 
948
943
  // ---- Inject tests ----
@@ -957,47 +952,47 @@ fn wrap_inject(allocator: Allocator, val: JsonValue) JsonValue {
957
952
  }
958
953
 
959
954
  test "inject-string" {
960
- var r = try runner.makeRunner(testing.allocator);
955
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
961
956
  defer r.deinit();
962
- try r.runsetAllocFlags(try getSubSpec(r, "inject", "string"), .{ .null_flag = false }, wrap_inject);
957
+ try r.runsetflags(r.group("inject", "string"), .{ .name = "inject/string", .null_ = false }, wrap_inject);
963
958
  }
964
959
 
965
960
  test "inject-deep" {
966
- var r = try runner.makeRunner(testing.allocator);
961
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
967
962
  defer r.deinit();
968
- try r.runsetAllocFlags(try getSubSpec(r, "inject", "deep"), .{ .null_flag = false }, wrap_inject);
963
+ try r.runsetflags(r.group("inject", "deep"), .{ .name = "inject/deep", .null_ = false }, wrap_inject);
969
964
  }
970
965
 
971
966
  // ---- Additional transform tests ----
972
967
 
973
968
  test "transform-each" {
974
- var r = try runner.makeRunner(testing.allocator);
969
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
975
970
  defer r.deinit();
976
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "each"), .{ .null_flag = false }, wrap_transform);
971
+ try r.runseterr(r.group("transform", "each"), .{ .name = "transform/each" }, wrap_transform);
977
972
  }
978
973
 
979
974
  test "transform-pack" {
980
- var r = try runner.makeRunner(testing.allocator);
975
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
981
976
  defer r.deinit();
982
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "pack"), .{ .null_flag = false }, wrap_transform);
977
+ try r.runseterr(r.group("transform", "pack"), .{ .name = "transform/pack" }, wrap_transform);
983
978
  }
984
979
 
985
980
  test "transform-ref" {
986
- var r = try runner.makeRunner(testing.allocator);
981
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
987
982
  defer r.deinit();
988
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "ref"), .{ .null_flag = false }, wrap_transform);
983
+ try r.runseterr(r.group("transform", "ref"), .{ .name = "transform/ref" }, wrap_transform);
989
984
  }
990
985
 
991
986
  test "transform-format" {
992
- var r = try runner.makeRunner(testing.allocator);
987
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
993
988
  defer r.deinit();
994
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "format"), .{ .null_flag = false }, wrap_transform);
989
+ try r.runseterr(r.group("transform", "format"), .{ .name = "transform/format", .null_ = false }, wrap_transform);
995
990
  }
996
991
 
997
992
  test "transform-apply" {
998
- var r = try runner.makeRunner(testing.allocator);
993
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
999
994
  defer r.deinit();
1000
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "apply"), .{ .null_flag = false }, wrap_transform);
995
+ try r.runseterr(r.group("transform", "apply"), .{ .name = "transform/apply" }, wrap_transform);
1001
996
  }
1002
997
 
1003
998
  // ---- Transform modify test ----
@@ -1018,57 +1013,69 @@ fn wrap_transform_modify(allocator: Allocator, val: JsonValue) JsonValue {
1018
1013
  }
1019
1014
 
1020
1015
  test "transform-modify" {
1021
- var r = try runner.makeRunner(testing.allocator);
1016
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1022
1017
  defer r.deinit();
1023
- try r.runsetAllocFlags(try getSubSpec(r, "transform", "modify"), .{ .null_flag = false }, wrap_transform_modify);
1018
+ try r.runsetflags(r.group("transform", "modify"), .{ .name = "transform/modify" }, wrap_transform_modify);
1024
1019
  }
1025
1020
 
1026
1021
  // ---- Validate tests ----
1027
1022
 
1028
- fn wrap_validate(allocator: Allocator, val: JsonValue) JsonValue {
1023
+ fn wrap_validate(allocator: Allocator, val: JsonValue, errout: *?[]const u8) JsonValue {
1029
1024
  // in: { data, spec }
1030
1025
  if (val != .object) return .null;
1031
1026
  const m = val.object;
1032
1027
  const data = m.get("data") orelse .null;
1033
1028
  const spec = m.get("spec") orelse return .null;
1034
- const result = voxgig_struct.validate(allocator, data, spec) catch return .null;
1029
+ // `validate.special` supplies its own injection definition (`in.inj`,
1030
+ // carrying the `meta` a `$=` spec reads), exactly as the reference driver
1031
+ // passes `vin.inj` as validate's third argument. Dropping it made every
1032
+ // `$=` case report "Expected field ... to be exactly equal to null" -
1033
+ // invisible until now, because the retiring runner swallowed the
1034
+ // validation error and compared only the value, which `$=` leaves alone.
1035
+ //
1036
+ // validateWith, not validate, because there IS a third argument here.
1037
+ const injdef = m.get("inj") orelse .null;
1038
+ const result = voxgig_struct.validateWith(allocator, data, spec, injdef) catch return .null;
1039
+ if (result.err) |message| {
1040
+ errout.* = message;
1041
+ }
1035
1042
  return result.out;
1036
1043
  }
1037
1044
 
1038
1045
  test "validate-basic" {
1039
- var r = try runner.makeRunner(testing.allocator);
1046
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1040
1047
  defer r.deinit();
1041
- try r.runsetAllocFlags(try getSubSpec(r, "validate", "basic"), .{ .null_flag = false }, wrap_validate);
1048
+ try r.runseterr(r.group("validate", "basic"), .{ .name = "validate/basic", .null_ = false }, wrap_validate);
1042
1049
  }
1043
1050
 
1044
1051
  test "validate-child" {
1045
- var r = try runner.makeRunner(testing.allocator);
1052
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1046
1053
  defer r.deinit();
1047
- try r.runsetAllocFlags(try getSubSpec(r, "validate", "child"), .{ .null_flag = false }, wrap_validate);
1054
+ try r.runseterr(r.group("validate", "child"), .{ .name = "validate/child" }, wrap_validate);
1048
1055
  }
1049
1056
 
1050
1057
  test "validate-one" {
1051
- var r = try runner.makeRunner(testing.allocator);
1058
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1052
1059
  defer r.deinit();
1053
- try r.runsetAllocFlags(try getSubSpec(r, "validate", "one"), .{ .null_flag = false }, wrap_validate);
1060
+ try r.runseterr(r.group("validate", "one"), .{ .name = "validate/one" }, wrap_validate);
1054
1061
  }
1055
1062
 
1056
1063
  test "validate-exact" {
1057
- var r = try runner.makeRunner(testing.allocator);
1064
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1058
1065
  defer r.deinit();
1059
- try r.runsetAllocFlags(try getSubSpec(r, "validate", "exact"), .{ .null_flag = false }, wrap_validate);
1066
+ try r.runseterr(r.group("validate", "exact"), .{ .name = "validate/exact" }, wrap_validate);
1060
1067
  }
1061
1068
 
1062
1069
  test "validate-invalid" {
1063
- var r = try runner.makeRunner(testing.allocator);
1070
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1064
1071
  defer r.deinit();
1065
- try r.runsetAllocFlags(try getSubSpec(r, "validate", "invalid"), .{ .null_flag = false }, wrap_validate);
1072
+ try r.runseterr(r.group("validate", "invalid"), .{ .name = "validate/invalid", .null_ = false }, wrap_validate);
1066
1073
  }
1067
1074
 
1068
1075
  test "validate-special" {
1069
- var r = try runner.makeRunner(testing.allocator);
1076
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1070
1077
  defer r.deinit();
1071
- try r.runsetAllocFlags(try getSubSpec(r, "validate", "special"), .{ .null_flag = false }, wrap_validate);
1078
+ try r.runseterr(r.group("validate", "special"), .{ .name = "validate/special" }, wrap_validate);
1072
1079
  }
1073
1080
 
1074
1081
  // ---- Select tests ----
@@ -1083,63 +1090,133 @@ fn wrap_select(allocator: Allocator, val: JsonValue) JsonValue {
1083
1090
  }
1084
1091
 
1085
1092
  test "select-basic" {
1086
- var r = try runner.makeRunner(testing.allocator);
1093
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1087
1094
  defer r.deinit();
1088
- try r.runsetAllocFlags(try getSubSpec(r, "select", "basic"), .{ .null_flag = false }, wrap_select);
1095
+ try r.runsetflags(r.group("select", "basic"), .{ .name = "select/basic" }, wrap_select);
1089
1096
  }
1090
1097
 
1091
1098
  test "select-operators" {
1092
- var r = try runner.makeRunner(testing.allocator);
1099
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1093
1100
  defer r.deinit();
1094
- try r.runsetAllocFlags(try getSubSpec(r, "select", "operators"), .{ .null_flag = false }, wrap_select);
1101
+ try r.runsetflags(r.group("select", "operators"), .{ .name = "select/operators" }, wrap_select);
1095
1102
  }
1096
1103
 
1097
1104
  test "select-edge" {
1098
- var r = try runner.makeRunner(testing.allocator);
1105
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1099
1106
  defer r.deinit();
1100
- try r.runsetAllocFlags(try getSubSpec(r, "select", "edge"), .{ .null_flag = false }, wrap_select);
1107
+ try r.runsetflags(r.group("select", "edge"), .{ .name = "select/edge" }, wrap_select);
1101
1108
  }
1102
1109
 
1103
1110
  test "select-alts" {
1104
- var r = try runner.makeRunner(testing.allocator);
1111
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1105
1112
  defer r.deinit();
1106
- try r.runsetAllocFlags(try getSubSpec(r, "select", "alts"), .{ .null_flag = false }, wrap_select);
1113
+ try r.runsetflags(r.group("select", "alts"), .{ .name = "select/alts" }, wrap_select);
1107
1114
  }
1108
1115
 
1109
1116
  // ---- sentinels: Group A null/undefined unification across the readers ----
1110
1117
 
1111
1118
  test "sentinels-getprop_unify" {
1112
- var r = try runner.makeRunner(testing.allocator);
1119
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1113
1120
  defer r.deinit();
1114
- try r.runsetAllocFlags(try getSubSpec(r, "sentinels", "getprop_unify"), .{ .null_flag = false }, wrap_getprop);
1121
+ try r.runsetflags(r.group("sentinels", "getprop_unify"), .{ .name = "sentinels/getprop_unify", .null_ = false }, wrap_getprop);
1115
1122
  }
1116
1123
 
1117
1124
  test "sentinels-getelem_absent" {
1118
- var r = try runner.makeRunner(testing.allocator);
1125
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1119
1126
  defer r.deinit();
1120
- try r.runsetAllocFlags(try getSubSpec(r, "sentinels", "getelem_absent"), .{ .null_flag = false }, wrap_getelem);
1127
+ try r.runsetflags(r.group("sentinels", "getelem_absent"), .{ .name = "sentinels/getelem_absent", .null_ = false }, wrap_getelem);
1121
1128
  }
1122
1129
 
1123
1130
  test "sentinels-haskey_unify" {
1124
- var r = try runner.makeRunner(testing.allocator);
1131
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1125
1132
  defer r.deinit();
1126
- try r.runsetAllocFlags(try getSubSpec(r, "sentinels", "haskey_unify"), .{ .null_flag = false }, wrap_haskey_val);
1133
+ try r.runsetflags(r.group("sentinels", "haskey_unify"), .{ .name = "sentinels/haskey_unify", .null_ = false }, wrap_haskey_val);
1127
1134
  }
1128
1135
 
1129
1136
  test "sentinels-isempty_unify" {
1130
- var r = try runner.makeRunner(testing.allocator);
1137
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1131
1138
  defer r.deinit();
1132
- try r.runsetAllocFlags(try getSubSpec(r, "sentinels", "isempty_unify"), .{ .null_flag = false }, wrap_isempty);
1139
+ try r.runsetflags(r.group("sentinels", "isempty_unify"), .{ .name = "sentinels/isempty_unify", .null_ = false }, wrap_isempty);
1133
1140
  }
1134
1141
 
1135
1142
  test "sentinels-isnode_unify" {
1136
- var r = try runner.makeRunner(testing.allocator);
1143
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1137
1144
  defer r.deinit();
1138
- try r.runsetAllocFlags(try getSubSpec(r, "sentinels", "isnode_unify"), .{ .null_flag = false }, wrap_isnode);
1145
+ try r.runsetflags(r.group("sentinels", "isnode_unify"), .{ .name = "sentinels/isnode_unify", .null_ = false }, wrap_isnode);
1139
1146
  }
1140
1147
 
1141
1148
  test "sentinels-stringify_null" {
1142
- var r = try runner.makeRunner(testing.allocator);
1149
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1150
+ defer r.deinit();
1151
+ try r.runsetflags(r.group("sentinels", "stringify_null"), .{ .name = "sentinels/stringify_null", .null_ = false }, wrap_stringify_raw);
1152
+ }
1153
+
1154
+ // ---- nullsem: null and absent are DIFFERENT, across the five readers ------
1155
+ //
1156
+ // The reference driver runs every one of these lanes with the null flag OFF:
1157
+ // with it on, the runner rewrites each null to __NULL__ and the section
1158
+ // asserts nothing about null at all. The section is a recent corpus addition,
1159
+ // so an older project corpus does not carry it - `group` answers absent and
1160
+ // the lane skips OUT LOUD rather than passing vacuously.
1161
+
1162
+ test "nullsem-getprop" {
1163
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1143
1164
  defer r.deinit();
1144
- try r.runsetAllocFlags(try getSubSpec(r, "sentinels", "stringify_null"), .{ .null_flag = false }, wrap_stringify_raw);
1165
+ try r.runsetflags(r.group("nullsem", "getprop"), .{ .name = "nullsem/getprop", .null_ = false }, wrap_getprop);
1166
+ }
1167
+
1168
+ test "nullsem-getelem" {
1169
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1170
+ defer r.deinit();
1171
+ try r.runsetflags(r.group("nullsem", "getelem"), .{ .name = "nullsem/getelem", .null_ = false }, wrap_getelem);
1172
+ }
1173
+
1174
+ test "nullsem-getpath" {
1175
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1176
+ defer r.deinit();
1177
+ try r.runsetflags(r.group("nullsem", "getpath"), .{ .name = "nullsem/getpath", .null_ = false }, wrap_getpath_basic);
1178
+ }
1179
+
1180
+ test "nullsem-haskey" {
1181
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1182
+ defer r.deinit();
1183
+ try r.runsetflags(r.group("nullsem", "haskey"), .{ .name = "nullsem/haskey", .null_ = false }, wrap_haskey);
1184
+ }
1185
+
1186
+ test "nullsem-keysof" {
1187
+ var r = try omnirun.makeRunner(testing.allocator, "struct");
1188
+ defer r.deinit();
1189
+ try r.runsetflags(r.group("nullsem", "keysof"), .{ .name = "nullsem/keysof", .null_ = false }, wrap_keysof);
1190
+ }
1191
+
1192
+ // ---- the census -----------------------------------------------------------
1193
+ //
1194
+ // A suite that stops executing the corpus looks exactly like a passing one,
1195
+ // and two targets in this rollout went green that way. Two guards stand
1196
+ // against it: every group above compares the SUBJECT INVOCATIONS against the
1197
+ // number of entries the group declares (omniresolver decision 6), and this
1198
+ // last test - declared last, so it runs last - holds the whole file to a
1199
+ // floor. The shared struct corpus is the same file in every SDK, so the
1200
+ // floor is a real number, not a token one; a legitimate shrink below it is a
1201
+ // corpus change worth reading.
1202
+ // Measured on the corpus this SDK compiles: 1212 cases across 65 groups with
1203
+ // the nullsem lanes present, 1179 across 60 without them. The floor sits
1204
+ // below the smaller reading, so an older corpus passes and a suite that lost
1205
+ // a section does not.
1206
+ const CASES_FLOOR = 1150;
1207
+ const GROUPS_FLOOR = 58;
1208
+
1209
+ test "zzz-census: the struct corpus actually ran" {
1210
+ std.debug.print(
1211
+ "\n struct corpus: {d} cases across {d} groups\n",
1212
+ .{ omnirun.CASES, omnirun.GROUPS },
1213
+ );
1214
+
1215
+ if (omnirun.CASES < CASES_FLOOR or omnirun.GROUPS < GROUPS_FLOOR) {
1216
+ std.debug.print(
1217
+ " EXPECTED at least {d} cases across {d} groups\n",
1218
+ .{ CASES_FLOOR, GROUPS_FLOOR },
1219
+ );
1220
+ return error.CorpusUnderRun;
1221
+ }
1145
1222
  }