@voxgig/sdkgen 1.3.17 → 1.3.18

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 (220) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/cmp/Entity.js +5 -1
  3. package/dist/cmp/Entity.js.map +1 -1
  4. package/dist/cmp/Feature.js +2 -1
  5. package/dist/cmp/Feature.js.map +1 -1
  6. package/dist/helpers/canonType.js +8 -3
  7. package/dist/helpers/canonType.js.map +1 -1
  8. package/dist/helpers/collectDeps.d.ts +1 -1
  9. package/dist/helpers/collectDeps.js +36 -13
  10. package/dist/helpers/collectDeps.js.map +1 -1
  11. package/dist/helpers/naming.d.ts +3 -1
  12. package/dist/helpers/naming.js +53 -0
  13. package/dist/helpers/naming.js.map +1 -1
  14. package/dist/helpers/opShape.d.ts +3 -1
  15. package/dist/helpers/opShape.js +87 -8
  16. package/dist/helpers/opShape.js.map +1 -1
  17. package/dist/sdkgen.d.ts +3 -3
  18. package/dist/sdkgen.js +6 -2
  19. package/dist/sdkgen.js.map +1 -1
  20. package/dist/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +15 -10
  22. package/project/.sdk/model/target/cpp.aontu +4 -4
  23. package/project/.sdk/model/target/go-cli.aontu +17 -17
  24. package/project/.sdk/model/target/go-mcp.aontu +11 -11
  25. package/project/.sdk/model/target/go.aontu +1 -1
  26. package/project/.sdk/model/target/java.aontu +4 -4
  27. package/project/.sdk/model/target/kotlin.aontu +4 -4
  28. package/project/.sdk/model/target/lean.aontu +51 -0
  29. package/project/.sdk/model/target/scala.aontu +4 -4
  30. package/project/.sdk/src/cmp/c/EntityTypes_c.ts +3 -4
  31. package/project/.sdk/src/cmp/c/Entity_c.ts +3 -3
  32. package/project/.sdk/src/cmp/c/ReadmeExamplesTest_c.ts +24 -7
  33. package/project/.sdk/src/cmp/c/TestDirect_c.ts +3 -3
  34. package/project/.sdk/src/cmp/c/TestEntity_c.ts +1 -1
  35. package/project/.sdk/src/cmp/clojure/Entity_clojure.ts +1 -1
  36. package/project/.sdk/src/cmp/clojure/ReadmeExamplesTest_clojure.ts +19 -8
  37. package/project/.sdk/src/cmp/cpp/EntityTypes_cpp.ts +2 -2
  38. package/project/.sdk/src/cmp/cpp/Entity_cpp.ts +3 -3
  39. package/project/.sdk/src/cmp/cpp/MainEntity_cpp.ts +2 -2
  40. package/project/.sdk/src/cmp/cpp/ReadmeExamplesTest_cpp.ts +136 -0
  41. package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +3 -3
  42. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +4 -0
  43. package/project/.sdk/src/cmp/csharp/EntityTypes_csharp.ts +2 -3
  44. package/project/.sdk/src/cmp/csharp/Entity_csharp.ts +3 -3
  45. package/project/.sdk/src/cmp/csharp/MainEntity_csharp.ts +2 -2
  46. package/project/.sdk/src/cmp/csharp/Package_csharp.ts +1 -1
  47. package/project/.sdk/src/cmp/csharp/ReadmeExamplesTest_csharp.ts +13 -1
  48. package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +3 -3
  49. package/project/.sdk/src/cmp/dart/EntityTypes_dart.ts +2 -3
  50. package/project/.sdk/src/cmp/dart/Entity_dart.ts +3 -3
  51. package/project/.sdk/src/cmp/dart/MainEntity_dart.ts +2 -2
  52. package/project/.sdk/src/cmp/dart/Main_dart.ts +3 -3
  53. package/project/.sdk/src/cmp/dart/Package_dart.ts +1 -1
  54. package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +4 -4
  55. package/project/.sdk/src/cmp/elixir/EntityTypes_elixir.ts +2 -3
  56. package/project/.sdk/src/cmp/elixir/Entity_elixir.ts +1 -1
  57. package/project/.sdk/src/cmp/elixir/ReadmeExamplesTest_elixir.ts +21 -3
  58. package/project/.sdk/src/cmp/go/Config_go.ts +4 -1
  59. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +110 -18
  60. package/project/.sdk/src/cmp/go/Entity_go.ts +3 -3
  61. package/project/.sdk/src/cmp/go/Main_go.ts +7 -6
  62. package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
  63. package/project/.sdk/src/cmp/go/TestDirect_go.ts +3 -3
  64. package/project/.sdk/src/cmp/go/TestEntity_go.ts +1 -1
  65. package/project/.sdk/src/cmp/go/utility_go.ts +25 -0
  66. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +9 -1
  67. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +9 -1
  68. package/project/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +28 -18
  69. package/project/.sdk/src/cmp/java/EntityTypes_java.ts +2 -3
  70. package/project/.sdk/src/cmp/java/Entity_java.ts +3 -3
  71. package/project/.sdk/src/cmp/java/MainEntity_java.ts +2 -2
  72. package/project/.sdk/src/cmp/java/Package_java.ts +1 -1
  73. package/project/.sdk/src/cmp/java/ReadmeExamplesTest_java.ts +23 -1
  74. package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
  75. package/project/.sdk/src/cmp/js/EntityTypes_js.ts +2 -3
  76. package/project/.sdk/src/cmp/js/Entity_js.ts +3 -3
  77. package/project/.sdk/src/cmp/js/MainEntity_js.ts +2 -2
  78. package/project/.sdk/src/cmp/js/Main_js.ts +2 -2
  79. package/project/.sdk/src/cmp/js/TestDirect_js.ts +4 -4
  80. package/project/.sdk/src/cmp/kotlin/EntityTypes_kotlin.ts +2 -3
  81. package/project/.sdk/src/cmp/kotlin/Entity_kotlin.ts +3 -3
  82. package/project/.sdk/src/cmp/kotlin/MainEntity_kotlin.ts +2 -2
  83. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +1 -1
  84. package/project/.sdk/src/cmp/kotlin/ReadmeExamplesTest_kotlin.ts +27 -2
  85. package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
  86. package/project/.sdk/src/cmp/lean/Config_lean.ts +88 -0
  87. package/project/.sdk/src/cmp/lean/Entity_lean.ts +9 -0
  88. package/project/.sdk/src/cmp/lean/Gitignore_lean.ts +18 -0
  89. package/project/.sdk/src/cmp/lean/Main_lean.ts +120 -0
  90. package/project/.sdk/src/cmp/lean/Package_lean.ts +68 -0
  91. package/project/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +29 -0
  92. package/project/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +19 -0
  93. package/project/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +25 -0
  94. package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +38 -0
  95. package/project/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +25 -0
  96. package/project/.sdk/src/cmp/lean/ReadmeModel_lean.ts +24 -0
  97. package/project/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +22 -0
  98. package/project/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +50 -0
  99. package/project/.sdk/src/cmp/lean/ReadmeRef_lean.ts +16 -0
  100. package/project/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +16 -0
  101. package/project/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +23 -0
  102. package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +18 -0
  103. package/project/.sdk/src/cmp/lean/Test_lean.ts +207 -0
  104. package/project/.sdk/src/cmp/lean/utility_lean.ts +78 -0
  105. package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +2 -3
  106. package/project/.sdk/src/cmp/lua/Entity_lua.ts +3 -3
  107. package/project/.sdk/src/cmp/lua/Package_lua.ts +1 -1
  108. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
  109. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +1 -1
  110. package/project/.sdk/src/cmp/ocaml/ReadmeExamplesTest_ocaml.ts +29 -14
  111. package/project/.sdk/src/cmp/perl/Entity_perl.ts +3 -3
  112. package/project/.sdk/src/cmp/perl/MainEntity_perl.ts +2 -2
  113. package/project/.sdk/src/cmp/perl/Package_perl.ts +1 -1
  114. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
  115. package/project/.sdk/src/cmp/php/EntityTypes_php.ts +2 -3
  116. package/project/.sdk/src/cmp/php/Entity_php.ts +3 -3
  117. package/project/.sdk/src/cmp/php/MainEntity_php.ts +2 -2
  118. package/project/.sdk/src/cmp/php/Package_php.ts +1 -1
  119. package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
  120. package/project/.sdk/src/cmp/php/TestEntity_php.ts +1 -1
  121. package/project/.sdk/src/cmp/py/EntityTypes_py.ts +2 -3
  122. package/project/.sdk/src/cmp/py/Entity_py.ts +3 -3
  123. package/project/.sdk/src/cmp/py/MainEntity_py.ts +2 -2
  124. package/project/.sdk/src/cmp/py/Main_py.ts +2 -2
  125. package/project/.sdk/src/cmp/py/Package_py.ts +1 -1
  126. package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
  127. package/project/.sdk/src/cmp/py/TestEntity_py.ts +1 -1
  128. package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +15 -5
  129. package/project/.sdk/src/cmp/rb/Entity_rb.ts +3 -3
  130. package/project/.sdk/src/cmp/rb/MainEntity_rb.ts +2 -2
  131. package/project/.sdk/src/cmp/rb/Package_rb.ts +2 -2
  132. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
  133. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +1 -1
  134. package/project/.sdk/src/cmp/rust/EntityBase_rust.ts +2 -2
  135. package/project/.sdk/src/cmp/rust/EntityTypes_rust.ts +3 -4
  136. package/project/.sdk/src/cmp/rust/Entity_rust.ts +3 -3
  137. package/project/.sdk/src/cmp/rust/MainEntity_rust.ts +2 -2
  138. package/project/.sdk/src/cmp/rust/Package_rust.ts +1 -1
  139. package/project/.sdk/src/cmp/rust/ReadmeExamplesTest_rust.ts +22 -10
  140. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
  141. package/project/.sdk/src/cmp/scala/EntityTypes_scala.ts +2 -3
  142. package/project/.sdk/src/cmp/scala/Entity_scala.ts +3 -3
  143. package/project/.sdk/src/cmp/scala/MainEntity_scala.ts +2 -2
  144. package/project/.sdk/src/cmp/scala/ReadmeExamplesTest_scala.ts +22 -3
  145. package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +3 -3
  146. package/project/.sdk/src/cmp/scala/Test_scala.ts +1 -1
  147. package/project/.sdk/src/cmp/swift/EntityTypes_swift.ts +3 -4
  148. package/project/.sdk/src/cmp/swift/Entity_swift.ts +3 -3
  149. package/project/.sdk/src/cmp/swift/MainEntity_swift.ts +2 -2
  150. package/project/.sdk/src/cmp/swift/Package_swift.ts +1 -1
  151. package/project/.sdk/src/cmp/swift/ReadmeExamplesTest_swift.ts +18 -1
  152. package/project/.sdk/src/cmp/swift/TestDirect_swift.ts +1 -1
  153. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +2 -3
  154. package/project/.sdk/src/cmp/ts/Entity_ts.ts +3 -3
  155. package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +2 -2
  156. package/project/.sdk/src/cmp/ts/Main_ts.ts +2 -2
  157. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +4 -4
  158. package/project/.sdk/src/cmp/zig/Entity_zig.ts +3 -3
  159. package/project/.sdk/src/cmp/zig/MainEntity_zig.ts +2 -2
  160. package/project/.sdk/src/cmp/zig/Package_zig.ts +10 -2
  161. package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +8 -16
  162. package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +10 -28
  163. package/project/.sdk/tm/dart/test/primary_test.dart +7 -0
  164. package/project/.sdk/tm/go/feature/test_feature.go +33 -1
  165. package/project/.sdk/tm/go/test/primary_utility_test.go +41 -42
  166. package/project/.sdk/tm/go/test/runner_test.go +30 -1
  167. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +7 -24
  168. package/project/.sdk/tm/js/src/feature/test/TestFeature.js +18 -1
  169. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +8 -0
  170. package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +7 -20
  171. package/project/.sdk/tm/lean/LICENSE +21 -0
  172. package/project/.sdk/tm/lean/VERSION +1 -0
  173. package/project/.sdk/tm/lean/src/SdkFeature.lean +171 -0
  174. package/project/.sdk/tm/lean/src/SdkFeatures.lean +602 -0
  175. package/project/.sdk/tm/lean/src/SdkJson.lean +134 -0
  176. package/project/.sdk/tm/lean/src/SdkRuntime.lean +356 -0
  177. package/project/.sdk/tm/lean/src/SdkUtility.lean +617 -0
  178. package/project/.sdk/tm/lean/src/VoxgigStruct.lean +2880 -0
  179. package/project/.sdk/tm/lean/src/Vregex.lean +412 -0
  180. package/project/.sdk/tm/lean/src/feature/README.md +5 -0
  181. package/project/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
  182. package/project/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
  183. package/project/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
  184. package/project/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
  185. package/project/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
  186. package/project/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
  187. package/project/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
  188. package/project/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
  189. package/project/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
  190. package/project/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
  191. package/project/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
  192. package/project/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
  193. package/project/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
  194. package/project/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
  195. package/project/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
  196. package/project/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
  197. package/project/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
  198. package/project/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
  199. package/project/.sdk/tm/lean/test/StructCorpus.lean +697 -0
  200. package/project/.sdk/tm/lean/test/TFeature.lean +268 -0
  201. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +349 -0
  202. package/project/.sdk/tm/lua/test/primary_utility_test.lua +10 -8
  203. package/project/.sdk/tm/perl/t/primary_utility.t +8 -17
  204. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +9 -7
  205. package/project/.sdk/tm/py/feature/test_feature.py +28 -1
  206. package/project/.sdk/tm/py/test/test_primary_utility.py +13 -18
  207. package/project/.sdk/tm/rb/feature/test_feature.rb +24 -1
  208. package/project/.sdk/tm/rb/test/primary_utility_test.rb +7 -8
  209. package/project/.sdk/tm/rust/tests/common/mod.rs +37 -1
  210. package/project/.sdk/tm/rust/tests/primary_utility_test.rs +12 -26
  211. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +7 -8
  212. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +18 -1
  213. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +65 -21
  214. package/src/cmp/Entity.ts +5 -1
  215. package/src/cmp/Feature.ts +2 -1
  216. package/src/helpers/canonType.ts +8 -3
  217. package/src/helpers/collectDeps.ts +39 -12
  218. package/src/helpers/naming.ts +59 -0
  219. package/src/helpers/opShape.ts +99 -12
  220. package/src/sdkgen.ts +7 -3
