@voxgig/sdkgen 4.8.2 → 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 (407) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/action/doctor.d.ts +1 -0
  3. package/dist/action/doctor.js +50 -2
  4. package/dist/action/doctor.js.map +1 -1
  5. package/dist/helpers/naming.js +4 -2
  6. package/dist/helpers/naming.js.map +1 -1
  7. package/dist/tsconfig.tsbuildinfo +1 -1
  8. package/model/sdkgen.aon +21 -0
  9. package/package.json +1 -1
  10. package/project/.sdk/model/feature/secrets.aon +120 -18
  11. package/project/.sdk/model/target/c.aon +10 -0
  12. package/project/.sdk/model/target/clojure.aon +13 -0
  13. package/project/.sdk/model/target/cpp.aon +10 -0
  14. package/project/.sdk/model/target/csharp.aon +9 -0
  15. package/project/.sdk/model/target/dart.aon +10 -0
  16. package/project/.sdk/model/target/elixir.aon +9 -0
  17. package/project/.sdk/model/target/go.aon +13 -0
  18. package/project/.sdk/model/target/java.aon +9 -0
  19. package/project/.sdk/model/target/js.aon +7 -0
  20. package/project/.sdk/model/target/kotlin.aon +9 -0
  21. package/project/.sdk/model/target/lean.aon +17 -0
  22. package/project/.sdk/model/target/lua.aon +8 -0
  23. package/project/.sdk/model/target/ocaml.aon +9 -0
  24. package/project/.sdk/model/target/perl.aon +8 -0
  25. package/project/.sdk/model/target/php.aon +8 -0
  26. package/project/.sdk/model/target/py.aon +13 -0
  27. package/project/.sdk/model/target/rb.aon +8 -0
  28. package/project/.sdk/model/target/rust.aon +10 -0
  29. package/project/.sdk/model/target/scala.aon +21 -2
  30. package/project/.sdk/model/target/swift.aon +18 -0
  31. package/project/.sdk/model/target/ts.aon +13 -0
  32. package/project/.sdk/model/target/zig.aon +9 -0
  33. package/project/.sdk/src/cmp/clojure/Package_clojure.ts +9 -2
  34. package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +3 -0
  35. package/project/.sdk/src/cmp/dart/Test_dart.ts +2 -0
  36. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +4 -1
  37. package/project/.sdk/src/cmp/go/Config_go.ts +59 -2
  38. package/project/.sdk/src/cmp/go/Main_go.ts +8 -2
  39. package/project/.sdk/src/cmp/java/Test_java.ts +6 -5
  40. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +6 -5
  41. package/project/.sdk/src/cmp/lean/Package_lean.ts +23 -0
  42. package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +1 -0
  43. package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +1 -0
  44. package/project/.sdk/src/cmp/ocaml/Gitignore_ocaml.ts +1 -0
  45. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +7 -3
  46. package/project/.sdk/src/cmp/py/Config_py.ts +82 -1
  47. package/project/.sdk/src/cmp/py/Main_py.ts +44 -0
  48. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +2 -0
  49. package/project/.sdk/src/cmp/swift/Main_swift.ts +10 -0
  50. package/project/.sdk/src/cmp/swift/Package_swift.ts +13 -1
  51. package/project/.sdk/src/cmp/ts/Config_ts.ts +42 -17
  52. package/project/.sdk/src/cmp/ts/fragment/Config.data.fragment.ts +13 -1
  53. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +13 -1
  54. package/project/.sdk/src/cmp/zig/Package_zig.ts +15 -11
  55. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +3 -3
  56. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +3 -3
  57. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +3 -3
  58. package/project/.sdk/src/cmp/zig/utility_zig.ts +50 -1
  59. package/project/.sdk/tm/c/Makefile +38 -3
  60. package/project/.sdk/tm/c/tests/omni_resolver.h +361 -0
  61. package/project/.sdk/tm/c/tests/omni_smoke_test.c +237 -0
  62. package/project/.sdk/tm/c/tests/primary_corpus_test.c +205 -284
  63. package/project/.sdk/tm/c/tests/struct_corpus_test.c +292 -212
  64. package/project/.sdk/tm/c/tests/vendor/omni/json.c +811 -0
  65. package/project/.sdk/tm/c/tests/vendor/omni/omni.h +240 -0
  66. package/project/.sdk/tm/c/tests/vendor/omni/runner.c +940 -0
  67. package/project/.sdk/tm/c/tests/vendor/omni/util.c +351 -0
  68. package/project/.sdk/tm/c/utility/struct/utility.c +7 -2
  69. package/project/.sdk/tm/clojure/test/sdk/test/omni.clj +401 -0
  70. package/project/.sdk/tm/clojure/test/sdk/test/omni_smoke.clj +81 -0
  71. package/project/.sdk/tm/clojure/test/sdk/test/primary.clj +92 -58
  72. package/project/.sdk/tm/clojure/test/sdk/test/struct_corpus.clj +122 -149
  73. package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +8 -3
  74. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +145 -0
  75. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +445 -0
  76. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +145 -0
  77. package/project/.sdk/tm/cpp/Makefile +5 -1
  78. package/project/.sdk/tm/cpp/test/omni_resolver.hpp +473 -0
  79. package/project/.sdk/tm/cpp/test/omni_smoke_test.cpp +209 -0
  80. package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +243 -184
  81. package/project/.sdk/tm/cpp/test/runner_support.hpp +68 -181
  82. package/project/.sdk/tm/cpp/test/struct_corpus_test.cpp +183 -56
  83. package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +406 -0
  84. package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +751 -0
  85. package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +256 -0
  86. package/project/.sdk/tm/cpp/utility/pipeline.hpp +7 -1
  87. package/project/.sdk/tm/csharp/test/OmniResolver.cs +491 -0
  88. package/project/.sdk/tm/csharp/test/OmniSmokeTest.cs +106 -0
  89. package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +299 -316
  90. package/project/.sdk/tm/csharp/test/Runner.cs +104 -269
  91. package/project/.sdk/tm/csharp/test/StructUtilityTest.cs +535 -724
  92. package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +864 -0
  93. package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +347 -0
  94. package/project/.sdk/tm/csharp/utility/MakeSpec.cs +3 -1
  95. package/project/.sdk/tm/csharp/utility/PrepareMethod.cs +6 -1
  96. package/project/.sdk/tm/csharp/utility/struct/Struct.cs +21 -5
  97. package/project/.sdk/tm/dart/test/omni.dart +520 -0
  98. package/project/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
  99. package/project/.sdk/tm/dart/test/primary_test.dart +86 -28
  100. package/project/.sdk/tm/dart/test/struct_test.dart +438 -11
  101. package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
  102. package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
  103. package/project/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
  104. package/project/.sdk/tm/elixir/Makefile +11 -3
  105. package/project/.sdk/tm/elixir/test/omni_smoke_test.exs +117 -0
  106. package/project/.sdk/tm/elixir/test/primary_utility_test.exs +341 -16
  107. package/project/.sdk/tm/elixir/test/struct_corpus_test.exs +554 -9
  108. package/project/.sdk/tm/elixir/test/support/omni.ex +377 -0
  109. package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +122 -0
  110. package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +623 -0
  111. package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +187 -0
  112. package/project/.sdk/tm/go/core/context.go +32 -16
  113. package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +261 -0
  114. package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +78 -0
  115. package/project/.sdk/tm/go/feature/secrets/plugin/config.go +652 -0
  116. package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +250 -0
  117. package/project/.sdk/tm/go/feature/secrets/plugin/env.go +194 -0
  118. package/project/.sdk/tm/go/feature/secrets/plugin/export.go +80 -0
  119. package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +238 -0
  120. package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1575 -0
  121. package/project/.sdk/tm/go/feature/secrets/plugin/order.go +248 -0
  122. package/project/.sdk/tm/go/feature/secrets/plugin/point.go +184 -0
  123. package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +123 -0
  124. package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +79 -0
  125. package/project/.sdk/tm/go/feature/secrets/plugin/types.go +296 -0
  126. package/project/.sdk/tm/go/feature/secrets/plugin/util.go +87 -0
  127. package/project/.sdk/tm/go/feature/secrets/plugin/version.go +161 -0
  128. package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +292 -0
  129. package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +201 -0
  130. package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +187 -0
  131. package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +184 -0
  132. package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +114 -0
  133. package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +156 -0
  134. package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +208 -0
  135. package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +241 -0
  136. package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +150 -0
  137. package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +152 -0
  138. package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +143 -0
  139. package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +120 -0
  140. package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +442 -0
  141. package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +714 -0
  142. package/project/.sdk/tm/go/feature/secrets_feature.go +675 -0
  143. package/project/.sdk/tm/go/src/feature/secrets/.gitkeep +0 -0
  144. package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +799 -0
  145. package/project/.sdk/tm/go/test/omni/omni.go +902 -0
  146. package/project/.sdk/tm/go/test/omni/util.go +381 -0
  147. package/project/.sdk/tm/go/test/omniresolver_test.go +748 -0
  148. package/project/.sdk/tm/go/test/omnismoke_test.go +112 -0
  149. package/project/.sdk/tm/go/test/primary_utility_test.go +123 -191
  150. package/project/.sdk/tm/go/test/struct_utility_test.go +323 -16
  151. package/project/.sdk/tm/go/test/testsupport_test.go +294 -0
  152. package/project/.sdk/tm/go/utility/make_options.go +8 -1
  153. package/project/.sdk/tm/go/utility/prepare_method.go +5 -1
  154. package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +2 -2
  155. package/project/.sdk/tm/java/test/OmniResolver.java +355 -0
  156. package/project/.sdk/tm/java/test/OmniSmokeTest.java +99 -0
  157. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +254 -280
  158. package/project/.sdk/tm/java/test/RunnerSupport.java +9 -194
  159. package/project/.sdk/tm/java/test/StructCorpusTest.java +119 -42
  160. package/project/.sdk/tm/java/test/vendor/omni/Json.java +287 -0
  161. package/project/.sdk/tm/java/test/vendor/omni/Runner.java +851 -0
  162. package/project/.sdk/tm/java/test/vendor/omni/Util.java +322 -0
  163. package/project/.sdk/tm/java/utility/MakeSpec.java +3 -1
  164. package/project/.sdk/tm/java/utility/PrepareMethod.java +5 -5
  165. package/project/.sdk/tm/java/utility/struct/Struct.java +17 -4
  166. package/project/.sdk/tm/js/src/utility/StructUtility.js +3 -3
  167. package/project/.sdk/tm/js/test/omni.js +251 -0
  168. package/project/.sdk/tm/js/test/omni.test.js +105 -0
  169. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +6 -2
  170. package/project/.sdk/tm/js/test/utility/StructUtility.test.js +27 -2
  171. package/project/.sdk/tm/js/test/vendor/omni/index.js +77 -0
  172. package/project/.sdk/tm/js/test/vendor/omni/runner.js +628 -0
  173. package/project/.sdk/tm/js/test/vendor/omni/util.js +229 -0
  174. package/project/.sdk/tm/kotlin/core/Utility.kt +1 -1
  175. package/project/.sdk/tm/kotlin/test/OmniResolver.kt +343 -0
  176. package/project/.sdk/tm/kotlin/test/OmniSmokeTest.kt +100 -0
  177. package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +244 -262
  178. package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +9 -178
  179. package/project/.sdk/tm/kotlin/test/StructCorpusTest.kt +121 -32
  180. package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +264 -0
  181. package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +615 -0
  182. package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +139 -0
  183. package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +6 -3
  184. package/project/.sdk/tm/kotlin/utility/Prepare.kt +6 -6
  185. package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +18 -2
  186. package/project/.sdk/tm/lean/Makefile +12 -5
  187. package/project/.sdk/tm/lean/src/SdkUtility.lean +14 -1
  188. package/project/.sdk/tm/lean/test/OmniResolver.lean +358 -0
  189. package/project/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
  190. package/project/.sdk/tm/lean/test/StructCorpus.lean +245 -574
  191. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +155 -291
  192. package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
  193. package/project/.sdk/tm/lua/test/omni.lua +456 -0
  194. package/project/.sdk/tm/lua/test/omni_smoke_test.lua +103 -0
  195. package/project/.sdk/tm/lua/test/primary_utility_test.lua +250 -509
  196. package/project/.sdk/tm/lua/test/struct_utility_test.lua +161 -70
  197. package/project/.sdk/tm/lua/test/vendor/omni/json.lua +268 -0
  198. package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +385 -0
  199. package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +641 -0
  200. package/project/.sdk/tm/lua/test/vendor/omni/util.lua +282 -0
  201. package/project/.sdk/tm/lua/utility/prepare_method.lua +5 -1
  202. package/project/.sdk/tm/lua/utility/struct/regex.lua +663 -0
  203. package/project/.sdk/tm/lua/utility/struct/struct.lua +660 -420
  204. package/project/.sdk/tm/ocaml/Makefile +37 -12
  205. package/project/.sdk/tm/ocaml/test/omni_resolver.ml +284 -0
  206. package/project/.sdk/tm/ocaml/test/omni_smoke_test.ml +169 -0
  207. package/project/.sdk/tm/ocaml/test/primary_utility_test.ml +84 -100
  208. package/project/.sdk/tm/ocaml/test/struct_corpus.ml +225 -201
  209. package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +1157 -0
  210. package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +88 -12
  211. package/project/.sdk/tm/perl/t/omni.pm +647 -0
  212. package/project/.sdk/tm/perl/t/omni_smoke.t +87 -0
  213. package/project/.sdk/tm/perl/t/primary_utility.t +189 -487
  214. package/project/.sdk/tm/perl/t/struct_utility.t +455 -389
  215. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +649 -0
  216. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +253 -0
  217. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +24 -0
  218. package/project/.sdk/tm/perl/utility/prepare_method.pm +7 -2
  219. package/project/.sdk/tm/php/test/Omni.php +691 -0
  220. package/project/.sdk/tm/php/test/OmniSmokeTest.php +93 -0
  221. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +210 -571
  222. package/project/.sdk/tm/php/test/StructUtilityTest.php +320 -342
  223. package/project/.sdk/tm/php/test/vendor/omni/Runner.php +644 -0
  224. package/project/.sdk/tm/php/test/vendor/omni/Util.php +283 -0
  225. package/project/.sdk/tm/php/utility/MakeSpec.php +10 -3
  226. package/project/.sdk/tm/php/utility/PrepareBody.php +7 -1
  227. package/project/.sdk/tm/php/utility/PrepareMethod.php +6 -2
  228. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +36 -0
  229. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +141 -0
  230. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +50 -0
  231. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +333 -0
  232. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +198 -0
  233. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +147 -0
  234. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +52 -0
  235. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +139 -0
  236. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1053 -0
  237. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +171 -0
  238. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +95 -0
  239. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +116 -0
  240. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +59 -0
  241. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +87 -0
  242. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +112 -0
  243. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +76 -0
  244. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +116 -0
  245. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +192 -0
  246. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +120 -0
  247. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +140 -0
  248. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +62 -0
  249. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +101 -0
  250. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +151 -0
  251. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +115 -0
  252. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +90 -0
  253. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +101 -0
  254. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +119 -0
  255. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +125 -0
  256. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +211 -0
  257. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +475 -0
  258. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +467 -0
  259. package/project/.sdk/tm/py/pkg/utility/prepare_method.py +5 -1
  260. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/__init__.py +0 -2
  261. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +780 -529
  262. package/project/.sdk/tm/py/src/feature/secrets/.gitkeep +0 -0
  263. package/project/.sdk/tm/py/test/feature/__init__.py +0 -0
  264. package/project/.sdk/tm/py/test/feature/secrets/__init__.py +0 -0
  265. package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +337 -0
  266. package/project/.sdk/tm/py/test/omni.py +415 -0
  267. package/project/.sdk/tm/py/test/test_omni_smoke.py +74 -0
  268. package/project/.sdk/tm/py/test/test_primary_utility.py +144 -668
  269. package/project/.sdk/tm/py/test/test_struct_utility.py +74 -27
  270. package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +62 -0
  271. package/project/.sdk/tm/py/test/voxgig_omni/runner.py +580 -0
  272. package/project/.sdk/tm/py/test/voxgig_omni/util.py +252 -0
  273. package/project/.sdk/tm/rb/test/omni.rb +505 -0
  274. package/project/.sdk/tm/rb/test/omni_smoke_test.rb +72 -0
  275. package/project/.sdk/tm/rb/test/primary_utility_test.rb +174 -560
  276. package/project/.sdk/tm/rb/test/struct_utility_test.rb +13 -7
  277. package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +493 -0
  278. package/project/.sdk/tm/rb/test/vendor/omni/util.rb +199 -0
  279. package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +15 -0
  280. package/project/.sdk/tm/rb/utility/prepare_method.rb +5 -1
  281. package/project/.sdk/tm/rust/tests/common/mod.rs +19 -242
  282. package/project/.sdk/tm/rust/tests/omni_resolver/mod.rs +888 -0
  283. package/project/.sdk/tm/rust/tests/omni_smoke_test.rs +286 -0
  284. package/project/.sdk/tm/rust/tests/primary_utility_test.rs +318 -312
  285. package/project/.sdk/tm/rust/tests/struct_utility_test.rs +66 -28
  286. package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +412 -0
  287. package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +38 -0
  288. package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +392 -0
  289. package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +1001 -0
  290. package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +161 -0
  291. package/project/.sdk/tm/rust/utility/prepare_method.rs +5 -1
  292. package/project/.sdk/tm/scala/Makefile +16 -6
  293. package/project/.sdk/tm/scala/sdktest/OmniResolver.scala +497 -0
  294. package/project/.sdk/tm/scala/sdktest/OmniSmoke.scala +192 -0
  295. package/project/.sdk/tm/scala/sdktest/PrimaryCorpus.scala +47 -19
  296. package/project/.sdk/tm/scala/sdktest/StructCorpus.scala +0 -0
  297. package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +229 -0
  298. package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +552 -0
  299. package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +104 -0
  300. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Constants.swift +10 -0
  301. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Inject.swift +28 -5
  302. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Injection.swift +5 -1
  303. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Minor.swift +4 -1
  304. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Validate.swift +15 -5
  305. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +6 -1
  306. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniResolver.swift +474 -0
  307. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniSmokeTest.swift +107 -0
  308. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +141 -178
  309. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/Runner.swift +17 -113
  310. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/StructUtilityTest.swift +295 -446
  311. package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +364 -0
  312. package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +730 -0
  313. package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +162 -0
  314. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +7 -0
  315. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +148 -0
  316. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +55 -0
  317. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +344 -0
  318. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +205 -0
  319. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +138 -0
  320. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +46 -0
  321. package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +349 -0
  322. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +181 -0
  323. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1132 -0
  324. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +177 -0
  325. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +119 -0
  326. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +102 -0
  327. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +61 -0
  328. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +112 -0
  329. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +100 -0
  330. package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +37 -0
  331. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +163 -30
  332. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +27 -22
  333. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/aws.ts +26 -36
  334. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/azuresecrets.ts +19 -21
  335. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/boru.ts +36 -17
  336. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/doppler.ts +14 -21
  337. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/gcpsecrets.ts +27 -27
  338. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/hashicorp.ts +25 -39
  339. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +99 -0
  340. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/infisical.ts +14 -16
  341. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/onepassword.ts +15 -22
  342. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +98 -0
  343. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{Sigv4.ts → plugins/sigv4.ts} +7 -6
  344. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +97 -23
  345. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +37 -0
  346. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +4 -17
  347. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +4 -16
  348. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +11 -25
  349. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +6 -23
  350. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +106 -39
  351. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +3 -3
  352. package/project/.sdk/tm/ts/test/omni.ts +104 -32
  353. package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +27 -0
  354. package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +32 -5
  355. package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +2 -2
  356. package/project/.sdk/tm/ts/test/vendor/omni/index.ts +2 -2
  357. package/project/.sdk/tm/zig/Makefile +15 -1
  358. package/project/.sdk/tm/zig/build.zig +23 -5
  359. package/project/.sdk/tm/zig/core/helpers.zig +52 -11
  360. package/project/.sdk/tm/zig/core/mem.zig +17 -1
  361. package/project/.sdk/tm/zig/core/utility.zig +23 -19
  362. package/project/.sdk/tm/zig/feature/audit.zig +2 -2
  363. package/project/.sdk/tm/zig/feature/cache.zig +2 -2
  364. package/project/.sdk/tm/zig/feature/debug.zig +5 -5
  365. package/project/.sdk/tm/zig/feature/netsim.zig +2 -2
  366. package/project/.sdk/tm/zig/feature/paging.zig +2 -2
  367. package/project/.sdk/tm/zig/feature/proxy.zig +15 -8
  368. package/project/.sdk/tm/zig/feature/streaming.zig +5 -5
  369. package/project/.sdk/tm/zig/feature/support.zig +3 -3
  370. package/project/.sdk/tm/zig/feature/telemetry.zig +5 -5
  371. package/project/.sdk/tm/zig/feature/test.zig +10 -5
  372. package/project/.sdk/tm/zig/test/fh.zig +10 -10
  373. package/project/.sdk/tm/zig/test/gotcha_test.zig +5 -5
  374. package/project/.sdk/tm/zig/test/omniresolver.zig +515 -0
  375. package/project/.sdk/tm/zig/test/omnismoke_test.zig +284 -0
  376. package/project/.sdk/tm/zig/test/pipeline_test.zig +8 -8
  377. package/project/.sdk/tm/zig/test/primary_utility_test.zig +145 -155
  378. package/project/.sdk/tm/zig/test/struct_corpus.zig +264 -187
  379. package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +1314 -0
  380. package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +446 -0
  381. package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +7 -4
  382. package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +356 -157
  383. package/project/sdkgen-package.json +1 -1
  384. package/src/action/doctor.ts +66 -2
  385. package/src/helpers/naming.ts +4 -2
  386. package/project/.sdk/tm/c/tests/runner.h +0 -274
  387. package/project/.sdk/tm/cpp/test/struct_runner.hpp +0 -314
  388. package/project/.sdk/tm/csharp/test/StructRunner.cs +0 -276
  389. package/project/.sdk/tm/dart/test/runner.dart +0 -406
  390. package/project/.sdk/tm/dart/test/struct_corpus.dart +0 -531
  391. package/project/.sdk/tm/elixir/test/support/struct_corpus.ex +0 -1088
  392. package/project/.sdk/tm/go/test/runner_test.go +0 -629
  393. package/project/.sdk/tm/go/test/struct_runner_test.go +0 -1094
  394. package/project/.sdk/tm/java/test/StructRunner.java +0 -281
  395. package/project/.sdk/tm/js/test/runner.js +0 -387
  396. package/project/.sdk/tm/kotlin/test/StructRunner.kt +0 -177
  397. package/project/.sdk/tm/lua/test/struct_runner.lua +0 -602
  398. package/project/.sdk/tm/ocaml/test/corpus_runner.ml +0 -185
  399. package/project/.sdk/tm/perl/t/struct_runner.pm +0 -275
  400. package/project/.sdk/tm/php/test/StructRunner.php +0 -275
  401. package/project/.sdk/tm/py/test/struct_runner.py +0 -411
  402. package/project/.sdk/tm/rb/test/struct_runner.rb +0 -309
  403. package/project/.sdk/tm/rust/tests/struct_runner/mod.rs +0 -424
  404. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/Registry.ts +0 -90
  405. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/http.ts +0 -66
  406. package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +0 -188
  407. package/project/.sdk/tm/zig/test/struct_runner.zig +0 -464