@@ -1136,16 +1136,18 @@ class PrimaryUtilityTest extends TestCase
1136
1136
 
1137
1137
  public function test_prepare_path_basic(): void
1138
1138
  {
1139
+ // Was hand-written cases that had drifted out of the shared corpus
1140
+ // (the preparePath fixture shipped as an empty `set: []`).
1141
+ $spec = self::load_test_spec();
1142
+ $primary = self::get_spec($spec, 'primary');
1139
1143
  $client = ProjectNameSDK::test(null, null);
1140
1144
  $utility = $client->get_utility();
1141
- $ctx = self::make_test_full_ctx($client, $utility);
1142
- $ctx->point = [
1143
- 'parts' => ['api', 'planet', '{id}'],
1144
- 'args' => ['params' => []],
1145
- ];
1146
1145
 
1147
- $path = ($utility->prepare_path)($ctx);
1148
- $this->assertEquals('api/planet/{id}', $path);
1146
+ $this->runset(self::get_spec($primary, 'preparePath', 'basic'), function (array $entry) use ($client, $utility) {
1147
+ $ctxmap = $entry['ctx'] ?? [];
1148
+ $ctx = self::make_ctx_from_map($ctxmap, $client, $utility);
1149
+ return [($utility->prepare_path)($ctx), null];
1150
+ });
1149
1151
  }