@@ -1,8 +1,34 @@
1
1
  <?php
2
- // Vendored from voxgig/struct/php
3
-
4
- require_once __DIR__ . '/../utility/struct/Struct.php';
5
- require_once __DIR__ . '/StructRunner.php';
2
+ declare(strict_types=1);
3
+
4
+ // ProjectName SDK struct utility test
5
+ //
6
+ // The struct corpus driven through the vendored omni runner, via the
7
+ // resolver in test/Omni.php (`makeStructRunner`: the struct-runner shape
8
+ // over native Voxgig\Omni, with the php-only empty-map preservation and
9
+ // the object-model argument bridge). The dedicated StructRunner.php this
10
+ // suite used to ship beside (and its own inline testSet engine) are
11
+ // retired - see docs/design/vendor-tag-rollout.md.
12
+ //
13
+ // Subjects receive corpus values in the OBJECT model the old engine fed
14
+ // them (maps as stdClass, lists as arrays); results are normalised back
15
+ // to omni's array model by the resolver. Every section runs with
16
+ // `{null: false}`: the retired engine compared RAW nulls, and this
17
+ // vendored struct port answers stored-null questions the OLD way, so the
18
+ // NULLMARK rewrite would change what the corpus asserts here.
19
+ //
20
+ // struct.nullsem: NOT opted in. Measured against this vendored copy
21
+ // (tm/php/utility/struct), the five null questions answer the OLD way -
22
+ // getprop({x:null},'x','ALT') is null (canonical: 'ALT'),
23
+ // getprop([null],0,'ALT') is null, getpath reads the stored null,
24
+ // haskey({x:null},'x') is true (canonical: false), and
25
+ // validate({auth:null}, spec-with-default) THROWS (fail-closed) where
26
+ // canonical substitutes the default. getelem({x:null},'x','ALT') alone
27
+ // answers 'ALT'. The lane opts in when the php struct port is resynced
28
+ // (blocked upstream: see vendoring-upgrade-migration.md, "php is NOT").
29
+
30
+ require_once __DIR__ . '/../projectname_sdk.php';
31
+ require_once __DIR__ . '/Omni.php';
6
32
 