1150
1152
 
1151
1153
 
@@ -1,6 +1,7 @@
1
1
  # ProjectName SDK test feature
2
2
 
3
3
  from __future__ import annotations
4
+ import re
4
5
  import random
5
6
  import time
6
7
 
@@ -8,6 +9,11 @@ from utility.voxgig_struct import voxgig_struct as vs
8
9
  from feature.base_feature import ProjectNameBaseFeature
9
10
 
10
11
 
12
+ # The `body.<key>` form of an op's response transform: the mock wraps its
13
+ # payload in <key> so the transform can unwrap it again.
14
+ ENVELOPE_RES_RE = re.compile(r"^`body\.([^`.]+)`$")
15
+
16
+
11
17
  class ProjectNameTestFeature(ProjectNameBaseFeature):
12
18
  def __init__(self):
13
19
  super().__init__()
@@ -36,11 +42,32 @@ class ProjectNameTestFeature(ProjectNameBaseFeature):
36
42
  test_self = self
37
43
 
38
44
  def test_fetcher(fctx, _fullurl, _fetchdef):
45
+ # Shape the mock payload the way the real API would, so the op's
46
+ # response transform recovers the entity from it. A point carrying
47
+ # transform.res of `body.item` describes an API that answers
48
+ # {"item": {...}}; handing back the bare entity means the transform
49
+ # unwraps a property that is not there and the caller gets None.
50
+ # The mock has to agree with the model, or it only ever simulates
51
+ # APIs whose responses happen to be unwrapped. Mirrors the ts mock.
52
+ def envelope(data):
53
+ point = getattr(fctx, "point", None)
54
+ if data is None or not isinstance(point, dict):
55
+ return data
56
+ transform = point.get("transform")
57
+ if not isinstance(transform, dict):
58
+ return data
59
+ restf = transform.get("res")
60
+ if not isinstance(restf, str):
61
+ return data
62
+ m = ENVELOPE_RES_RE.match(restf)
63
+ return data if m is None else {m.group(1): data}
64
+
39
65
  def respond(status, data, extra=None):
66
+ payload = envelope(data)
40
67
  out = {
41
68
  "status": status,
42
69
  "statusText": "OK",
43
- "json": lambda: data,
70
+ "json": lambda: payload,
44
71
  "body": "not-used",
45
72
  }
46
73
  if isinstance(extra, dict):
@@ -945,28 +945,23 @@ class TestPrimaryUtility:
945
945
  _runset(_get_spec(primary, "prepareParams", "basic"), subject)
946
946
 
947
947
  def test_prepare_path_basic(self):
948
+ # Was two hand-written cases that had drifted out of the shared corpus
949
+ # (the preparePath fixture shipped as an empty `set: []`). Now driven
950
+ # by the corpus like every other section, so all ports assert the same
951
+ # separator / blank-segment behaviour.
952
+ spec = _load_test_spec()
953
+ primary = _get_spec(spec, "primary")
948
954
  client = ProjectNameSDK.test(None, None)
949
955
  utility = client._utility
950
- ctx = _make_test_full_ctx(client, utility)
951
- ctx.point = {
952
- "parts": ["api", "planet", "{id}"],
953
- "args": {"params": []},
954
- }
955
-
956
- path = utility.prepare_path(ctx)
957
- assert path == "api/planet/{id}"
958
956
 
959
- def test_prepare_path_single(self):
960
- client = ProjectNameSDK.test(None, None)
961
- utility = client._utility
962
- ctx = _make_test_full_ctx(client, utility)
963
- ctx.point = {
964
- "parts": ["items"],
965
- "args": {"params": []},
966
- }
957
+ def subject(entry):
958
+ ctxmap = entry.get("ctx")
959
+ if not isinstance(ctxmap, dict):
960
+ ctxmap = {}
961
+ ctx = _make_ctx_from_map(ctxmap, client, utility)
962
+ return utility.prepare_path(ctx), None
967
963
 
968
- path = utility.prepare_path(ctx)
969
- assert path == "items"
964
+ _runset(_get_spec(primary, "preparePath", "basic"), subject)
970
965
 
971
966
  def test_prepare_query_basic(self):
972
967
  spec = _load_test_spec()
@@ -4,6 +4,10 @@ require_relative '../utility/struct/voxgig_struct'
4
4
  require_relative 'base_feature'
5
5
 
6
6
  class ProjectNameTestFeature < ProjectNameBaseFeature