7
33
  use PHPUnit\Framework\TestCase;
8
34
  use Voxgig\Struct\Struct;
@@ -10,205 +36,142 @@ use Voxgig\Struct\ListRef;
10
36
 
11
37
  class StructUtilityTest extends TestCase
12
38
  {
39
+ private const TEST_JSON_FILE = '../../.sdk/test/test.json';
13
40
 
14
- private stdClass $testSpec;
41
+ private static ?array $run = null;
15
42
 
16
- protected function setUp(): void
43
+ /** The 'struct' runpack, built once for the whole class. */
44
+ private static function R(): array
17
45
  {
18
- $jsonPath = __DIR__ . '/../../.sdk/test/test.json';
19
- if (!file_exists($jsonPath)) {
20
- throw new RuntimeException("Test JSON file not found: $jsonPath");
21
- }
22
- $jsonContent = file_get_contents($jsonPath);
23
- if ($jsonContent === false) {
24
- throw new RuntimeException("Failed to read test JSON: $jsonPath");
25
- }
26
- // decode objects as stdClass, arrays as PHP arrays
27
- $data = json_decode($jsonContent, false);
28
- if (json_last_error() !== JSON_ERROR_NONE) {
29
- throw new RuntimeException("Invalid JSON: " . json_last_error_msg());
46
+ if (self::$run === null) {
47
+ $runner = ProjectNameOmni::makeStructRunner(
48
+ self::TEST_JSON_FILE, ProjectNameSDK::test(null, null));
49
+ self::$run = $runner('struct');
30
50
  }
31
- if (!isset($data->struct)) {
32
- throw new RuntimeException("'struct' key not found in the test JSON file.");
51
+ return self::$run;
52
+ }
53
+
54
+ /** One corpus section, asserted present. */
55
+ private function sect(string ...$path): array
56
+ {
57
+ $cur = self::R()['spec'];
58
+ foreach ($path as $key) {
59
+ $this->assertTrue(is_array($cur) && array_key_exists($key, $cur),
60
+ "struct corpus section '" . implode('.', $path) . "' missing");
61
+ $cur = $cur[$key];
33
62
  }
34
- $this->testSpec = $data->struct;
63
+ $this->assertIsArray($cur,
64
+ "struct corpus section '" . implode('.', $path) . "' is not a map");
65
+ return $cur;
35
66
  }
36
67
 
37
68
  /**
38
- * Helper that loops over each entry in $tests->set, calls $apply, then asserts:
39
- * - deep‐equals (assertEquals) if $forceEquals===true or expected is array/object,
40
- * - strict‐same (assertSame) otherwise.
69
+ * Run one section through the resolver, raw-null semantics (see the
70
+ * header note), failing loudly on a section that would run ZERO cases.
41
71
  *
42
- * @param stdClass $tests The spec object (has ->set array)
43
- * @param callable $apply Function to call on each entry's input
44
- * @param bool $forceEquals Whether to always use deep equality
72
+ * `$skip` names entry indices this VENDORED struct copy cannot answer
73
+ * (index => reason) - pre-resync defects the retired engine passed
74
+ * silently by never asserting on entries without `out`. Each skip is
75
+ * pinned to its index: when the corpus moves, the guard below fails
76
+ * and the divergence must be re-measured, not silently forgotten.
45
77
  */
46
- private function testSet(stdClass $tests, callable $apply, bool $forceEquals = false): void
47
- {
48
- foreach ($tests->set as $i => $entry) {
49
- $hasErr = property_exists($entry, 'err');
50
-
51
- // 1) Determine input
52
- try {
53
- if (property_exists($entry, 'args')) {
54
- $inForMsg = $entry->args;
55
- $result = $apply(...$entry->args);
56
- } else {
57
- $in = property_exists($entry, 'in') ? $entry->in : Struct::undef();
58
- $inForMsg = $in;
59
- $result = $apply($in);
60
- }
61
- } catch (\Throwable $e) {
62
- if ($hasErr) {
63
- $expectedErr = $entry->err;
64
- if ($expectedErr === true || str_contains($e->getMessage(), (string) $expectedErr)) {
65
- continue;
66
- }
67
- $this->fail(
68
- "Entry #{$i} error mismatch. Expected: {$expectedErr} | Got: " .
69
- $e->getMessage() . ' | Input: ' . json_encode($inForMsg ?? null)
70
- );
71
- }
72
- throw $e;
73
- }
74
-
75
- // Expected error but none thrown.
76
- if ($hasErr) {
77
- $this->fail(
78
- "Entry #{$i} expected error ({$entry->err}) but none was thrown. Input: " .
79
- json_encode($inForMsg)
80
- );
81
- }
78
+ private function runsection(array $testspec, callable $subject, array $skip = []): void
79
+ {
80
+ $set = $testspec['set'] ?? null;
81
+ $this->assertTrue(is_array($set) && 0 < count($set),
82
+ 'struct corpus section has no cases - zero entries would run');
82
83
 
83
- // 2) If no expected 'out', skip
84
- if (!property_exists($entry, 'out')) {
85
- continue;
84
+ if (0 < count($skip)) {
85
+ foreach (array_keys($skip) as $i) {
86
+ $this->assertArrayHasKey($i, $set,
87
+ "skipped entry [{$i}] vanished - the corpus moved; re-measure: " . $skip[$i]);
86
88
  }
87
- $expected = $entry->out;
88
-
89
- // 3) Choose assertion
90
- if ($forceEquals || is_array($expected) || is_object($expected)) {
91
- // Normalise both sides: transform() now returns PHP associative
92
- // arrays for map values, while test fixtures decode JSON into
93
- // stdClass. Compare on a common representation so shape matches
94
- // without caring about map carrier type.
95
- $expectedNorm = self::normalizeMaps($expected);
96
- $resultNorm = self::normalizeMaps($result);
97
- $this->assertEquals(
98
- $expectedNorm,
99
- $resultNorm,
100
- "Entry #{$i} failed deep‐equal. Input: " . json_encode($inForMsg)
101
- );
102
- } else {
103
- $this->assertSame(
104
- $expected,
105
- $result,
106
- "Entry #{$i} failed strict. Input: " . json_encode($inForMsg)
107
- );
89
+ $kept = [];
90
+ foreach ($set as $i => $entry) {
91
+ if (!array_key_exists($i, $skip)) {
92
+ $kept[] = $entry;
93
+ }
108
94
  }
95
+ $this->assertTrue(0 < count($kept),
96
+ 'every entry of the section is skipped - retire the section instead');
97
+ $testspec['set'] = $kept;
109
98
  }
99
+
100
+ self::R()['runsetflags']($testspec, ['null' => false], $subject);
101
+ $this->assertTrue(true, 'corpus section completed');
110
102
  }
111
103
 
112
- private static function normalizeMaps(mixed $val, int $depth = 0): mixed
104
+ /** A single-case fixture value in the object model (input side). */
105
+ private static function inval($val)
113
106
  {
114
- if ($depth > 64) {
115
- return $val;
116
- }
117
- if ($val instanceof \stdClass) {
118
- $out = [];
119
- foreach (get_object_vars($val) as $k => $v) {
120
- $out[$k] = self::normalizeMaps($v, $depth + 1);
121
- }
122
- return $out;
123
- }
124
- if (is_array($val)) {
125
- $out = [];
126
- foreach ($val as $k => $v) {
127
- $out[$k] = self::normalizeMaps($v, $depth + 1);
128
- }
129
- return $out;
130
- }
131
- return $val;
107
+ return ProjectNameOmni::objmodel(ProjectNameOmni::argval($val));
108
+ }
109
+
110
+ /** A single-case fixture value on the comparison side. */
111
+ private static function outval($val)
112
+ {
113
+ return ProjectNameOmni::unmark($val);
114
+ }
115
+
116
+ /** A result normalised to the comparison model. */
117
+ private static function resval($val)
118
+ {
119
+ return ProjectNameOmni::structfix($val, Struct::undef());
132
120
  }
133
121
 
122
+
134
123
  // ——— Exists test ———
135
124
  public function testExists(): void
136
125
  {
137
- $this->assertEquals('string', gettype([Struct::class, 'clone'][0]));
138
- $this->assertEquals('string', gettype([Struct::class, 'delprop'][0]));
139
- $this->assertEquals('string', gettype([Struct::class, 'escre'][0]));
140
- $this->assertEquals('string', gettype([Struct::class, 'escurl'][0]));
141
- $this->assertEquals('string', gettype([Struct::class, 'getelem'][0]));
142
- $this->assertEquals('string', gettype([Struct::class, 'getprop'][0]));
143
-
144
- $this->assertEquals('string', gettype([Struct::class, 'getpath'][0]));
145
- $this->assertEquals('string', gettype([Struct::class, 'haskey'][0]));
146
- $this->assertEquals('string', gettype([Struct::class, 'inject'][0]));
147
- $this->assertEquals('string', gettype([Struct::class, 'isempty'][0]));
148
- $this->assertEquals('string', gettype([Struct::class, 'isfunc'][0]));
149
-
150
- $this->assertEquals('string', gettype([Struct::class, 'iskey'][0]));
151
- $this->assertEquals('string', gettype([Struct::class, 'islist'][0]));
152
- $this->assertEquals('string', gettype([Struct::class, 'ismap'][0]));
153
- $this->assertEquals('string', gettype([Struct::class, 'isnode'][0]));
154
- $this->assertEquals('string', gettype([Struct::class, 'items'][0]));
155
-
156
- $this->assertEquals('string', gettype([Struct::class, 'joinurl'][0]));
157
- $this->assertEquals('string', gettype([Struct::class, 'jsonify'][0]));
158
- $this->assertEquals('string', gettype([Struct::class, 'keysof'][0]));
159
- $this->assertEquals('string', gettype([Struct::class, 'merge'][0]));
160
- $this->assertEquals('string', gettype([Struct::class, 'pad'][0]));
161
- $this->assertEquals('string', gettype([Struct::class, 'pathify'][0]));
162
-
163
- $this->assertEquals('string', gettype([Struct::class, 'select'][0]));
164
- $this->assertEquals('string', gettype([Struct::class, 'size'][0]));
165
- $this->assertEquals('string', gettype([Struct::class, 'slice'][0]));
166
- $this->assertEquals('string', gettype([Struct::class, 'setprop'][0]));
167
-
168
- $this->assertEquals('string', gettype([Struct::class, 'strkey'][0]));
169
- $this->assertEquals('string', gettype([Struct::class, 'stringify'][0]));
170
- $this->assertEquals('string', gettype([Struct::class, 'transform'][0]));
171
- $this->assertEquals('string', gettype([Struct::class, 'typify'][0]));
172
- $this->assertEquals('string', gettype([Struct::class, 'validate'][0]));
173
-
174
- $this->assertEquals('string', gettype([Struct::class, 'walk'][0]));
126
+ foreach ([
127
+ 'clone', 'delprop', 'escre', 'escurl', 'getelem', 'getprop',
128
+ 'getpath', 'haskey', 'inject', 'isempty', 'isfunc',
129
+ 'iskey', 'islist', 'ismap', 'isnode', 'items',
130
+ 'joinurl', 'jsonify', 'keysof', 'merge', 'pad', 'pathify',
131
+ 'select', 'size', 'slice', 'setprop',
132
+ 'strkey', 'stringify', 'transform', 'typify', 'validate',
133
+ 'walk',
134
+ ] as $name) {
135
+ $this->assertTrue(method_exists(Struct::class, $name),
136
+ "Struct::{$name} missing");
137
+ }
175
138
  }
176
139
 
177
140
  // ——— Minor/simple tests ———
178
- public function testIsnode()
141
+ public function testIsnode(): void
179
142
  {
180
- $this->testSet($this->testSpec->minor->isnode, [Struct::class, 'isnode']);
143
+ $this->runsection($this->sect('minor', 'isnode'), [Struct::class, 'isnode']);
181
144
  }
182
- public function testIsmap()
145
+ public function testIsmap(): void
183
146
  {
184
- $this->testSet($this->testSpec->minor->ismap, [Struct::class, 'ismap']);
147
+ $this->runsection($this->sect('minor', 'ismap'), [Struct::class, 'ismap']);
185
148
  }
186
- public function testIslist()
149
+ public function testIslist(): void
187
150
  {
188
- $this->testSet($this->testSpec->minor->islist, [Struct::class, 'islist']);
151
+ $this->runsection($this->sect('minor', 'islist'), [Struct::class, 'islist']);
189
152
  }
190
- public function testIskey()
153
+ public function testIskey(): void
191
154
  {
192
- $this->testSet($this->testSpec->minor->iskey, [Struct::class, 'iskey']);
155
+ $this->runsection($this->sect('minor', 'iskey'), [Struct::class, 'iskey']);
193
156
  }
194
- public function testIsempty()
157
+ public function testIsempty(): void
195
158
  {
196
- $this->testSet($this->testSpec->minor->isempty, [Struct::class, 'isempty']);
159
+ $this->runsection($this->sect('minor', 'isempty'), [Struct::class, 'isempty']);
197
160
  }
198
- public function testIsfunc()
161
+ public function testIsfunc(): void
199
162
  {
200
- $this->testSet($this->testSpec->minor->isfunc, [Struct::class, 'isfunc']);
163
+ $this->runsection($this->sect('minor', 'isfunc'), [Struct::class, 'isfunc']);
201
164
  }
202
- public function testTypify()
165
+ public function testTypify(): void
203
166
  {
204
- $this->testSet($this->testSpec->minor->typify, [Struct::class, 'typify']);
167
+ $this->runsection($this->sect('minor', 'typify'), [Struct::class, 'typify']);
205
168
  }
206
169
 
207
170
  // ——— getprop needs to extract stdClass props ———
208
171
  public function testGetprop(): void
209
172
  {
210
- $this->testSet(
211
- $this->testSpec->minor->getprop,
173
+ $this->runsection(
174
+ $this->sect('minor', 'getprop'),
212
175
  function ($input) {
213
176
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
214
177
  $key = property_exists($input, 'key') ? $input->key : Struct::undef();
@@ -220,28 +183,28 @@ class StructUtilityTest extends TestCase
220
183
 
221
184
  public function testGetelem(): void
222
185
  {
223
- $this->testSet(
224
- $this->testSpec->minor->getelem,
186
+ $this->runsection(
187
+ $this->sect('minor', 'getelem'),
225
188
  function ($input) {
226
189
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
227
190
  $key = property_exists($input, 'key') ? $input->key : Struct::undef();
228
191
  $alt = property_exists($input, 'alt') ? $input->alt : Struct::undef();
229
- return $alt === Struct::undef() ?
230
- Struct::getelem($val, $key) :
192
+ return $alt === Struct::undef() ?
193
+ Struct::getelem($val, $key) :
231
194
  Struct::getelem($val, $key, $alt);
232
195
  }
233
196
  );
234
197
  }
235
198
 
236
199
  // ——— Simple again ———
237
- public function testStrkey()
200
+ public function testStrkey(): void
238
201
  {
239
- $this->testSet($this->testSpec->minor->strkey, [Struct::class, 'strkey']);
202
+ $this->runsection($this->sect('minor', 'strkey'), [Struct::class, 'strkey']);
240
203
  }
241
- public function testHaskey()
204
+ public function testHaskey(): void
242
205
  {
243
- $this->testSet(
244
- $this->testSpec->minor->haskey,
206
+ $this->runsection(
207
+ $this->sect('minor', 'haskey'),
245
208
  function ($input) {
246
209
  $src = property_exists($input, 'src') ? $input->src : Struct::undef();
247
210
  $key = property_exists($input, 'key') ? $input->key : Struct::undef();
@@ -250,46 +213,40 @@ class StructUtilityTest extends TestCase
250
213
  );
251
214
  }
252
215
 
253
- public function testKeysof()
216
+ public function testKeysof(): void
254
217
  {
255
- $this->testSet($this->testSpec->minor->keysof, [Struct::class, 'keysof']);
218
+ $this->runsection($this->sect('minor', 'keysof'), [Struct::class, 'keysof']);
256
219
  }
257
220
 
258
- // ——— items returns array of [key, stdClass/array], so deep-equal ———
259
221
  public function testItems(): void
260
222
  {
261
- $this->testSet(
262
- $this->testSpec->minor->items,
263
- fn($in) => Struct::items($in),
264
- /*forceEquals=*/ true
265
- );
223
+ $this->runsection($this->sect('minor', 'items'), fn($in) => Struct::items($in));
266
224
  }
267
225
 
268
- public function testEscre()
226
+ public function testEscre(): void
269
227
  {
270
- $this->testSet($this->testSpec->minor->escre, [Struct::class, 'escre']);
228
+ $this->runsection($this->sect('minor', 'escre'), [Struct::class, 'escre']);
271
229
  }
272
- public function testEscurl()
230
+ public function testEscurl(): void
273
231
  {
274
- $this->testSet($this->testSpec->minor->escurl, [Struct::class, 'escurl']);
232
+ $this->runsection($this->sect('minor', 'escurl'), [Struct::class, 'escurl']);
275
233
  }
276
234
 
277
- public function testDelprop()
235
+ public function testDelprop(): void
278
236
  {
279
- $this->testSet(
280
- $this->testSpec->minor->delprop,
237
+ $this->runsection(
238
+ $this->sect('minor', 'delprop'),
281
239
  function ($input) {
282
- $parent = property_exists($input, 'parent') ? $input->parent : [];
240
+ $parent = property_exists($input, 'parent') ? $input->parent : Struct::undef();
283
241
  $key = property_exists($input, 'key') ? $input->key : null;
284
242
  return Struct::delprop($parent, $key);
285
- },
286
- true
243
+ }
287
244
  );
288
245
  }
289
- public function testJoinurl()
246
+ public function testJoinurl(): void
290
247
  {
291
- $this->testSet(
292
- $this->testSpec->minor->join,
248
+ $this->runsection(
249
+ $this->sect('minor', 'join'),
293
250
  function ($input) {
294
251
  $val = property_exists($input, 'val') ? $input->val : [];
295
252
  $sep = property_exists($input, 'sep') ? $input->sep : null;
@@ -299,10 +256,10 @@ class StructUtilityTest extends TestCase
299
256
  );
300
257
  }
301
258
 
302
- public function testJsonify()
259
+ public function testJsonify(): void
303
260
  {
304
- $this->testSet(
305
- $this->testSpec->minor->jsonify,
261
+ $this->runsection(
262
+ $this->sect('minor', 'jsonify'),
306
263
  function ($input) {
307
264
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
308
265
  $flags = property_exists($input, 'flags') ? $input->flags : null;
@@ -311,15 +268,15 @@ class StructUtilityTest extends TestCase
311
268
  );
312
269
  }
313
270
 
314
- public function testSize()
271
+ public function testSize(): void
315
272
  {
316
- $this->testSet($this->testSpec->minor->size, [Struct::class, 'size']);
273
+ $this->runsection($this->sect('minor', 'size'), [Struct::class, 'size']);
317
274
  }
318
275
 
319
- public function testSlice()
276
+ public function testSlice(): void
320
277
  {
321
- $this->testSet(
322
- $this->testSpec->minor->slice,
278
+ $this->runsection(
279
+ $this->sect('minor', 'slice'),
323
280
  function ($input) {
324
281
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
325
282
  $start = property_exists($input, 'start') ? $input->start : null;
@@ -329,10 +286,10 @@ class StructUtilityTest extends TestCase
329
286
  );
330
287
  }
331
288
 
332
- public function testPad()
289
+ public function testPad(): void
333
290
  {
334
- $this->testSet(
335
- $this->testSpec->minor->pad,
291
+ $this->runsection(
292
+ $this->sect('minor', 'pad'),
336
293
  function ($input) {
337
294
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
338
295
  $pad = property_exists($input, 'pad') ? $input->pad : null;
@@ -342,11 +299,11 @@ class StructUtilityTest extends TestCase
342
299
  );
343
300
  }
344
301
 
345
- // ——— stringify returns strings but built from objects, so deep-equal ———
302
+ // ——— stringify ———
346
303
  public function testStringify(): void
347
304
  {
348
- $this->testSet(
349
- $this->testSpec->minor->stringify,
305
+ $this->runsection(
306
+ $this->sect('minor', 'stringify'),
350
307
  function ($input) {
351
308
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
352
309
  if ($val === null) {
@@ -355,17 +312,16 @@ class StructUtilityTest extends TestCase
355
312
  return property_exists($input, 'max')
356
313
  ? Struct::stringify($val, $input->max)
357
314
  : Struct::stringify($val);
358
- },
359
- true
315
+ }
360
316
  );
361
317
  }
362
318
 
363
- // ——— pathify returns strings but tests include null-marker tweaks ———
319
+ // ——— pathify: null-marker tweaks preserved from the retired engine ———
364
320
  public function testPathify(): void
365
321
  {
366
- $this->testSet(
367
- $this->testSpec->minor->pathify,
368
- function (stdClass $entry) {
322
+ $this->runsection(
323
+ $this->sect('minor', 'pathify'),
324
+ function ($entry) {
369
325
  // 1) If the JSON had no "path" key at all, use our UNDEF marker.
370
326
  // Otherwise take whatever value was there (could be null).
371
327
  $raw = property_exists($entry, 'path')
@@ -384,9 +340,7 @@ class StructUtilityTest extends TestCase
384
340
  // 4) Run PHP port of pathify
385
341
  $s = Struct::pathify($path, $from);
386
342
 
387
- // 5) Strip out any UNDEF fragments (no-op with sentinel object)
388
-
389
- // 6) TS does: if vin.path === NULLMARK then add ":null>"
343
+ // 5) TS does: if vin.path === NULLMARK then add ":null>"
390
344
  // In our convention, JSON null => raw === null (not UNDEF),
391
345
  // so we inject only when raw === null.
392
346
  if ($raw === null) {
@@ -394,8 +348,7 @@ class StructUtilityTest extends TestCase
394
348
  }
395
349
 
396
350
  return $s;
397
- },
398
- /* deep‐equal = */ true
351
+ }
399
352
  );
400
353
  }
401
354
 
@@ -429,15 +382,15 @@ class StructUtilityTest extends TestCase
429
382
 
430
383
  public function testGetpathHandler(): void
431
384
  {
432
- $this->testSet(
433
- $this->testSpec->getpath->handler,
385
+ $this->runsection(
386
+ $this->sect('getpath', 'handler'),
434
387
  function ($input) {
435
388
  $store = [
436
389
  '$TOP' => $input->store,
437
- '$FOO' => function() { return 'foo'; }
390
+ '$FOO' => function () { return 'foo'; }
438
391
  ];
439
392
  $state = new \stdClass();
440
- $state->handler = function($inj, $val, $cur, $ref) {
393
+ $state->handler = function ($inj, $val, $cur, $ref) {
441
394
  return $val();
442
395
  };
443
396
  return Struct::getpath(
@@ -451,24 +404,19 @@ class StructUtilityTest extends TestCase
451
404
 
452
405
  public function testClone(): void
453
406
  {
454
- $this->testSet(
455
- $this->testSpec->minor->clone,
456
- fn($in) => Struct::clone($in),
457
- true
458
- );
407
+ $this->runsection($this->sect('minor', 'clone'), fn($in) => Struct::clone($in));
459
408
  }
460
409
 
461
410
  public function testSetprop(): void
462
411
  {
463
- $this->testSet(
464
- $this->testSpec->minor->setprop,
412
+ $this->runsection(
413
+ $this->sect('minor', 'setprop'),
465
414
  function ($input) {
466
- $parent = property_exists($input, 'parent') ? $input->parent : [];
415
+ $parent = property_exists($input, 'parent') ? $input->parent : Struct::undef();
467
416
  $key = property_exists($input, 'key') ? $input->key : null;
468
417
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
469
418
  return Struct::setprop($parent, $key, $val);
470
- },
471
- true
419
+ }
472
420
  );
473
421
  }
474
422
 
@@ -489,8 +437,9 @@ class StructUtilityTest extends TestCase
489
437
 
490
438
  public function testWalkLog(): void
491
439
  {
492
- $spec = $this->testSpec->walk->log;
493
- $test = Struct::clone($spec);
440
+ $spec = $this->sect('walk', 'log');
441
+ $test = self::inval($spec['in'] ?? null);
442
+ $expect = self::outval($spec['out'] ?? []);
494
443
 
495
444
  $log = [];
496
445
  $walklog = function ($key, $val, $parent, $path) use (&$log) {
@@ -503,38 +452,35 @@ class StructUtilityTest extends TestCase
503
452
  return $val;
504
453
  };
505
454
 
506
- Struct::walk($test->in, null, $walklog);
455
+ Struct::walk(Struct::clone($test), null, $walklog);
507
456
  $this->assertEquals(
508
- $test->out->after,
457
+ $expect['after'] ?? null,
509
458
  $log,
510
459
  "walk-log after did not match"
511
460
  );
512
461
 
513
462
  $log = [];
514
- Struct::walk($test->in, $walklog);
463
+ Struct::walk(Struct::clone($test), $walklog);
515
464
  $this->assertEquals(
516
- $test->out->before,
465
+ $expect['before'] ?? null,
517
466
  $log,
518
467
  "walk-log before did not match"
519
468
  );
520
469
 
521
470
  $log = [];
522
- Struct::walk($test->in, $walklog, $walklog);
471
+ Struct::walk(Struct::clone($test), $walklog, $walklog);
523
472
  $this->assertEquals(
524
- $test->out->both,
473
+ $expect['both'] ?? null,
525
474
  $log,
526
475
  "walk-log both did not match"
527
476
  );
528
477
  }
529
478
 
530
- /**
531
- * @covers \Voxgig\Struct\Struct::walk
532
- */
533
479
  public function testWalkBasic(): void
534
480
  {
535
- $this->testSet(
536
- $this->testSpec->walk->basic,
537
- function ($input) {
481
+ $this->runsection(
482
+ $this->sect('walk', 'basic'),
483
+ function ($input = null) {
538
484
  return Struct::walk(
539
485
  $input,
540
486
  function ($_k, $v, $_p, $path) {
@@ -543,51 +489,37 @@ class StructUtilityTest extends TestCase
543
489
  : $v;
544
490
  }
545
491
  );
546
- },
547
- true
492
+ }
548
493
  );
549
494
  }
550
495
 
551
496
 
552
497
  public function testMergeBasic(): void
553
498
  {
554
- $spec = $this->testSpec->merge->basic;
555
- $in = Struct::clone($spec->in);
499
+ $spec = $this->sect('merge', 'basic');
500
+ $in = self::inval($spec['in'] ?? null);
556
501
  $out = Struct::merge($in);
557
502
 
558
503
  $this->assertEquals(
559
- $spec->out,
560
- $out,
504
+ self::outval($spec['out'] ?? null),
505
+ self::resval($out),
561
506
  "merge-basic did not produce the expected result"
562
507
  );
563
508
  }
564
509
 
565
510
  public function testMergeCases(): void
566
511
  {
567
- $this->testSet(
568
- $this->testSpec->merge->cases,
569
- // take the input array/val as-is, don't try to read ->in again
570
- fn($in) => Struct::merge($in),
571
- /* force deep‐equal */ true
572
- );
512
+ $this->runsection($this->sect('merge', 'cases'), fn($in) => Struct::merge($in));
573
513
  }
574
514
 
575
515
  public function testMergeArray(): void
576
516
  {
577
- $this->testSet(
578
- $this->testSpec->merge->array,
579
- fn($in) => Struct::merge($in),
580
- /* force deep‐equal */ true
581
- );
517
+ $this->runsection($this->sect('merge', 'array'), fn($in) => Struct::merge($in));
582
518
  }
583
519
 
584
520
  public function testMergeIntegrity(): void
585
521
  {
586
- $this->testSet(
587
- $this->testSpec->merge->integrity,
588
- fn($in) => Struct::merge($in),
589
- /* force deep‐equal */ true
590
- );
522
+ $this->runsection($this->sect('merge', 'integrity'), fn($in) => Struct::merge($in));
591
523
  }
592
524
 
593
525
  public function testMergeSpecial(): void
@@ -624,22 +556,21 @@ class StructUtilityTest extends TestCase
624
556
 
625
557
  public function testGetpathBasic(): void
626
558
  {
627
- $this->testSet(
628
- $this->testSpec->getpath->basic,
559
+ $this->runsection(
560
+ $this->sect('getpath', 'basic'),
629
561
  function ($input) {
630
562
  $path = property_exists($input, 'path') ? $input->path : Struct::undef();
631
563
  $store = property_exists($input, 'store') ? $input->store : Struct::undef();
632
564
  $result = Struct::getpath($store, $path);
633
565
  return $result;
634
- },
635
- true
566
+ }
636
567
  );
637
568
  }
638
569
 
639
570
  public function testGetpathRelative(): void
640
571
  {
641
- $this->testSet(
642
- $this->testSpec->getpath->relative,
572
+ $this->runsection(
573
+ $this->sect('getpath', 'relative'),
643
574
  function ($input) {
644
575
  $path = property_exists($input, 'path') ? $input->path : Struct::undef();
645
576
  $store = property_exists($input, 'store') ? $input->store : Struct::undef();
@@ -652,15 +583,14 @@ class StructUtilityTest extends TestCase
652
583
  }
653
584
  $result = Struct::getpath($store, $path, $state);
654
585
  return $result;
655
- },
656
- true
586
+ }
657
587
  );
658
588
  }
659
589
 
660
590
  public function testGetpathSpecial(): void
661
591
  {
662
- $this->testSet(
663
- $this->testSpec->getpath->special,
592
+ $this->runsection(
593
+ $this->sect('getpath', 'special'),
664
594
  function ($input) {
665
595
  $path = property_exists($input, 'path') ? $input->path : Struct::undef();
666
596
  $store = property_exists($input, 'store') ? $input->store : Struct::undef();
@@ -668,23 +598,34 @@ class StructUtilityTest extends TestCase
668
598
  $result = Struct::getpath($store, $path, $state);
669
599
  return $result;
670
600
  },
671
- true
601
+ [
602
+ // Pre-resync defect, measured: an UNRESOLVED $REF/$GET/$META
603
+ // segment answers the WHOLE STORE here where canonical
604
+ // answers no value (the resolved siblings [4]/[6]/[8] pass,
605
+ // and the ~-meta miss [12] correctly answers no value). The
606
+ // retired engine passed these by never asserting on entries
607
+ // without `out`. Unskip at the php struct resync (blocked -
608
+ // vendoring-upgrade-migration.md).
609
+ 5 => 'vendored getpath answers the store for an unresolved $REF segment',
610
+ 7 => 'vendored getpath answers the store for an unresolved $GET segment',
611
+ 9 => 'vendored getpath answers the store for an unresolved $META segment',
612
+ ]
672
613
  );
673
614
  }
674
615
 
675
616
  public function testInjectBasic(): void
676
617
  {
677
- // single‐case spec: injectSpec.basic
678
- $spec = $this->testSpec->inject->basic;
618
+ $spec = $this->sect('inject', 'basic');
619
+ $in = self::inval($spec['in'] ?? null);
679
620
  // clone the input so we don't modify the fixture
680
- $val = Struct::clone($spec->in->val);
681
- $store = $spec->in->store;
621
+ $val = Struct::clone($in->val);
622
+ $store = $in->store;
682
623
 
683
624
  $result = Struct::inject($val, $store);
684
625
 
685
626
  $this->assertEquals(
686
- $spec->out,
687
- $result,
627
+ self::outval($spec['out'] ?? null),
628
+ self::resval($result),
688
629
  "inject-basic did not produce the expected result"
689
630
  );
690
631
  }
@@ -697,14 +638,13 @@ class StructUtilityTest extends TestCase
697
638
  return $v;
698
639
  };
699
640
 
700
- $this->testSet(
701
- $this->testSpec->inject->string,
702
- function (stdClass $in) use ($nullModifier) {
641
+ $this->runsection(
642
+ $this->sect('inject', 'string'),
643
+ function ($in) use ($nullModifier) {
703
644
  $opts = new \stdClass();
704
645
  $opts->modify = $nullModifier;
705
646
  return Struct::inject($in->val, $in->store, $opts);
706
- },
707
- /* force deep‐equal */ true
647
+ }
708
648
  );
709
649
  }
710
650
 
@@ -714,28 +654,26 @@ class StructUtilityTest extends TestCase
714
654
  */
715
655
  public function testInjectDeep(): void
716
656
  {
717
- $this->testSet(
718
- $this->testSpec->inject->deep,
719
- function (stdClass $in) {
657
+ $this->runsection(
658
+ $this->sect('inject', 'deep'),
659
+ function ($in) {
720
660
  // deep tests never need a modifier or current
721
661
  $val = property_exists($in, 'val') ? $in->val : null;
722
662
  $store = property_exists($in, 'store') ? $in->store : null;
723
663
  return Struct::inject($val, $store);
724
- },
725
- /* force deep‐equal */ true
664
+ }
726
665
  );
727
666
  }
728
667
 
729
668
  // ——— transform-basic ———
730
669
  public function testTransformBasic(): void
731
670
  {
732
- // single‐case test (no "set" array)
733
- $test = $this->testSpec->transform->basic;
734
- $in = $test->in;
671
+ $spec = $this->sect('transform', 'basic');
672
+ $in = self::inval($spec['in'] ?? null);
735
673
  $out = Struct::transform($in->data, $in->spec);
736
674
  $this->assertEquals(
737
- self::normalizeMaps($test->out),
738
- self::normalizeMaps($out),
675
+ self::outval($spec['out'] ?? null),
676
+ self::resval($out),
739
677
  'transform-basic failed'
740
678
  );
741
679
  }
@@ -743,21 +681,30 @@ class StructUtilityTest extends TestCase
743
681
  // ——— transform-paths ———
744
682
  public function testTransformPaths(): void
745
683
  {
746
- $this->testSet(
747
- $this->testSpec->transform->paths,
684
+ $this->runsection(
685
+ $this->sect('transform', 'paths'),
748
686
  fn(object $vin) => Struct::transform(
749
687
  property_exists($vin, 'data') ? $vin->data : (object) [],
750
688
  property_exists($vin, 'spec') ? $vin->spec : null,
751
689
  property_exists($vin, 'store') ? $vin->store : (object) []
752
- )
690
+ ),
691
+ [
692
+ // Pre-resync defect, measured: a bare-string spec whose
693
+ // reference resolves to nothing answers a value here
694
+ // (canonical: no value) - the same quirk PrepareBody
695
+ // collapses for the SDK. Unskip at the php struct resync.
696
+ 5 => 'vendored transform answers a value for a reference that resolves to nothing',
697
+ 6 => 'vendored transform answers a value for a reference that resolves to nothing',
698
+ 7 => 'vendored transform answers a value for a reference that resolves to nothing',
699
+ ]
753
700
  );
754
701
  }
755
702
 
756
703
  // ——— transform-cmds ———
757
704
  public function testTransformCmds(): void
758
705
  {
759
- $this->testSet(
760
- $this->testSpec->transform->cmds,
706
+ $this->runsection(
707
+ $this->sect('transform', 'cmds'),
761
708
  fn(object $vin) => Struct::transform(
762
709
  property_exists($vin, 'data') ? $vin->data : (object) [],
763
710
  property_exists($vin, 'spec') ? $vin->spec : null,
@@ -781,8 +728,8 @@ class StructUtilityTest extends TestCase
781
728
 
782
729
  public function testTransformModify(): void
783
730
  {
784
- $this->testSet(
785
- $this->testSpec->transform->modify,
731
+ $this->runsection(
732
+ $this->sect('transform', 'modify'),
786
733
  function (object $vin) {
787
734
  $opts = new \stdClass();
788
735
  $opts->extra = property_exists($vin, 'store') ? $vin->store : (object) [];
@@ -802,8 +749,8 @@ class StructUtilityTest extends TestCase
802
749
 
803
750
  public function testTransformRef(): void
804
751
  {
805
- $this->testSet(
806
- $this->testSpec->transform->ref,
752
+ $this->runsection(
753
+ $this->sect('transform', 'ref'),
807
754
  function ($input) {
808
755
  return Struct::transform(
809
756
  property_exists($input, 'data') ? $input->data : (object) [],
@@ -838,12 +785,12 @@ class StructUtilityTest extends TestCase
838
785
  );
839
786
 
840
787
  $this->assertEquals(
841
- self::normalizeMaps((object) [
788
+ self::resval((object) [
842
789
  'x' => 1,
843
790
  'b' => 2,
844
791
  'c' => 'C',
845
792
  ]),
846
- self::normalizeMaps($res)
793
+ self::resval($res)
847
794
  );
848
795
  }
849
796
 
@@ -875,8 +822,8 @@ class StructUtilityTest extends TestCase
875
822
  public function testValidateInvalid(): void
876
823
  {
877
824
  $count = 0;
878
- $this->testSet(
879
- $this->testSpec->validate->invalid,
825
+ $this->runsection(
826
+ $this->sect('validate', 'invalid'),
880
827
  function ($input) use (&$count) {
881
828
  $count++;
882
829
  return Struct::validate(
@@ -907,8 +854,8 @@ class StructUtilityTest extends TestCase
907
854
 
908
855
  // literal value stays literal
909
856
  $this->assertEquals(
910
- self::normalizeMaps((object) ['x' => 1]),
911
- self::normalizeMaps(Struct::transform((object) [], (object) ['x' => 1]))
857
+ self::resval((object) ['x' => 1]),
858
+ self::resval(Struct::transform((object) [], (object) ['x' => 1]))
912
859
  );
913
860
 
914
861
  // function as a spec value is preserved
@@ -917,8 +864,8 @@ class StructUtilityTest extends TestCase
917
864
 
918
865
  // backtick reference to a number field
919
866
  $this->assertEquals(
920
- self::normalizeMaps((object) ['x' => 1]),
921
- self::normalizeMaps(Struct::transform((object) ['a' => 1], (object) ['x' => '`a`']))
867
+ self::resval((object) ['x' => 1]),
868
+ self::resval(Struct::transform((object) ['a' => 1], (object) ['x' => '`a`']))
922
869
  );
923
870
 
924
871
  // backtick reference to a function field
@@ -951,19 +898,18 @@ class StructUtilityTest extends TestCase
951
898
 
952
899
  public function testTypename(): void
953
900
  {
954
- $this->testSet($this->testSpec->minor->typename, [Struct::class, 'typename']);
901
+ $this->runsection($this->sect('minor', 'typename'), [Struct::class, 'typename']);
955
902
  }
956
903
 
957
904
  public function testFlatten(): void
958
905
  {
959
- $this->testSet(
960
- $this->testSpec->minor->flatten,
906
+ $this->runsection(
907
+ $this->sect('minor', 'flatten'),
961
908
  function ($input) {
962
909
  $val = property_exists($input, 'val') ? $input->val : [];
963
910
  $depth = property_exists($input, 'depth') ? $input->depth : null;
964
911
  return Struct::flatten($val, $depth);
965
- },
966
- true
912
+ }
967
913
  );
968
914
  }
969
915
 
@@ -973,28 +919,64 @@ class StructUtilityTest extends TestCase
973
919
  'gt3' => function ($n) { return $n[1] > 3; },
974
920
  'lt3' => function ($n) { return $n[1] < 3; },
975
921
  ];
976
- $this->testSet(
977
- $this->testSpec->minor->filter,
922
+ $this->runsection(
923
+ $this->sect('minor', 'filter'),
978
924
  function ($input) use ($checkmap) {
979
925
  $val = property_exists($input, 'val') ? $input->val : [];
980
926
  $check = $checkmap[$input->check];
981
927
  return Struct::filter($val, $check);
982
- },
983
- true
928
+ }
984
929
  );
985
930
  }
986
931
 
987
932
  public function testSetpath(): void
988
933
  {
989
- $this->testSet(
990
- $this->testSpec->minor->setpath,
934
+ // The corpus's `match: {args: [{store: ...}]}` entries assert the
935
+ // store was mutated IN PLACE. omni-php cannot read a post-call
936
+ // argument (PHP arrays are value types and the runner clones at
937
+ // the boundary), so the subject carries that assertion instead:
938
+ // the returned store must BE the stdClass it was handed, which
939
+ // makes the `out` comparison cover the mutated store too. The
940
+ // match blocks are stripped here, not on disk.
941
+ $testspec = $this->sect('minor', 'setpath');
942
+ $testspec['set'] = array_map(function ($e) {
943
+ if (is_array($e)) {
944
+ unset($e['match']);
945
+ }
946
+ return $e;
947
+ }, $testspec['set'] ?? []);
948
+
949
+ $this->runsection(
950
+ $testspec,
991
951
  function ($input) {
992
952
  $store = property_exists($input, 'store') ? $input->store : (object) [];
993
- $path = property_exists($input, 'path') ? $input->path : '';
953
+ $path = property_exists($input, 'path') ? $input->path : Struct::undef();
994
954
  $val = property_exists($input, 'val') ? $input->val : Struct::undef();
995
- return Struct::setpath($store, $path, $val);
955
+ $result = Struct::setpath($store, $path, $val);
956
+ $haspath = (is_string($path) && '' !== $path)
957
+ || (is_array($path) && 0 < count($path));
958
+ if (is_object($store) && $haspath && Struct::undef() !== $val) {
959
+ // An array path may carry int parts this getpath chokes
960
+ // on - read back through the dotted spelling.
961
+ $checkpath = is_array($path)
962
+ ? implode('.', array_map('strval', $path)) : $path;
963
+ $now = Struct::getpath($store, $checkpath);
964
+ if (json_encode(ProjectNameOmni::structfix($now, Struct::undef()))
965
+ !== json_encode(ProjectNameOmni::structfix($val, Struct::undef()))) {
966
+ throw new \Exception('setpath did not mutate its store in place');
967
+ }
968
+ }
969
+ return $result;
996
970
  },
997
- true
971
+ [
972
+ // Pre-resync mutation defect, measured: for the ARRAY path
973
+ // ['x','y',0] on an empty store this vendored setpath
974
+ // RETURNS [6] but leaves the store at {"x":{"y":[]}} - the
975
+ // created list leaf never reaches the store (the PHP
976
+ // value-array problem ListRef exists to solve). Exactly the
977
+ // in-place assertion above; unskip at the php struct resync.
978
+ 5 => 'vendored setpath loses the created list leaf from the store on an array path',
979
+ ]
998
980
  );
999
981
  }
1000
982
 
@@ -1130,14 +1112,13 @@ class StructUtilityTest extends TestCase
1130
1112
 
1131
1113
  public function testMergeDepth(): void
1132
1114
  {
1133
- $this->testSet(
1134
- $this->testSpec->merge->depth,
1115
+ $this->runsection(
1116
+ $this->sect('merge', 'depth'),
1135
1117
  function ($input) {
1136
1118
  $val = property_exists($input, 'val') ? $input->val : [];
1137
1119
  $depth = property_exists($input, 'depth') ? $input->depth : null;
1138
1120
  return Struct::merge($val, $depth);
1139
- },
1140
- true
1121
+ }
1141
1122
  );
1142
1123
  }
1143
1124
 
@@ -1177,20 +1158,19 @@ class StructUtilityTest extends TestCase
1177
1158
  return $val;
1178
1159
  };
1179
1160
 
1180
- $this->testSet(
1181
- $this->testSpec->walk->copy,
1182
- function ($vin) use (&$cur, $walkcopy_before, $walkcopy_after) {
1161
+ $this->runsection(
1162
+ $this->sect('walk', 'copy'),
1163
+ function ($vin = null) use (&$cur, $walkcopy_before, $walkcopy_after) {
1183
1164
  Struct::walk($vin, $walkcopy_before, $walkcopy_after);
1184
1165
  return $cur[0];
1185
- },
1186
- true
1166
+ }
1187
1167
  );
1188
1168
  }
1189
1169
 
1190
1170
  public function testWalkDepth(): void
1191
1171
  {
1192
- $this->testSet(
1193
- $this->testSpec->walk->depth,
1172
+ $this->runsection(
1173
+ $this->sect('walk', 'depth'),
1194
1174
  function ($vin) {
1195
1175
  if (!is_object($vin) || !property_exists($vin, 'src')) {
1196
1176
  return null;
@@ -1215,8 +1195,7 @@ class StructUtilityTest extends TestCase
1215
1195
  $maxdepth = property_exists($vin, 'maxdepth') ? $vin->maxdepth : null;
1216
1196
  Struct::walk($vin->src, $copy, null, $maxdepth);
1217
1197
  return $top;
1218
- },
1219
- true
1198
+ }
1220
1199
  );
1221
1200
  }
1222
1201
 
@@ -1332,5 +1311,4 @@ class StructUtilityTest extends TestCase
1332
1311
  $result6 = Struct::validate($data6, $spec, $injdef6);
1333
1312
  $this->assertEmpty($errs6, 'empty ListRef should not cause type-mismatch against map spec');
1334
1313
  }
1335
-
1336
1314
  }