7
+ # The `body.<key>` form of an op's response transform: the mock wraps its
8
+ # payload in <key> so the transform can unwrap it again.
9
+ ENVELOPE_RES_RE = /\A`body\.([^`.]+)`\z/
10
+
7
11
  def initialize
8
12
  super
9
13
  @version = "0.0.1"
@@ -33,11 +37,30 @@ class ProjectNameTestFeature < ProjectNameBaseFeature
33
37
  test_self = self
34
38
 
35
39
  test_fetcher = ->(fctx, _fullurl, _fetchdef) {
40
+ # Shape the mock payload the way the real API would, so the op's
41
+ # response transform recovers the entity from it. A point carrying
42
+ # transform.res of `body.item` describes an API that answers
43
+ # {"item" => {...}}; handing back the bare entity means the transform
44
+ # unwraps a property that is not there and the caller gets nil. The mock
45
+ # has to agree with the model, or it only ever simulates APIs whose
46
+ # responses happen to be unwrapped. Mirrors the ts mock.
47
+ envelope = ->(data) {
48
+ point = fctx.point
49
+ next data if data.nil? || !point.is_a?(Hash)
50
+ transform = point["transform"]
51
+ next data unless transform.is_a?(Hash)
52
+ restf = transform["res"]
53
+ next data unless restf.is_a?(String)
54
+ m = ENVELOPE_RES_RE.match(restf)
55
+ m.nil? ? data : { m[1] => data }
56
+ }
57
+
36
58
  respond = ->(status, data, extra) {
59
+ payload = envelope.call(data)
37
60
  out = {
38
61
  "status" => status,
39
62
  "statusText" => "OK",
40
- "json" => -> { data },
63
+ "json" => -> { payload },
41
64
  "body" => "not-used",
42
65
  }
43
66
  extra&.each { |k, v| out[k] = v }
@@ -610,14 +610,13 @@ class PrimaryUtilityTest < Minitest::Test
610
610
  # === preparePath ===
611
611
 
612
612
  def test_prepare_path_basic
613
- ctx = make_test_full_ctx(@client, @utility)
614
- ctx.point = {
615
- "parts" => ["api", "planet", "{id}"],
616
- "args" => { "params" => [] },
617
- }
618
-
619
- path = @utility.prepare_path.call(ctx)
620
- assert_equal "api/planet/{id}", path
613
+ # Was hand-written cases that had drifted out of the shared corpus
614
+ # (the preparePath fixture shipped as an empty `set: []`).
615
+ runset(get_spec(@primary, "preparePath", "basic")) do |entry|
616
+ ctxmap = entry["ctx"] || {}
617
+ ctx = make_ctx_from_map(ctxmap, @client, @utility)
618
+ @utility.prepare_path.call(ctx)
619
+ end
621
620
  end
622
621
 
623
622
  def test_prepare_path_single
@@ -291,15 +291,51 @@ pub fn match_deep(check: &Value, base: &Value) -> Option<String> {
291
291
 
292
292
  // ---- runset (mirrors go runner_test.go runset) -----------------------------------
293
293
 
294
+ // Sections deliberately left empty in the shared corpus
295
+ // (.sdk/test/primary/<name>.aontu carries a PENDING header). Everything else
296
+ // MUST contribute cases.
297
+ pub const PENDING_SECTIONS: &[&str] = &[
298
+ "fetcher", "makeFetchDef", "makePoint", "makeResult", "featureAdd",
299
+ "featureHook", "featureInit",
300
+ ];
301
+
294
302
  pub fn runset(
295
303
  testspec: &Value,
296
304
  subject: &mut dyn FnMut(&Value) -> Result<Value, ProjectNameError>,
305
+ ) {
306
+ runset_named("", testspec, subject)
307
+ }
308
+
309
+ /// Drive one section of the shared test corpus.
310
+ ///
311
+ /// This used to `return` silently when "set" was missing or not a list, so a
312
+ /// renamed section, a fixture that failed to compile, or an empty set reported
313
+ /// PASS while running zero assertions — the whole point of a shared oracle lost
314
+ /// without a single red test. Both conditions now panic, except for the
315
+ /// sections explicitly marked PENDING in the corpus.
316
+ pub fn runset_named(
317
+ name: &str,
318
+ testspec: &Value,
319
+ subject: &mut dyn FnMut(&Value) -> Result<Value, ProjectNameError>,
297
320
  ) {
298
321
  let set = match getp(testspec, "set") {
299
322
  Value::List(l) => Value::List(l),
300
- _ => return,
323
+ _ => panic!(
324
+ "test corpus section {:?} has no `set` list — zero cases would run",
325
+ name
326
+ ),
301
327
  };
302
328
 
329
+ if let Value::List(l) = &set {
330
+ if l.borrow().is_empty() && !PENDING_SECTIONS.contains(&name) {
331
+ panic!(
332
+ "test corpus section {:?} is EMPTY — zero cases would run; add \
333
+ cases, or mark the fixture PENDING in .sdk/test/primary/",
334
+ name
335
+ );
336
+ }
337
+ }
338
+
303
339
  let entries: Vec<Value> = match &set {
304
340
  Value::List(l) => l.borrow().clone(),
305
341
  _ => Vec::new(),
@@ -810,35 +810,21 @@ fn primary_prepare_params_basic() {
810
810
  );
811
811
  }
812
812
 
813
+ // Was two hand-written cases that had drifted out of the shared corpus (the
814
+ // preparePath fixture shipped as an empty `set: []`). Now driven by the
815
+ // corpus like every other section, so all ports assert the same separator /
816
+ // blank-segment behaviour.
813
817
  #[test]
814
818
  fn primary_prepare_path_basic() {
815
819
  let (client, utility) = base_client();
816
- let ctx = make_test_full_ctx(&client, &utility);
817
- *ctx.point.borrow_mut() = jo(vec![
818
- (
819
- "parts",
820
- ja(vec![
821
- Value::str("api"),
822
- Value::str("planet"),
823
- Value::str("{id}"),
824
- ]),
825
- ),
826
- ("args", jo(vec![("params", Value::empty_list())])),
827
- ]);
828
-
829
- assert_eq!(utility.prepare_path(&ctx), "api/planet/{id}");
830
- }
831
-
832
- #[test]
833
- fn primary_prepare_path_single() {
834
- let (client, utility) = base_client();
835
- let ctx = make_test_full_ctx(&client, &utility);
836
- *ctx.point.borrow_mut() = jo(vec![
837
- ("parts", ja(vec![Value::str("items")])),
838
- ("args", jo(vec![("params", Value::empty_list())])),
839
- ]);
840
-
841
- assert_eq!(utility.prepare_path(&ctx), "items");
820
+ let primary = primary();
821
+ runset(
822
+ &get_spec(&primary, &["preparePath", "basic"]),
823
+ &mut |entry| {
824
+ let ctx = make_ctx_from_map(&getp(entry, "ctx"), &client, &utility);
825
+ Ok(Value::str(utility.prepare_path(&ctx)))
826
+ },
827
+ );
842
828
  }
843
829
 
844
830
  #[test]
@@ -629,14 +629,13 @@ final class PrimaryUtilityTest: XCTestCase {
629
629
  }
630
630
 
631
631
  func testPreparePathBasic() {
632
- let ctx = makeTestFullCtx(client, utility)
633
- ctx.point = vm(
634
- ("parts", .list([.string("api"), .string("planet"), .string("{id}")])),
635
- ("args", .map(vm(("params", .list([])))))
636
- )
637
-
638
- let path = utility.preparePath(ctx)
639
- XCTAssertEqual(path, "api/planet/{id}")
632
+ // Was hand-written cases that had drifted out of the shared corpus
633
+ // (the preparePath fixture shipped as an empty `set: []`).
634
+ SdkRunner.runSet(SdkRunner.spec(primary, "preparePath", "basic")) { entry in
635
+ let ctxmap = entry.entries["ctx"]?.asMap
636
+ let ctx = SdkRunner.makeCtxFromMap(ctxmap, self.client, self.utility)
637
+ return .string(self.utility.preparePath(ctx))
638
+ }
640
639
  }
641
640
 
642
641
  func testPreparePathSingle() {
@@ -52,12 +52,29 @@ class TestFeature extends BaseFeature {
52
52
  const delprop = struct.delprop
53
53
  const getdef = struct.getdef
54
54
 
55
+ // Shape the mock payload the way the real API would, so the op's
56
+ // response transform recovers the entity from it. A point carrying
57
+ // `transform.res: \`body.item\`` describes an API that answers
58
+ // `{item: {...}}`; handing back the bare entity means the transform
59
+ // unwraps a property that is not there and the caller gets undefined.
60
+ // The mock has to agree with the model, or it only ever simulates APIs
61
+ // whose responses happen to be unwrapped.
62
+ function envelope(data: any) {
63
+ const restf = getprop(getprop(ctx.point, 'transform', {}), 'res')
64
+ if (null == data || 'string' !== typeof restf) {
65
+ return data
66
+ }
67
+ const m = restf.match(/^`body\.([^`.]+)`$/)
68
+ return null == m ? data : { [m[1]]: data }
69
+ }
70
+
55
71
  function respond(status: number, data?: any, res?: any) {
72
+ const payload = envelope(data)
56
73
  const out = merge([
57
74
  {
58
75
  status,
59
76
  statusText: 'OK',
60
- json: async () => data,
77
+ json: async () => payload,
61
78
  body: 'not-used',
62
79
  },
63
80
  getdef(res, {})
@@ -31,6 +31,38 @@ describe('PrimaryUtility', async () => {
31
31
  }
32
32
 
33
33
 
34
+ // Sections deliberately left empty in the shared corpus
35
+ // (.sdk/test/primary/<name>.aontu carries a PENDING header). Everything
36
+ // else MUST contribute cases.
37
+ const PENDING = new Set([
38
+ 'fetcher', 'makeFetchDef', 'makePoint', 'makeResult',
39
+ 'featureAdd', 'featureHook', 'featureInit',
40
+ ])
41
+
42
+ // Run one corpus section, failing loudly when it would run ZERO cases.
43
+ // A renamed section or a fixture that compiled to an empty `set` used to
44
+ // pass silently, which defeats the point of a shared oracle. (The guard
45
+ // lives here rather than in runner.ts, which is vendored verbatim from
46
+ // @voxgig/struct and must stay byte-identical to upstream.)
47
+ //
48
+ // EVERY corpus-backed test goes through here — a guard that only some
49
+ // sections opt into leaves the rest able to run zero assertions, which is
50
+ // the exact hole it was added to close.
51
+ async function runsection(name: string, subject: Function) {
52
+ const section = spec[name]
53
+ ok(null != section,
54
+ `test corpus section '${name}' missing — check the name against .sdk/test/primary/`)
55
+ ok(null != section.basic && Array.isArray(section.basic.set),
56
+ `test corpus section '${name}' has no basic.set list`)
57
+ if (0 === section.basic.set.length && !PENDING.has(name)) {
58
+ throw new Error(
59
+ `test corpus section '${name}' is EMPTY — zero cases would run; ` +
60
+ `add cases, or mark the fixture PENDING in .sdk/test/primary/`)
61
+ }
62
+ return runset(section.basic, subject)
63
+ }
64
+
65
+
34
66
  before(async () => {
35
67
  const runner = await makeRunner(TEST_JSON_FILE, await SDK.test())
36
68
  const run = await runner('primary')
@@ -61,24 +93,24 @@ describe('PrimaryUtility', async () => {
61
93
 
62
94
 
63
95
  test('context-basic', async () => {
64
- await runset(spec.makeContext.basic, utility.makeContext)
96
+ await runsection('makeContext', utility.makeContext)
65
97
  })
66
98
 
67
99
 
68
100
  test('method-basic', async () => {
69
- await runset(spec.prepareMethod.basic, utility.prepareMethod)
101
+ await runsection('prepareMethod', utility.prepareMethod)
70
102
  })
71
103
 
72
104
 
73
105
  test('headers-basic', async () => {
74
- await runset(spec.prepareHeaders.basic, utility.prepareHeaders)
106
+ await runsection('prepareHeaders', utility.prepareHeaders)
75
107
  })
76
108
 
77
109
 
78
110
  test('auth-basic', async () => {
79
111
  const sdkopts = spec.prepareAuth?.DEF?.setup?.a || {}
80
112
  const authClient = SDK.test({}, sdkopts)
81
- await runset(spec.prepareAuth.basic, (ctx: any) => {
113
+ await runsection('prepareAuth', (ctx: any) => {
82
114
  ctx.client = authClient
83
115
  fixctx(ctx)
84
116
  return utility.prepareAuth(ctx)
@@ -87,17 +119,17 @@ describe('PrimaryUtility', async () => {
87
119
 
88
120
 
89
121
  test('params-basic', async () => {
90
- await runset(spec.prepareParams.basic, utility.prepareParams)
122
+ await runsection('prepareParams', utility.prepareParams)
91
123
  })
92
124
 
93
125
 
94
126
  test('query-basic', async () => {
95
- await runset(spec.prepareQuery.basic, utility.prepareQuery)
127
+ await runsection('prepareQuery', utility.prepareQuery)
96
128
  })
97
129
 
98
130
 
99
131
  test('body-basic', async () => {
100
- await runset(spec.prepareBody.basic, (ctx: any) => {
132
+ await runsection('prepareBody', (ctx: any) => {
101
133
  fixctx(ctx)
102
134
  return utility.prepareBody(ctx)
103
135
  })
@@ -105,17 +137,17 @@ describe('PrimaryUtility', async () => {
105
137
 
106
138
 
107
139
  test('findparam-basic', async () => {
108
- await runset(spec.param.basic, utility.param)
140
+ await runsection('param', utility.param)
109
141
  })
110
142
 
111
143
 
112
144
  test('fullurl-basic', async () => {
113
- await runset(spec.makeUrl.basic, utility.makeUrl)
145
+ await runsection('makeUrl', utility.makeUrl)
114
146
  })
115
147
 
116
148
 
117
149
  test('operator-basic', async () => {
118
- await runset(spec.operator.basic, (opmap: any) => ({
150
+ await runsection('operator', (opmap: any) => ({
119
151
  entity: opmap.entity || '_',
120
152
  name: opmap.name || '_',
121
153
  input: opmap.input || '_',
@@ -125,7 +157,7 @@ describe('PrimaryUtility', async () => {
125
157
 
126
158
 
127
159
  test('options-basic', async () => {
128
- await runset(spec.makeOptions.basic, (vin: any) => {
160
+ await runsection('makeOptions', (vin: any) => {
129
161
  const ctx = utility.makeContext({ options: vin.options, config: vin.config })
130
162
  ctx.client = client
131
163
  ctx.utility = utility
@@ -137,7 +169,7 @@ describe('PrimaryUtility', async () => {
137
169
  test('spec-basic', async () => {
138
170
  const sdkopts = spec.makeSpec?.DEF?.setup?.a || {}
139
171
  const specClient = SDK.test({}, sdkopts)
140
- await runset(spec.makeSpec.basic, (ctx: any) => {
172
+ await runsection('makeSpec', (ctx: any) => {
141
173
  ctx.client = specClient
142
174
  ctx.options = specClient.options()
143
175
  return utility.makeSpec(ctx)
@@ -146,17 +178,17 @@ describe('PrimaryUtility', async () => {
146
178
 
147
179
 
148
180
  test('reqform-basic', async () => {
149
- await runset(spec.transformRequest.basic, utility.transformRequest)
181
+ await runsection('transformRequest', utility.transformRequest)
150
182
  })
151
183
 
152
184
 
153
185
  test('resform-basic', async () => {
154
- await runset(spec.transformResponse.basic, utility.transformResponse)
186
+ await runsection('transformResponse', utility.transformResponse)
155
187
  })
156
188
 
157
189
 
158
190
  test('resbasic-basic', async () => {
159
- await runset(spec.resultBasic.basic, (ctx: any) => {
191
+ await runsection('resultBasic', (ctx: any) => {
160
192
  fixctx(ctx)
161
193
  return utility.resultBasic(ctx)
162
194
  })
@@ -164,7 +196,7 @@ describe('PrimaryUtility', async () => {
164
196
 
165
197
 
166
198
  test('resheaders-basic', async () => {
167
- await runset(spec.resultHeaders.basic, (ctx: any) => {
199
+ await runsection('resultHeaders', (ctx: any) => {
168
200
  // Convert plain headers map to forEach-based (browser Response API)
169
201
  if (ctx.response?.headers && !ctx.response.headers.forEach) {
170
202
  const h = ctx.response.headers
@@ -178,7 +210,7 @@ describe('PrimaryUtility', async () => {
178
210
 
179
211
 
180
212
  test('resbody-basic', async () => {
181
- await runset(spec.resultBody.basic, async (ctx: any) => {
213
+ await runsection('resultBody', async (ctx: any) => {
182
214
  if (ctx.response && !ctx.response.json) {
183
215
  const body = ctx.response.body
184
216
  ctx.response.json = async () => body
@@ -200,7 +232,7 @@ describe('PrimaryUtility', async () => {
200
232
  system: { fetch: mockFetch }
201
233
  })
202
234
  const reqUtility = reqClient.utility()
203
- await runset(spec.makeRequest.basic, async (ctx: any) => {
235
+ await runsection('makeRequest', async (ctx: any) => {
204
236
  ctx.client = reqClient
205
237
  ctx.utility = reqUtility
206
238
  ctx.options = reqClient.options()
@@ -210,7 +242,7 @@ describe('PrimaryUtility', async () => {
210
242
 
211
243
 
212
244
  test('response-basic', async () => {
213
- await runset(spec.makeResponse.basic, async (ctx: any) => {
245
+ await runsection('makeResponse', async (ctx: any) => {
214
246
  fixctx(ctx)
215
247
  // Add json() and forEach to response for proper TS handling
216
248
  if (ctx.response && !ctx.response.json) {
@@ -229,7 +261,7 @@ describe('PrimaryUtility', async () => {
229
261
 
230
262
 
231
263
  test('done-basic', async () => {
232
- await runset(spec.done.basic, (ctx: any) => {
264
+ await runsection('done', (ctx: any) => {
233
265
  fixctx(ctx)
234
266
  return utility.done(ctx)
235
267
  })
@@ -237,7 +269,7 @@ describe('PrimaryUtility', async () => {
237
269
 
238
270
 
239
271
  test('error-basic', async () => {
240
- await runset(spec.makeError.basic, (...args: any[]) => {
272
+ await runsection('makeError', (...args: any[]) => {
241
273
  const ctx = args[0]
242
274
  fixctx(ctx)
243
275
  return utility.makeError(...args)
@@ -424,6 +456,18 @@ describe('PrimaryUtility', async () => {
424
456
  })
425
457
 
426
458
 
459
+ test('path-basic', async () => {
460
+ // preparePath shipped as an empty `set: []` — every port "passed" it while
461
+ // running zero cases. Now corpus-driven like every other section.
462
+ await runsection('preparePath', (ctx: any) => utility.preparePath(ctx))
463
+ })
464
+
465
+
466
+ test('clean-corpus', async () => {
467
+ await runsection('clean', (...args: any[]) => utility.clean(args[0], args[1]))
468
+ })
469
+
470
+
427
471
  test('clean', () => {
428
472
  const ctx = makeFullCtx()
429
473
  const val = { key: 'secret123', name: 'test' }
package/src/cmp/Entity.ts CHANGED
@@ -21,8 +21,12 @@ const Entity = cmp(function Entity(props: any) {
21
21
  const Entity_sdk = requirePath(ctx$, `./cmp/${target.name}/Entity_${target.name}`)
22
22
  Entity_sdk['Entity']({ target, entity, entitySDK })
23
23
 
24
+ // Log identifiers, not the model subtrees. `target` and `entity` are large
25
+ // aontu nodes and this fires once per entity per target (thousands of times
26
+ // for a big API x 22 targets), so passing them serialised the whole model
27
+ // fragment each time at default log level.
24
28
  log.info({
25
- point: 'generate-entity', target, entity,
29
+ point: 'generate-entity', target: target.name, entity: entity.name,
26
30
  note: 'target:' + target.name + ', ' + 'entity: ' + entity.name
27
31
  })
28
32
  })
@@ -19,7 +19,8 @@ const Feature = cmp(function Feature(props: any) {
19
19
  }
20
20
 
21
21
  log.info({
22
- point: 'generate-feature', target, feature,
22
+ // Identifiers only — see the note in Entity.ts.
23
+ point: 'generate-feature', target: target.name, feature: feature.name,
23
24
  note: 'target:' + target.name + ', ' + 'feature: ' + feature.name
24
25
  })
25
26
 
@@ -14,9 +14,14 @@
14
14
  // the SINGLE mapping per language: components must not keep local copies.
15
15
  //
16
16
  // Kept as a small mirror here (rather than importing VALID_CANON at runtime)
17
- // because apidef is a peer dependency and the table is the INVERSE direction;
18
- // `ts/test/canontype.test.ts` asserts this table covers apidef's exported
19
- // sentinel vocabulary whenever apidef is installed, so drift fails the suite.
17
+ // because apidef is a peer dependency and the table is the INVERSE direction.
18
+ //
19
+ // `ts/test/canonsync.test.ts` guards it two ways: the vocabulary and every
20
+ // language column are pinned LOCALLY (that check always runs), and the table
21
+ // is cross-checked against apidef's exported VALID_CANON/CANON_ONE when the
22
+ // installed apidef exports them. Note that the currently published apidef
23
+ // (6.3.1) does NOT export them, so the cross-check skips — do not rely on it
24
+ // alone; add a new sentinel to the local list in the same change.
20
25
  //
21
26
  // KNOWN GAPS (papered over sanely, documented for the port):
22
27
  // - Unknown / missing sentinel -> the language's "any" (never throws).