@voxgig/sdkgen-langpack 0.0.1

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 (300) hide show
  1. package/.sdk/model/target/dart.aon +63 -0
  2. package/.sdk/model/target/haskell.aon +72 -0
  3. package/.sdk/model/target/lean.aon +91 -0
  4. package/.sdk/src/cmp/dart/Config_dart.ts +248 -0
  5. package/.sdk/src/cmp/dart/EntityBase_dart.ts +34 -0
  6. package/.sdk/src/cmp/dart/EntityOperation_dart.ts +43 -0
  7. package/.sdk/src/cmp/dart/EntityTypes_dart.ts +207 -0
  8. package/.sdk/src/cmp/dart/Entity_dart.ts +87 -0
  9. package/.sdk/src/cmp/dart/Gitignore_dart.ts +34 -0
  10. package/.sdk/src/cmp/dart/MainEntity_dart.ts +33 -0
  11. package/.sdk/src/cmp/dart/Main_dart.ts +178 -0
  12. package/.sdk/src/cmp/dart/Package_dart.ts +82 -0
  13. package/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +177 -0
  14. package/.sdk/src/cmp/dart/ReadmeExamplesTest_dart.ts +238 -0
  15. package/.sdk/src/cmp/dart/ReadmeExplanation_dart.ts +53 -0
  16. package/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +152 -0
  17. package/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +59 -0
  18. package/.sdk/src/cmp/dart/ReadmeIntro_dart.ts +65 -0
  19. package/.sdk/src/cmp/dart/ReadmeModel_dart.ts +151 -0
  20. package/.sdk/src/cmp/dart/ReadmeOptions_dart.ts +63 -0
  21. package/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +225 -0
  22. package/.sdk/src/cmp/dart/ReadmeRef_dart.ts +397 -0
  23. package/.sdk/src/cmp/dart/ReadmeTopHowto_dart.ts +24 -0
  24. package/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +106 -0
  25. package/.sdk/src/cmp/dart/ReadmeTopTest_dart.ts +78 -0
  26. package/.sdk/src/cmp/dart/SdkError_dart.ts +42 -0
  27. package/.sdk/src/cmp/dart/TestDirect_dart.ts +516 -0
  28. package/.sdk/src/cmp/dart/TestEntity_dart.ts +628 -0
  29. package/.sdk/src/cmp/dart/Test_dart.ts +138 -0
  30. package/.sdk/src/cmp/dart/fragment/Config.data.fragment.dart +98 -0
  31. package/.sdk/src/cmp/dart/fragment/Config.fragment.dart +70 -0
  32. package/.sdk/src/cmp/dart/fragment/Direct.test.fragment.dart +25 -0
  33. package/.sdk/src/cmp/dart/fragment/Entity.fragment.dart +29 -0
  34. package/.sdk/src/cmp/dart/fragment/Entity.test.fragment.dart +28 -0
  35. package/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +302 -0
  36. package/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +98 -0
  37. package/.sdk/src/cmp/dart/fragment/EntityListOp.fragment.dart +90 -0
  38. package/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +102 -0
  39. package/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +108 -0
  40. package/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +102 -0
  41. package/.sdk/src/cmp/dart/fragment/Main.fragment.dart +339 -0
  42. package/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +26 -0
  43. package/.sdk/src/cmp/dart/tsconfig.json +15 -0
  44. package/.sdk/src/cmp/dart/utility_dart.ts +155 -0
  45. package/.sdk/src/cmp/haskell/Config_haskell.ts +98 -0
  46. package/.sdk/src/cmp/haskell/Entity_haskell.ts +13 -0
  47. package/.sdk/src/cmp/haskell/Gitignore_haskell.ts +27 -0
  48. package/.sdk/src/cmp/haskell/Main_haskell.ts +123 -0
  49. package/.sdk/src/cmp/haskell/Package_haskell.ts +60 -0
  50. package/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +186 -0
  51. package/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +135 -0
  52. package/.sdk/src/cmp/haskell/ReadmeExplanation_haskell.ts +48 -0
  53. package/.sdk/src/cmp/haskell/ReadmeHowto_haskell.ts +168 -0
  54. package/.sdk/src/cmp/haskell/ReadmeInstall_haskell.ts +51 -0
  55. package/.sdk/src/cmp/haskell/ReadmeIntro_haskell.ts +67 -0
  56. package/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +162 -0
  57. package/.sdk/src/cmp/haskell/ReadmeOptions_haskell.ts +74 -0
  58. package/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +241 -0
  59. package/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +408 -0
  60. package/.sdk/src/cmp/haskell/ReadmeTopHowto_haskell.ts +31 -0
  61. package/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +104 -0
  62. package/.sdk/src/cmp/haskell/ReadmeTopTest_haskell.ts +80 -0
  63. package/.sdk/src/cmp/haskell/Test_haskell.ts +297 -0
  64. package/.sdk/src/cmp/haskell/tsconfig.json +15 -0
  65. package/.sdk/src/cmp/haskell/utility_haskell.ts +166 -0
  66. package/.sdk/src/cmp/lean/Config_lean.ts +93 -0
  67. package/.sdk/src/cmp/lean/Entity_lean.ts +9 -0
  68. package/.sdk/src/cmp/lean/Gitignore_lean.ts +18 -0
  69. package/.sdk/src/cmp/lean/Main_lean.ts +120 -0
  70. package/.sdk/src/cmp/lean/Package_lean.ts +93 -0
  71. package/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +29 -0
  72. package/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +19 -0
  73. package/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +25 -0
  74. package/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +39 -0
  75. package/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +25 -0
  76. package/.sdk/src/cmp/lean/ReadmeModel_lean.ts +24 -0
  77. package/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +22 -0
  78. package/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +50 -0
  79. package/.sdk/src/cmp/lean/ReadmeRef_lean.ts +40 -0
  80. package/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +16 -0
  81. package/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +23 -0
  82. package/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +19 -0
  83. package/.sdk/src/cmp/lean/Test_lean.ts +261 -0
  84. package/.sdk/src/cmp/lean/utility_lean.ts +129 -0
  85. package/.sdk/tm/dart/LICENSE +22 -0
  86. package/.sdk/tm/dart/Makefile +50 -0
  87. package/.sdk/tm/dart/lib/Context.dart +150 -0
  88. package/.sdk/tm/dart/lib/Control.dart +15 -0
  89. package/.sdk/tm/dart/lib/Operation.dart +31 -0
  90. package/.sdk/tm/dart/lib/Point.dart +51 -0
  91. package/.sdk/tm/dart/lib/Response.dart +32 -0
  92. package/.sdk/tm/dart/lib/Result.dart +39 -0
  93. package/.sdk/tm/dart/lib/Spec.dart +49 -0
  94. package/.sdk/tm/dart/lib/feature/audit/AuditFeature.dart +103 -0
  95. package/.sdk/tm/dart/lib/feature/base/BaseFeature.dart +76 -0
  96. package/.sdk/tm/dart/lib/feature/cache/CacheFeature.dart +152 -0
  97. package/.sdk/tm/dart/lib/feature/clienttrack/ClienttrackFeature.dart +104 -0
  98. package/.sdk/tm/dart/lib/feature/cost/CostFeature.dart +446 -0
  99. package/.sdk/tm/dart/lib/feature/debug/DebugFeature.dart +153 -0
  100. package/.sdk/tm/dart/lib/feature/idempotency/IdempotencyFeature.dart +92 -0
  101. package/.sdk/tm/dart/lib/feature/log/LogFeature.dart +85 -0
  102. package/.sdk/tm/dart/lib/feature/metrics/MetricsFeature.dart +103 -0
  103. package/.sdk/tm/dart/lib/feature/netsim/NetsimFeature.dart +186 -0
  104. package/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +240 -0
  105. package/.sdk/tm/dart/lib/feature/proxy/ProxyFeature.dart +118 -0
  106. package/.sdk/tm/dart/lib/feature/ratelimit/RatelimitFeature.dart +103 -0
  107. package/.sdk/tm/dart/lib/feature/rbac/RbacFeature.dart +121 -0
  108. package/.sdk/tm/dart/lib/feature/retry/RetryFeature.dart +155 -0
  109. package/.sdk/tm/dart/lib/feature/secrets/SecretsFeature.dart +649 -0
  110. package/.sdk/tm/dart/lib/feature/secrets/plugin/capability.dart +105 -0
  111. package/.sdk/tm/dart/lib/feature/secrets/plugin/catalog.dart +46 -0
  112. package/.sdk/tm/dart/lib/feature/secrets/plugin/config.dart +297 -0
  113. package/.sdk/tm/dart/lib/feature/secrets/plugin/depend.dart +198 -0
  114. package/.sdk/tm/dart/lib/feature/secrets/plugin/env.dart +144 -0
  115. package/.sdk/tm/dart/lib/feature/secrets/plugin/export.dart +58 -0
  116. package/.sdk/tm/dart/lib/feature/secrets/plugin/graph.dart +160 -0
  117. package/.sdk/tm/dart/lib/feature/secrets/plugin/host.dart +1067 -0
  118. package/.sdk/tm/dart/lib/feature/secrets/plugin/order.dart +172 -0
  119. package/.sdk/tm/dart/lib/feature/secrets/plugin/plugin.dart +23 -0
  120. package/.sdk/tm/dart/lib/feature/secrets/plugin/point.dart +117 -0
  121. package/.sdk/tm/dart/lib/feature/secrets/plugin/ref.dart +105 -0
  122. package/.sdk/tm/dart/lib/feature/secrets/plugin/resolve.dart +58 -0
  123. package/.sdk/tm/dart/lib/feature/secrets/plugin/types.dart +201 -0
  124. package/.sdk/tm/dart/lib/feature/secrets/plugin/version.dart +116 -0
  125. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/aws.dart +285 -0
  126. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/azuresecrets.dart +178 -0
  127. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/boru.dart +145 -0
  128. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/crypto.dart +194 -0
  129. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/doppler.dart +101 -0
  130. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/gcpsecrets.dart +143 -0
  131. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/hashicorp.dart +190 -0
  132. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/httpjson.dart +363 -0
  133. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/infisical.dart +149 -0
  134. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/onepassword.dart +146 -0
  135. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/secretspec.dart +116 -0
  136. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/sigv4.dart +237 -0
  137. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/addr.dart +138 -0
  138. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/json.dart +276 -0
  139. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/provider.dart +31 -0
  140. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/providers.dart +243 -0
  141. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/sekreto.dart +730 -0
  142. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/spec.dart +200 -0
  143. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/support.dart +217 -0
  144. package/.sdk/tm/dart/lib/feature/streaming/StreamingFeature.dart +97 -0
  145. package/.sdk/tm/dart/lib/feature/telemetry/TelemetryFeature.dart +136 -0
  146. package/.sdk/tm/dart/lib/feature/test/TestFeature.dart +328 -0
  147. package/.sdk/tm/dart/lib/feature/timeout/TimeoutFeature.dart +104 -0
  148. package/.sdk/tm/dart/lib/utility/CleanUtility.dart +12 -0
  149. package/.sdk/tm/dart/lib/utility/DoneUtility.dart +18 -0
  150. package/.sdk/tm/dart/lib/utility/ErrUtility.dart +46 -0
  151. package/.sdk/tm/dart/lib/utility/FeatureAddUtility.dart +35 -0
  152. package/.sdk/tm/dart/lib/utility/FeatureHookUtility.dart +20 -0
  153. package/.sdk/tm/dart/lib/utility/FeatureInitUtility.dart +9 -0
  154. package/.sdk/tm/dart/lib/utility/FetcherUtility.dart +104 -0
  155. package/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +162 -0
  156. package/.sdk/tm/dart/lib/utility/MakeContextUtility.dart +6 -0
  157. package/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +71 -0
  158. package/.sdk/tm/dart/lib/utility/MakeFetchDefUtility.dart +42 -0
  159. package/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +233 -0
  160. package/.sdk/tm/dart/lib/utility/MakePointUtility.dart +130 -0
  161. package/.sdk/tm/dart/lib/utility/MakeRequestUtility.dart +66 -0
  162. package/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +59 -0
  163. package/.sdk/tm/dart/lib/utility/MakeResultUtility.dart +49 -0
  164. package/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +77 -0
  165. package/.sdk/tm/dart/lib/utility/MakeUrlUtility.dart +51 -0
  166. package/.sdk/tm/dart/lib/utility/ParamUtility.dart +56 -0
  167. package/.sdk/tm/dart/lib/utility/PrepareAuthUtility.dart +46 -0
  168. package/.sdk/tm/dart/lib/utility/PrepareBodyUtility.dart +19 -0
  169. package/.sdk/tm/dart/lib/utility/PrepareHeadersUtility.dart +11 -0
  170. package/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +30 -0
  171. package/.sdk/tm/dart/lib/utility/PrepareParamsUtility.dart +23 -0
  172. package/.sdk/tm/dart/lib/utility/PreparePathUtility.dart +9 -0
  173. package/.sdk/tm/dart/lib/utility/PrepareQueryUtility.dart +18 -0
  174. package/.sdk/tm/dart/lib/utility/ResultBasicUtility.dart +29 -0
  175. package/.sdk/tm/dart/lib/utility/ResultBodyUtility.dart +15 -0
  176. package/.sdk/tm/dart/lib/utility/ResultHeadersUtility.dart +18 -0
  177. package/.sdk/tm/dart/lib/utility/StructUtility.dart +127 -0
  178. package/.sdk/tm/dart/lib/utility/TransformRequestUtility.dart +28 -0
  179. package/.sdk/tm/dart/lib/utility/TransformResponseUtility.dart +44 -0
  180. package/.sdk/tm/dart/lib/utility/Utility.dart +239 -0
  181. package/.sdk/tm/dart/lib/utility/voxgig_struct.dart +2462 -0
  182. package/.sdk/tm/dart/src/feature/README.md +3 -0
  183. package/.sdk/tm/dart/src/feature/audit/.gitkeep +0 -0
  184. package/.sdk/tm/dart/src/feature/base/.gitkeep +0 -0
  185. package/.sdk/tm/dart/src/feature/cache/.gitkeep +0 -0
  186. package/.sdk/tm/dart/src/feature/clienttrack/.gitkeep +0 -0
  187. package/.sdk/tm/dart/src/feature/cost/.gitkeep +0 -0
  188. package/.sdk/tm/dart/src/feature/debug/.gitkeep +0 -0
  189. package/.sdk/tm/dart/src/feature/idempotency/.gitkeep +0 -0
  190. package/.sdk/tm/dart/src/feature/log/.gitkeep +0 -0
  191. package/.sdk/tm/dart/src/feature/metrics/.gitkeep +0 -0
  192. package/.sdk/tm/dart/src/feature/netsim/.gitkeep +0 -0
  193. package/.sdk/tm/dart/src/feature/paging/.gitkeep +0 -0
  194. package/.sdk/tm/dart/src/feature/proxy/.gitkeep +0 -0
  195. package/.sdk/tm/dart/src/feature/ratelimit/.gitkeep +0 -0
  196. package/.sdk/tm/dart/src/feature/rbac/.gitkeep +0 -0
  197. package/.sdk/tm/dart/src/feature/retry/.gitkeep +0 -0
  198. package/.sdk/tm/dart/src/feature/secrets/.gitkeep +0 -0
  199. package/.sdk/tm/dart/src/feature/streaming/.gitkeep +0 -0
  200. package/.sdk/tm/dart/src/feature/telemetry/.gitkeep +0 -0
  201. package/.sdk/tm/dart/src/feature/test/.gitkeep +0 -0
  202. package/.sdk/tm/dart/src/feature/timeout/.gitkeep +0 -0
  203. package/.sdk/tm/dart/test/custom_test.dart +65 -0
  204. package/.sdk/tm/dart/test/exists_test.dart +12 -0
  205. package/.sdk/tm/dart/test/feature/harness.dart +347 -0
  206. package/.sdk/tm/dart/test/feature/secrets/secrets_test.dart +1107 -0
  207. package/.sdk/tm/dart/test/feature_test.dart +1193 -0
  208. package/.sdk/tm/dart/test/harness.dart +153 -0
  209. package/.sdk/tm/dart/test/netsim_test.dart +48 -0
  210. package/.sdk/tm/dart/test/omni.dart +520 -0
  211. package/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
  212. package/.sdk/tm/dart/test/pipeline_test.dart +608 -0
  213. package/.sdk/tm/dart/test/primary_test.dart +476 -0
  214. package/.sdk/tm/dart/test/sdk-test-control.json +19 -0
  215. package/.sdk/tm/dart/test/struct_test.dart +468 -0
  216. package/.sdk/tm/dart/test/utility.dart +198 -0
  217. package/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
  218. package/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
  219. package/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
  220. package/.sdk/tm/haskell/LICENSE +21 -0
  221. package/.sdk/tm/haskell/Makefile +22 -0
  222. package/.sdk/tm/haskell/VERSION +1 -0
  223. package/.sdk/tm/haskell/src/SdkFeatures.hs +1440 -0
  224. package/.sdk/tm/haskell/src/SdkHelpers.hs +337 -0
  225. package/.sdk/tm/haskell/src/SdkJson.hs +111 -0
  226. package/.sdk/tm/haskell/src/SdkRuntime.hs +1279 -0
  227. package/.sdk/tm/haskell/src/SdkTypes.hs +195 -0
  228. package/.sdk/tm/haskell/src/VoxgigStruct.hs +2299 -0
  229. package/.sdk/tm/haskell/src/Vregex.hs +237 -0
  230. package/.sdk/tm/haskell/src/feature/README.md +5 -0
  231. package/.sdk/tm/haskell/src/feature/audit/.gitkeep +0 -0
  232. package/.sdk/tm/haskell/src/feature/base/.gitkeep +0 -0
  233. package/.sdk/tm/haskell/src/feature/cache/.gitkeep +0 -0
  234. package/.sdk/tm/haskell/src/feature/clienttrack/.gitkeep +0 -0
  235. package/.sdk/tm/haskell/src/feature/debug/.gitkeep +0 -0
  236. package/.sdk/tm/haskell/src/feature/idempotency/.gitkeep +0 -0
  237. package/.sdk/tm/haskell/src/feature/log/.gitkeep +0 -0
  238. package/.sdk/tm/haskell/src/feature/metrics/.gitkeep +0 -0
  239. package/.sdk/tm/haskell/src/feature/netsim/.gitkeep +0 -0
  240. package/.sdk/tm/haskell/src/feature/paging/.gitkeep +0 -0
  241. package/.sdk/tm/haskell/src/feature/proxy/.gitkeep +0 -0
  242. package/.sdk/tm/haskell/src/feature/ratelimit/.gitkeep +0 -0
  243. package/.sdk/tm/haskell/src/feature/rbac/.gitkeep +0 -0
  244. package/.sdk/tm/haskell/src/feature/retry/.gitkeep +0 -0
  245. package/.sdk/tm/haskell/src/feature/streaming/.gitkeep +0 -0
  246. package/.sdk/tm/haskell/src/feature/telemetry/.gitkeep +0 -0
  247. package/.sdk/tm/haskell/src/feature/test/.gitkeep +0 -0
  248. package/.sdk/tm/haskell/src/feature/timeout/.gitkeep +0 -0
  249. package/.sdk/tm/haskell/test/Harness.hs +281 -0
  250. package/.sdk/tm/haskell/test/OmniResolver.hs +252 -0
  251. package/.sdk/tm/haskell/test/Runner.hs +49 -0
  252. package/.sdk/tm/haskell/test/StructCorpus.hs +449 -0
  253. package/.sdk/tm/haskell/test/TCustomUtility.hs +38 -0
  254. package/.sdk/tm/haskell/test/TFeature.hs +794 -0
  255. package/.sdk/tm/haskell/test/TNetsim.hs +50 -0
  256. package/.sdk/tm/haskell/test/TPipeline.hs +334 -0
  257. package/.sdk/tm/haskell/test/TPrimaryCorpus.hs +263 -0
  258. package/.sdk/tm/haskell/test/TPrimaryUtility.hs +386 -0
  259. package/.sdk/tm/haskell/test/Testutil.hs +59 -0
  260. package/.sdk/tm/haskell/test/vendor/omni/Omni.hs +1147 -0
  261. package/.sdk/tm/lean/LICENSE +21 -0
  262. package/.sdk/tm/lean/Makefile +32 -0
  263. package/.sdk/tm/lean/VERSION +1 -0
  264. package/.sdk/tm/lean/src/SdkFeature.lean +171 -0
  265. package/.sdk/tm/lean/src/SdkFeatures.lean +787 -0
  266. package/.sdk/tm/lean/src/SdkJson.lean +134 -0
  267. package/.sdk/tm/lean/src/SdkRuntime.lean +374 -0
  268. package/.sdk/tm/lean/src/SdkUtility.lean +809 -0
  269. package/.sdk/tm/lean/src/VoxgigStruct.lean +2880 -0
  270. package/.sdk/tm/lean/src/Vregex.lean +412 -0
  271. package/.sdk/tm/lean/src/feature/README.md +5 -0
  272. package/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
  273. package/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
  274. package/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
  275. package/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
  276. package/.sdk/tm/lean/src/feature/cost/.gitkeep +0 -0
  277. package/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
  278. package/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
  279. package/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
  280. package/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
  281. package/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
  282. package/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
  283. package/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
  284. package/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
  285. package/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
  286. package/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
  287. package/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
  288. package/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
  289. package/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
  290. package/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
  291. package/.sdk/tm/lean/test/OmniResolver.lean +358 -0
  292. package/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
  293. package/.sdk/tm/lean/test/StructCorpus.lean +368 -0
  294. package/.sdk/tm/lean/test/TFeature.lean +281 -0
  295. package/.sdk/tm/lean/test/TPrimaryUtility.lean +227 -0
  296. package/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
  297. package/LICENSE +21 -0
  298. package/README.md +104 -0
  299. package/package.json +78 -0
  300. package/sdkgen-package.json +22 -0
@@ -0,0 +1,1193 @@
1
+ // Behavioural + coverage tests for the enterprise features shipped with
2
+ // this SDK. Each block runs only when its feature is present (see
3
+ // hasFeature), driving the real generated feature class through the offline
4
+ // harness pipeline against a simulated network. Port of ts test/feature.test.ts.
5
+
6
+ import 'harness.dart';
7
+ import 'feature/harness.dart';
8
+
9
+ import '../lib/utility/ErrUtility.dart';
10
+
11
+ class Recording {
12
+ final List calls = [];
13
+ late ServerFn server;
14
+ }
15
+
16
+ Recording recordingServer([dynamic Function(int n, dynamic fetchdef)? reply]) {
17
+ final rec = Recording();
18
+ rec.server = (dynamic _ctx, dynamic url, dynamic fetchdef) {
19
+ rec.calls.add({'url': url, 'fetchdef': fetchdef});
20
+ if (null != reply) {
21
+ return reply(rec.calls.length, fetchdef);
22
+ }
23
+ return makeResponse(200, {'ok': true, 'n': rec.calls.length});
24
+ };
25
+ return rec;
26
+ }
27
+
28
+ dynamic _hdr(Recording rec, int i, String name) =>
29
+ rec.calls[i]['fetchdef']['headers'][name];
30
+
31
+ void tests() {
32
+ describe('feature', () {
33
+ test('at least the test feature is present', (t) {
34
+ equal(true, hasFeature('test'));
35
+ });
36
+
37
+ // --- netsim -------------------------------------------------------------
38
+ if (hasFeature('netsim')) {
39
+ describe('netsim', () {
40
+ test('fixed latency then delegate', (t) async {
41
+ final clock = makeClock();
42
+ final h = makeClient(features: [
43
+ {'name': 'netsim', 'options': {'latency': 250, 'sleep': clock.sleep}}
44
+ ]);
45
+ final res = await h.op({'op': 'load', 'ctrl': {'explain': {}}});
46
+ equal(true, res['ok']);
47
+ equal(250, clock.time);
48
+ equal(1, h.client.track['netsim']['calls']);
49
+ });
50
+
51
+ test('ranged latency samples within [min,max)', (t) async {
52
+ final clock = makeClock();
53
+ final h = makeClient(features: [
54
+ {
55
+ 'name': 'netsim',
56
+ 'options': {
57
+ 'latency': {'min': 100, 'max': 300},
58
+ 'seed': 7,
59
+ 'sleep': clock.sleep
60
+ }
61
+ }
62
+ ]);
63
+ await h.op({'op': 'load'});
64
+ ok(clock.time >= 100 && clock.time < 300,
65
+ 'latency in range, got ' + clock.time.toString());
66
+ });
67
+
68
+ test('equal min/max latency is exact', (t) async {
69
+ final clock = makeClock();
70
+ final h = makeClient(features: [
71
+ {
72
+ 'name': 'netsim',
73
+ 'options': {
74
+ 'latency': {'min': 50, 'max': 50},
75
+ 'sleep': clock.sleep
76
+ }
77
+ }
78
+ ]);
79
+ await h.op({'op': 'load'});
80
+ equal(50, clock.time);
81
+ });
82
+
83
+ test('failTimes returns a retryable status', (t) async {
84
+ final h = makeClient(features: [
85
+ {'name': 'netsim', 'options': {'failTimes': 2, 'failStatus': 503}}
86
+ ]);
87
+ equal(503, (await h.op({'op': 'load'}))['result'].status);
88
+ equal(503, (await h.op({'op': 'load'}))['result'].status);
89
+ equal(true, (await h.op({'op': 'load'}))['ok']);
90
+ });
91
+
92
+ test('failEvery fails every Nth call', (t) async {
93
+ final h = makeClient(features: [
94
+ {'name': 'netsim', 'options': {'failEvery': 2}}
95
+ ]);
96
+ equal(true, (await h.op({'op': 'load'}))['ok']);
97
+ equal(false, (await h.op({'op': 'load'}))['ok']);
98
+ equal(true, (await h.op({'op': 'load'}))['ok']);
99
+ });
100
+
101
+ test('failRate with a seed is deterministic', (t) async {
102
+ final h = makeClient(features: [
103
+ {'name': 'netsim', 'options': {'failRate': 1, 'seed': 5}}
104
+ ]);
105
+ equal(false, (await h.op({'op': 'load'}))['ok']);
106
+ });
107
+
108
+ test('errorTimes throws a connection error', (t) async {
109
+ final h = makeClient(features: [
110
+ {'name': 'netsim', 'options': {'errorTimes': 1}}
111
+ ]);
112
+ equal('netsim_conn', errcode((await h.op({'op': 'load'}))['error']));
113
+ });
114
+
115
+ test('offline fails every call', (t) async {
116
+ final h = makeClient(features: [
117
+ {'name': 'netsim', 'options': {'offline': true}}
118
+ ]);
119
+ equal('netsim_offline', errcode((await h.op({'op': 'load'}))['error']));
120
+ });
121
+
122
+ test('rateLimitTimes returns 429 + Retry-After', (t) async {
123
+ final h = makeClient(features: [
124
+ {'name': 'netsim', 'options': {'rateLimitTimes': 1, 'retryAfter': 3}}
125
+ ]);
126
+ final res = await h.op({'op': 'load'});
127
+ equal(429, res['result'].status);
128
+ equal('3', res['result'].headers['retry-after']);
129
+ });
130
+ });
131
+ }
132
+
133
+ // --- retry --------------------------------------------------------------
134
+ if (hasFeature('retry')) {
135
+ describe('retry', () {
136
+ test('retries transient failures then succeeds', (t) async {
137
+ // Drives netsim as the simulated network: runnable only when this
138
+ // SDK was generated with it (the harness skips absent features).
139
+ if (!hasFeature('netsim')) {
140
+ t.skip('this SDK was generated without the netsim feature');
141
+ return;
142
+ }
143
+ final clock = makeClock();
144
+ final h = makeClient(features: [
145
+ {'name': 'netsim', 'options': {'failTimes': 2, 'failStatus': 503}},
146
+ {
147
+ 'name': 'retry',
148
+ 'options': {
149
+ 'retries': 3,
150
+ 'minDelay': 10,
151
+ 'jitter': false,
152
+ 'sleep': clock.sleep
153
+ }
154
+ },
155
+ ]);
156
+ equal(true, (await h.op({'op': 'load'}))['ok']);
157
+ equal(2, h.client.track['retry']['attempts']);
158
+ });
159
+
160
+ test('gives up after the budget', (t) async {
161
+ // Drives netsim as the simulated network: runnable only when this
162
+ // SDK was generated with it (the harness skips absent features).
163
+ if (!hasFeature('netsim')) {
164
+ t.skip('this SDK was generated without the netsim feature');
165
+ return;
166
+ }
167
+ final clock = makeClock();
168
+ final h = makeClient(features: [
169
+ {'name': 'netsim', 'options': {'failTimes': 9, 'failStatus': 500}},
170
+ {
171
+ 'name': 'retry',
172
+ 'options': {
173
+ 'retries': 2,
174
+ 'minDelay': 1,
175
+ 'jitter': false,
176
+ 'sleep': clock.sleep
177
+ }
178
+ },
179
+ ]);
180
+ equal(500, (await h.op({'op': 'load'}))['result'].status);
181
+ });
182
+
183
+ test('does not retry a non-retryable status', (t) async {
184
+ final rec = recordingServer((n, f) => makeResponse(404));
185
+ final h = makeClient(features: [
186
+ {'name': 'retry', 'options': {'retries': 3, 'minDelay': 0}}
187
+ ], server: rec.server);
188
+ await h.op({'op': 'load'});
189
+ equal(1, rec.calls.length);
190
+ });
191
+
192
+ test('retries a thrown transport error then rethrows when exhausted',
193
+ (t) async {
194
+ final clock = makeClock();
195
+ var n = 0;
196
+ server(dynamic c, dynamic u, dynamic f) {
197
+ n++;
198
+ throw StateError('boom');
199
+ }
200
+
201
+ final h = makeClient(features: [
202
+ {
203
+ 'name': 'retry',
204
+ 'options': {
205
+ 'retries': 2,
206
+ 'minDelay': 1,
207
+ 'jitter': false,
208
+ 'sleep': clock.sleep
209
+ }
210
+ }
211
+ ], server: server);
212
+ final res = await h.op({'op': 'load'});
213
+ equal(false, res['ok']);
214
+ equal(3, n);
215
+ });
216
+
217
+ test('honours a server Retry-After', (t) async {
218
+ // Drives netsim as the simulated network: runnable only when this
219
+ // SDK was generated with it (the harness skips absent features).
220
+ if (!hasFeature('netsim')) {
221
+ t.skip('this SDK was generated without the netsim feature');
222
+ return;
223
+ }
224
+ final clock = makeClock();
225
+ final h = makeClient(features: [
226
+ {'name': 'netsim', 'options': {'rateLimitTimes': 1, 'retryAfter': 2}},
227
+ {
228
+ 'name': 'retry',
229
+ 'options': {
230
+ 'retries': 2,
231
+ 'minDelay': 10,
232
+ 'maxDelay': 60000,
233
+ 'jitter': false,
234
+ 'sleep': clock.sleep
235
+ }
236
+ },
237
+ ]);
238
+ equal(true, (await h.op({'op': 'load'}))['ok']);
239
+ equal(2000, clock.time);
240
+ });
241
+
242
+ test('default jitter path still succeeds', (t) async {
243
+ // Drives netsim as the simulated network: runnable only when this
244
+ // SDK was generated with it (the harness skips absent features).
245
+ if (!hasFeature('netsim')) {
246
+ t.skip('this SDK was generated without the netsim feature');
247
+ return;
248
+ }
249
+ final h = makeClient(features: [
250
+ {'name': 'netsim', 'options': {'failTimes': 1}},
251
+ {'name': 'retry', 'options': {'retries': 2, 'minDelay': 0}},
252
+ ]);
253
+ equal(true, (await h.op({'op': 'load'}))['ok']);
254
+ });
255
+ });
256
+ }
257
+
258
+ // --- timeout ------------------------------------------------------------
259
+ if (hasFeature('timeout')) {
260
+ describe('timeout', () {
261
+ test('a slow request times out', (t) async {
262
+ // Drives netsim as the simulated network: runnable only when this
263
+ // SDK was generated with it (the harness skips absent features).
264
+ if (!hasFeature('netsim')) {
265
+ t.skip('this SDK was generated without the netsim feature');
266
+ return;
267
+ }
268
+ final h = makeClient(features: [
269
+ {'name': 'netsim', 'options': {'latency': 80}},
270
+ {'name': 'timeout', 'options': {'ms': 10}},
271
+ ]);
272
+ final res = await h.op({'op': 'load'});
273
+ equal('timeout', errcode(res['error']));
274
+ equal(1, h.client.track['timeout']['count']);
275
+ });
276
+
277
+ test('a fast request passes through', (t) async {
278
+ final h = makeClient(features: [
279
+ {'name': 'timeout', 'options': {'ms': 1000}}
280
+ ]);
281
+ equal(true, (await h.op({'op': 'load'}))['ok']);
282
+ });
283
+
284
+ test('ms<=0 disables the timeout', (t) async {
285
+ final h = makeClient(features: [
286
+ {'name': 'timeout', 'options': {'ms': 0}}
287
+ ]);
288
+ equal(true, (await h.op({'op': 'load'}))['ok']);
289
+ });
290
+ });
291
+ }
292
+
293
+ // --- ratelimit ----------------------------------------------------------
294
+ if (hasFeature('ratelimit')) {
295
+ describe('ratelimit', () {
296
+ test('throttles once the burst is spent', (t) async {
297
+ final clock = makeClock();
298
+ final h = makeClient(features: [
299
+ {
300
+ 'name': 'ratelimit',
301
+ 'options': {
302
+ 'rate': 1,
303
+ 'burst': 2,
304
+ 'now': clock.now,
305
+ 'sleep': clock.sleep
306
+ }
307
+ }
308
+ ]);
309
+ await h.op({'op': 'load'});
310
+ await h.op({'op': 'load'});
311
+ await h.op({'op': 'load'});
312
+ equal(1, h.client.track['ratelimit']['throttled']);
313
+ ok(clock.time > 0);
314
+ });
315
+
316
+ test('burst defaults to rate and refills over time', (t) async {
317
+ final clock = makeClock();
318
+ final h = makeClient(features: [
319
+ {
320
+ 'name': 'ratelimit',
321
+ 'options': {'rate': 2, 'now': clock.now, 'sleep': clock.sleep}
322
+ }
323
+ ]);
324
+ await h.op({'op': 'load'});
325
+ await h.op({'op': 'load'});
326
+ clock.advance(1000); // refill
327
+ await h.op({'op': 'load'});
328
+ final rl = h.client.track['ratelimit'];
329
+ equal(0, null == rl ? 0 : rl['throttled']);
330
+ });
331
+ });
332
+ }
333
+
334
+ // --- cache --------------------------------------------------------------
335
+ if (hasFeature('cache')) {
336
+ describe('cache', () {
337
+ test('serves a repeated read from cache', (t) async {
338
+ final rec = recordingServer();
339
+ final h = makeClient(features: [
340
+ {'name': 'cache', 'options': {'ttl': 10000}}
341
+ ], server: rec.server);
342
+ final a = await h.op({'op': 'load', 'path': '/w/1'});
343
+ final b = await h.op({'op': 'load', 'path': '/w/1'});
344
+ equal(1, rec.calls.length);
345
+ deepEqual(a['data'], b['data']);
346
+ equal(1, h.client.track['cache']['hit']);
347
+ });
348
+
349
+ test('does not cache non-GET', (t) async {
350
+ final rec = recordingServer();
351
+ final h = makeClient(features: [
352
+ {'name': 'cache'}
353
+ ], server: rec.server);
354
+ await h.op({'op': 'create', 'path': '/w'});
355
+ await h.op({'op': 'create', 'path': '/w'});
356
+ equal(2, rec.calls.length);
357
+ });
358
+
359
+ test('does not cache a non-2xx (bypass)', (t) async {
360
+ final rec = recordingServer((n, f) => makeResponse(500));
361
+ final h = makeClient(features: [
362
+ {'name': 'cache'}
363
+ ], server: rec.server);
364
+ await h.op({'op': 'load', 'path': '/w'});
365
+ await h.op({'op': 'load', 'path': '/w'});
366
+ equal(2, rec.calls.length);
367
+ equal(2, h.client.track['cache']['bypass']);
368
+ });
369
+
370
+ test('re-fetches after the ttl', (t) async {
371
+ final clock = makeClock();
372
+ final rec = recordingServer();
373
+ final h = makeClient(features: [
374
+ {'name': 'cache', 'options': {'ttl': 1000, 'now': clock.now}}
375
+ ], server: rec.server);
376
+ await h.op({'op': 'load', 'path': '/w'});
377
+ clock.advance(1500);
378
+ await h.op({'op': 'load', 'path': '/w'});
379
+ equal(2, rec.calls.length);
380
+ });
381
+
382
+ test('evicts the oldest entry past max', (t) async {
383
+ final rec = recordingServer();
384
+ final h = makeClient(features: [
385
+ {'name': 'cache', 'options': {'ttl': 10000, 'max': 1}}
386
+ ], server: rec.server);
387
+ await h.op({'op': 'load', 'path': '/a'});
388
+ await h.op({'op': 'load', 'path': '/b'}); // evicts /a
389
+ await h.op({'op': 'load', 'path': '/a'}); // miss again
390
+ equal(3, rec.calls.length);
391
+ });
392
+ });
393
+ }
394
+
395
+ // --- idempotency ----------------------------------------------------------
396
+ if (hasFeature('idempotency')) {
397
+ describe('idempotency', () {
398
+ test('adds a key to mutating ops', (t) async {
399
+ final rec = recordingServer();
400
+ final h = makeClient(features: [
401
+ {'name': 'idempotency'}
402
+ ], server: rec.server);
403
+ await h.op({'op': 'create', 'path': '/w'});
404
+ ok(null != _hdr(rec, 0, 'Idempotency-Key'));
405
+ });
406
+
407
+ test('adds a key based on HTTP method', (t) async {
408
+ final rec = recordingServer();
409
+ final h = makeClient(features: [
410
+ {'name': 'idempotency'}
411
+ ], server: rec.server);
412
+ await h.op({'op': 'act', 'method': 'PUT', 'path': '/w'});
413
+ ok(null != _hdr(rec, 0, 'Idempotency-Key'));
414
+ });
415
+
416
+ test('leaves reads untouched', (t) async {
417
+ final rec = recordingServer();
418
+ final h = makeClient(features: [
419
+ {'name': 'idempotency'}
420
+ ], server: rec.server);
421
+ await h.op({'op': 'load', 'path': '/w/1'});
422
+ equal(null, _hdr(rec, 0, 'Idempotency-Key'));
423
+ });
424
+
425
+ test('preserves a caller key and honours a custom header', (t) async {
426
+ final rec = recordingServer();
427
+ final h = makeClient(features: [
428
+ {'name': 'idempotency', 'options': {'header': 'X-Idem'}}
429
+ ], server: rec.server);
430
+ await h.op({
431
+ 'op': 'create',
432
+ 'path': '/w',
433
+ 'headers': {'X-Idem': 'caller-1'}
434
+ });
435
+ equal('caller-1', _hdr(rec, 0, 'X-Idem'));
436
+ });
437
+ });
438
+ }
439
+
440
+ // --- rbac ---------------------------------------------------------------
441
+ if (hasFeature('rbac')) {
442
+ describe('rbac', () {
443
+ test('denies before any call', (t) async {
444
+ final rec = recordingServer();
445
+ final h = makeClient(features: [
446
+ {
447
+ 'name': 'rbac',
448
+ 'options': {
449
+ 'rules': {'widget.remove': 'admin'},
450
+ 'permissions': []
451
+ }
452
+ }
453
+ ], server: rec.server);
454
+ final res = await h.op({'op': 'remove', 'path': '/w/1'});
455
+ equal('rbac_denied', errcode(res['error']));
456
+ equal(0, rec.calls.length);
457
+ equal(1, h.client.track['rbac']['denied']);
458
+ });
459
+
460
+ test('allows a held permission', (t) async {
461
+ final h = makeClient(features: [
462
+ {
463
+ 'name': 'rbac',
464
+ 'options': {
465
+ 'rules': {'widget.remove': 'admin'},
466
+ 'permissions': ['admin']
467
+ }
468
+ }
469
+ ]);
470
+ equal(true, (await h.op({'op': 'remove', 'path': '/w/1'}))['ok']);
471
+ });
472
+
473
+ test('rule by op name and wildcard grant', (t) async {
474
+ final h = makeClient(features: [
475
+ {
476
+ 'name': 'rbac',
477
+ 'options': {
478
+ 'rules': {'load': 'read'},
479
+ 'permissions': ['*']
480
+ }
481
+ }
482
+ ]);
483
+ equal(true, (await h.op({'op': 'load'}))['ok']);
484
+ });
485
+
486
+ test('no rule allows by default; deny:true blocks', (t) async {
487
+ final allow = makeClient(features: [
488
+ {'name': 'rbac', 'options': {'permissions': []}}
489
+ ]);
490
+ equal(true, (await allow.op({'op': 'load'}))['ok']);
491
+ final deny = makeClient(features: [
492
+ {'name': 'rbac', 'options': {'deny': true, 'permissions': []}}
493
+ ]);
494
+ equal('rbac_denied', errcode((await deny.op({'op': 'load'}))['error']));
495
+ });
496
+ });
497
+ }
498
+
499
+ // --- metrics ------------------------------------------------------------
500
+ if (hasFeature('metrics')) {
501
+ describe('metrics', () {
502
+ test('counts ok and err per op', (t) async {
503
+ // Drives netsim as the simulated network: runnable only when this
504
+ // SDK was generated with it (the harness skips absent features).
505
+ if (!hasFeature('netsim')) {
506
+ t.skip('this SDK was generated without the netsim feature');
507
+ return;
508
+ }
509
+ final h = makeClient(features: [
510
+ {'name': 'netsim', 'options': {'failTimes': 1, 'failStatus': 500}},
511
+ {'name': 'metrics', 'options': {}},
512
+ ]);
513
+ await h.op({'op': 'load'});
514
+ await h.op({'op': 'load'});
515
+ await h.op({'op': 'list'});
516
+ final m = h.client.track['metrics'];
517
+ equal(3, m['total']['count']);
518
+ equal(2, m['total']['ok']);
519
+ equal(1, m['total']['err']);
520
+ equal(2, m['ops']['widget.load']['count']);
521
+ });
522
+ });
523
+ }
524
+
525
+ // --- telemetry ----------------------------------------------------------
526
+ if (hasFeature('telemetry')) {
527
+ describe('telemetry', () {
528
+ test('opens spans and propagates trace headers', (t) async {
529
+ final rec = recordingServer();
530
+ final spans = [];
531
+ final h = makeClient(features: [
532
+ {
533
+ 'name': 'telemetry',
534
+ 'options': {'exporter': (s) => spans.add(s)}
535
+ }
536
+ ], server: rec.server);
537
+ final res = await h.op({'op': 'load'});
538
+ equal(true, res['ok']);
539
+ equal(1, h.client.track['telemetry']['spans'].length);
540
+ equal(1, spans.length);
541
+ equal(_hdr(rec, 0, 'X-Trace-Id'),
542
+ h.client.track['telemetry']['spans'][0]['traceId']);
543
+ ok(RegExp(r'^00-.+-.+-01$')
544
+ .hasMatch(_hdr(rec, 0, 'traceparent').toString()));
545
+ });
546
+
547
+ test('records a failed span on error', (t) async {
548
+ // Drives netsim as the simulated network: runnable only when this
549
+ // SDK was generated with it (the harness skips absent features).
550
+ if (!hasFeature('netsim')) {
551
+ t.skip('this SDK was generated without the netsim feature');
552
+ return;
553
+ }
554
+ final h = makeClient(features: [
555
+ {'name': 'netsim', 'options': {'failTimes': 1, 'failStatus': 500}},
556
+ {'name': 'telemetry', 'options': {}},
557
+ ]);
558
+ await h.op({'op': 'load'});
559
+ equal(false, h.client.track['telemetry']['spans'][0]['ok']);
560
+ });
561
+ });
562
+ }
563
+
564
+ // --- debug --------------------------------------------------------------
565
+ if (hasFeature('debug')) {
566
+ describe('debug', () {
567
+ test('captures a redacted trace and honours onEntry + max', (t) async {
568
+ final seen = [];
569
+ final h = makeClient(features: [
570
+ {
571
+ 'name': 'debug',
572
+ 'options': {'max': 1, 'onEntry': (e) => seen.add(e)}
573
+ }
574
+ ]);
575
+ await h.op({
576
+ 'op': 'load',
577
+ 'headers': {'authorization': 'Bearer secret'}
578
+ });
579
+ await h.op({'op': 'list'});
580
+ final entries = h.client.track['debug']['entries'];
581
+ equal(1, entries.length); // ring buffer capped at max
582
+ equal(2, seen.length);
583
+ equal('<redacted>', seen[0]['headers']['authorization']);
584
+ });
585
+
586
+ test('captures failures', (t) async {
587
+ // Drives netsim as the simulated network: runnable only when this
588
+ // SDK was generated with it (the harness skips absent features).
589
+ if (!hasFeature('netsim')) {
590
+ t.skip('this SDK was generated without the netsim feature');
591
+ return;
592
+ }
593
+ final h = makeClient(features: [
594
+ {'name': 'netsim', 'options': {'failTimes': 1, 'failStatus': 500}},
595
+ {'name': 'debug', 'options': {}},
596
+ ]);
597
+ await h.op({'op': 'load'});
598
+ equal(false, h.client.track['debug']['entries'][0]['ok']);
599
+ });
600
+ });
601
+ }
602
+
603
+ // --- audit --------------------------------------------------------------
604
+ if (hasFeature('audit')) {
605
+ describe('audit', () {
606
+ test('one record per op with sink + actor', (t) async {
607
+ // Drives netsim as the simulated network: runnable only when this
608
+ // SDK was generated with it (the harness skips absent features).
609
+ if (!hasFeature('netsim')) {
610
+ t.skip('this SDK was generated without the netsim feature');
611
+ return;
612
+ }
613
+ final sink = [];
614
+ final h = makeClient(features: [
615
+ {'name': 'netsim', 'options': {'failTimes': 1, 'failStatus': 500}},
616
+ {
617
+ 'name': 'audit',
618
+ 'options': {'actor': 'svc', 'sink': (r) => sink.add(r), 'max': 5}
619
+ },
620
+ ]);
621
+ await h.op({'op': 'remove', 'path': '/w/1'});
622
+ await h.op({
623
+ 'op': 'load',
624
+ 'ctrl': {'actor': 'per-call'}
625
+ });
626
+ final recs = h.client.track['audit']['records'];
627
+ equal(2, recs.length);
628
+ equal('error', recs[0]['outcome']);
629
+ equal('svc', recs[0]['actor']);
630
+ equal('per-call', recs[1]['actor']);
631
+ equal(2, sink.length);
632
+ });
633
+ });
634
+ }
635
+
636
+ // --- clienttrack ----------------------------------------------------------
637
+ if (hasFeature('clienttrack')) {
638
+ describe('clienttrack', () {
639
+ test('stable client id, unique request ids, UA', (t) async {
640
+ final rec = recordingServer();
641
+ final h = makeClient(features: [
642
+ {
643
+ 'name': 'clienttrack',
644
+ 'options': {'clientName': 'Acme', 'clientVersion': '2.0.0'}
645
+ }
646
+ ], server: rec.server);
647
+ await h.ready();
648
+ await h.op({'op': 'load'});
649
+ await h.op({'op': 'load'});
650
+ equal('Acme/2.0.0', _hdr(rec, 0, 'User-Agent'));
651
+ equal(_hdr(rec, 0, 'X-Client-Id'), _hdr(rec, 1, 'X-Client-Id'));
652
+ ok(_hdr(rec, 0, 'X-Request-Id') != _hdr(rec, 1, 'X-Request-Id'));
653
+ equal(2, h.client.track['clienttrack']['requests']);
654
+ });
655
+
656
+ test('does not clobber a caller User-Agent', (t) async {
657
+ final rec = recordingServer();
658
+ final h = makeClient(features: [
659
+ {'name': 'clienttrack'}
660
+ ], server: rec.server);
661
+ await h.ready();
662
+ await h.op({
663
+ 'op': 'load',
664
+ 'headers': {'User-Agent': 'mine'}
665
+ });
666
+ equal('mine', _hdr(rec, 0, 'User-Agent'));
667
+ });
668
+ });
669
+ }
670
+
671
+ // --- paging ---------------------------------------------------------------
672
+ if (hasFeature('paging')) {
673
+ describe('paging', () {
674
+ test('stamps page/limit and reads header signals', (t) async {
675
+ final rec = recordingServer((n, f) => makeResponse(200, {
676
+ 'items': [1, 2]
677
+ }, {
678
+ 'x-next-page': '2',
679
+ 'x-total-count': '5',
680
+ 'link': '</w?page=2>; rel="next"'
681
+ }));
682
+ final h = makeClient(features: [
683
+ {'name': 'paging', 'options': {'limit': 2}}
684
+ ], server: rec.server);
685
+ final res = await h.op({'op': 'list', 'path': '/w'});
686
+ ok(RegExp(r'[?&]page=1(&|$)').hasMatch(rec.calls[0]['url'].toString()));
687
+ ok(RegExp(r'[?&]limit=2(&|$)').hasMatch(rec.calls[0]['url'].toString()));
688
+ equal(2, res['result'].paging['nextPage']);
689
+ equal(5, res['result'].paging['totalCount']);
690
+ equal('/w?page=2', res['result'].paging['next']);
691
+ });
692
+
693
+ test('body cursor + explicit cursor request', (t) async {
694
+ final rec = recordingServer(
695
+ (n, f) => makeResponse(200, {'nextCursor': 'abc', 'hasMore': true}));
696
+ final h = makeClient(features: [
697
+ {'name': 'paging'}
698
+ ], server: rec.server);
699
+ final res = await h.op({
700
+ 'op': 'list',
701
+ 'path': '/w',
702
+ 'ctrl': {
703
+ 'paging': {'cursor': 'xyz'}
704
+ }
705
+ });
706
+ ok(RegExp(r'[?&]cursor=xyz(&|$)')
707
+ .hasMatch(rec.calls[0]['url'].toString()));
708
+ equal('abc', res['result'].paging['cursor']);
709
+ equal(true, res['result'].paging['hasMore']);
710
+ });
711
+ });
712
+ }
713
+
714
+ // --- streaming ------------------------------------------------------------
715
+ if (hasFeature('streaming')) {
716
+ describe('streaming', () {
717
+ test('streams list items', (t) async {
718
+ final clock = makeClock();
719
+ final rec = recordingServer((n, f) => makeResponse(200, ['a', 'b', 'c']));
720
+ final h = makeClient(features: [
721
+ {
722
+ 'name': 'streaming',
723
+ 'options': {'chunkDelay': 5, 'sleep': clock.sleep}
724
+ }
725
+ ], server: rec.server);
726
+ final res = await h.op({'op': 'list', 'path': '/w'});
727
+ equal(true, res['result'].streaming);
728
+ final seen = [];
729
+ await for (final item in res['result'].stream()) {
730
+ seen.add(item);
731
+ }
732
+ deepEqual(seen, ['a', 'b', 'c']);
733
+ equal(15, clock.time);
734
+ });
735
+
736
+ test('batches with chunkSize', (t) async {
737
+ final rec = recordingServer((n, f) => makeResponse(200, [1, 2, 3, 4, 5]));
738
+ final h = makeClient(features: [
739
+ {'name': 'streaming', 'options': {'chunkSize': 2}}
740
+ ], server: rec.server);
741
+ final res = await h.op({'op': 'list', 'path': '/w'});
742
+ final batches = [];
743
+ await for (final b in res['result'].stream()) {
744
+ batches.add(b);
745
+ }
746
+ deepEqual(batches, [
747
+ [1, 2],
748
+ [3, 4],
749
+ [5]
750
+ ]);
751
+ });
752
+ });
753
+ }
754
+
755
+ // --- proxy ----------------------------------------------------------------
756
+ if (hasFeature('proxy')) {
757
+ describe('proxy', () {
758
+ test('routes through the proxy and invokes an agent factory', (t) async {
759
+ final rec = recordingServer();
760
+ var agentUrl = '';
761
+ final h = makeClient(features: [
762
+ {
763
+ 'name': 'proxy',
764
+ 'options': {
765
+ 'url': 'http://proxy:8080',
766
+ 'agent': (u, target) {
767
+ agentUrl = u.toString();
768
+ return {'a': 1};
769
+ }
770
+ }
771
+ }
772
+ ], server: rec.server);
773
+ await h.op({'op': 'load'});
774
+ equal('http://proxy:8080', rec.calls[0]['fetchdef']['proxy']);
775
+ equal(1, rec.calls[0]['fetchdef']['dispatcher']['a']);
776
+ equal('http://proxy:8080', agentUrl);
777
+ equal(1, h.client.track['proxy']['routed']);
778
+ });
779
+
780
+ test('bypasses noProxy hosts', (t) async {
781
+ final rec = recordingServer();
782
+ final h = makeClient(
783
+ features: [
784
+ {
785
+ 'name': 'proxy',
786
+ 'options': {
787
+ 'url': 'http://proxy:8080',
788
+ 'noProxy': ['api.test']
789
+ }
790
+ }
791
+ ],
792
+ server: rec.server,
793
+ base: 'http://api.test');
794
+ await h.op({'op': 'load'});
795
+ equal(null, rec.calls[0]['fetchdef']['proxy']);
796
+ });
797
+ });
798
+ }
799
+
800
+ // --- edge branches (coverage) ---------------------------------------------
801
+ // Inactive features must no-op; transport features must handle odd
802
+ // responses; the default (non-injected) clocks/timers must run.
803
+
804
+ if (hasFeature('netsim')) {
805
+ describe('netsim-edge', () {
806
+ test('inactive netsim does not wrap', (t) async {
807
+ final h = makeClient(features: [
808
+ {'name': 'netsim', 'options': {'active': false}}
809
+ ]);
810
+ equal(true, (await h.op({'op': 'load'}))['ok']);
811
+ equal(null, h.client.track['netsim']);
812
+ });
813
+ test('no latency option delays nothing (real timer path)', (t) async {
814
+ final h = makeClient(features: [
815
+ {'name': 'netsim', 'options': {}}
816
+ ]);
817
+ equal(true, (await h.op({'op': 'load'}))['ok']);
818
+ });
819
+ test('real-timer latency actually waits', (t) async {
820
+ final h = makeClient(features: [
821
+ {'name': 'netsim', 'options': {'latency': 15}}
822
+ ]);
823
+ final t0 = DateTime.now().millisecondsSinceEpoch;
824
+ await h.op({'op': 'load'});
825
+ ok(DateTime.now().millisecondsSinceEpoch - t0 >= 8);
826
+ });
827
+ });
828
+ }
829
+
830
+ if (hasFeature('retry')) {
831
+ describe('retry-edge', () {
832
+ test('inactive retry does not wrap', (t) async {
833
+ final rec = recordingServer((n, f) => makeResponse(503));
834
+ final h = makeClient(features: [
835
+ {'name': 'retry', 'options': {'active': false}}
836
+ ], server: rec.server);
837
+ await h.op({'op': 'load'});
838
+ equal(1, rec.calls.length);
839
+ });
840
+ test('retries a null transport result', (t) async {
841
+ var n = 0;
842
+ server(dynamic c, dynamic u, dynamic f) {
843
+ n++;
844
+ return n < 2 ? null : makeResponse(200, {'ok': true});
845
+ }
846
+
847
+ final h = makeClient(features: [
848
+ {'name': 'retry', 'options': {'retries': 3, 'minDelay': 0}}
849
+ ], server: server);
850
+ equal(true, (await h.op({'op': 'load'}))['ok']);
851
+ equal(2, n);
852
+ });
853
+ test('non-numeric status is not retryable', (t) async {
854
+ final rec = recordingServer((n, f) => {
855
+ 'status': 'weird',
856
+ 'json': () => {},
857
+ 'headers': {},
858
+ });
859
+ final h = makeClient(features: [
860
+ {'name': 'retry', 'options': {'retries': 3, 'minDelay': 0}}
861
+ ], server: rec.server);
862
+ await h.op({'op': 'load'});
863
+ equal(1, rec.calls.length);
864
+ });
865
+ test('Retry-After via plain headers', (t) async {
866
+ final clock = makeClock();
867
+ var n = 0;
868
+ server(dynamic c, dynamic u, dynamic f) {
869
+ n++;
870
+ return n < 2
871
+ ? {
872
+ 'status': 429,
873
+ 'json': () => null,
874
+ 'headers': {'retry-after': '1'},
875
+ }
876
+ : makeResponse(200, {'ok': true});
877
+ }
878
+
879
+ final h = makeClient(features: [
880
+ {
881
+ 'name': 'retry',
882
+ 'options': {
883
+ 'retries': 2,
884
+ 'minDelay': 0,
885
+ 'jitter': false,
886
+ 'sleep': clock.sleep
887
+ }
888
+ }
889
+ ], server: server);
890
+ equal(true, (await h.op({'op': 'load'}))['ok']);
891
+ equal(1000, clock.time);
892
+ });
893
+ test('default timer backoff path runs', (t) async {
894
+ var n = 0;
895
+ server(dynamic c, dynamic u, dynamic f) {
896
+ n++;
897
+ return n < 2 ? makeResponse(503) : makeResponse(200, {'ok': true});
898
+ }
899
+
900
+ final h = makeClient(features: [
901
+ {
902
+ 'name': 'retry',
903
+ 'options': {'retries': 2, 'minDelay': 1, 'jitter': false}
904
+ }
905
+ ], server: server);
906
+ equal(true, (await h.op({'op': 'load'}))['ok']);
907
+ });
908
+ });
909
+ }
910
+
911
+ if (hasFeature('timeout')) {
912
+ describe('timeout-edge', () {
913
+ test('inactive timeout does not wrap', (t) async {
914
+ final h = makeClient(features: [
915
+ {'name': 'timeout', 'options': {'active': false}}
916
+ ]);
917
+ equal(true, (await h.op({'op': 'load'}))['ok']);
918
+ });
919
+ });
920
+ }
921
+
922
+ if (hasFeature('cache')) {
923
+ describe('cache-edge', () {
924
+ test('inactive cache does not wrap', (t) async {
925
+ final rec = recordingServer();
926
+ final h = makeClient(features: [
927
+ {'name': 'cache', 'options': {'active': false}}
928
+ ], server: rec.server);
929
+ await h.op({'op': 'load', 'path': '/x'});
930
+ await h.op({'op': 'load', 'path': '/x'});
931
+ equal(2, rec.calls.length);
932
+ });
933
+ test('real clock ttl path', (t) async {
934
+ final rec = recordingServer();
935
+ final h = makeClient(features: [
936
+ {'name': 'cache', 'options': {'ttl': 10000}}
937
+ ], server: rec.server);
938
+ await h.op({'op': 'load', 'path': '/y'});
939
+ await h.op({'op': 'load', 'path': '/y'});
940
+ equal(1, rec.calls.length);
941
+ });
942
+ });
943
+ }
944
+
945
+ if (hasFeature('ratelimit')) {
946
+ describe('ratelimit-edge', () {
947
+ test('inactive ratelimit does not wrap', (t) async {
948
+ final h = makeClient(features: [
949
+ {'name': 'ratelimit', 'options': {'active': false}}
950
+ ]);
951
+ equal(true, (await h.op({'op': 'load'}))['ok']);
952
+ });
953
+ test('real clock throttle path', (t) async {
954
+ final h = makeClient(features: [
955
+ {'name': 'ratelimit', 'options': {'rate': 1000, 'burst': 1}}
956
+ ]);
957
+ await h.op({'op': 'load'});
958
+ await h.op({'op': 'load'});
959
+ final rl = h.client.track['ratelimit'];
960
+ ok((null == rl ? 0 : rl['throttled']) >= 0);
961
+ });
962
+ });
963
+ }
964
+
965
+ if (hasFeature('proxy')) {
966
+ describe('proxy-edge', () {
967
+ test('inactive proxy does not wrap', (t) async {
968
+ final rec = recordingServer();
969
+ final h = makeClient(features: [
970
+ {'name': 'proxy', 'options': {'active': false}}
971
+ ], server: rec.server);
972
+ await h.op({'op': 'load'});
973
+ equal(null, rec.calls[0]['fetchdef']['proxy']);
974
+ });
975
+ test('no url set is a no-op', (t) async {
976
+ final rec = recordingServer();
977
+ final h = makeClient(features: [
978
+ {'name': 'proxy', 'options': {}}
979
+ ], server: rec.server);
980
+ await h.op({'op': 'load'});
981
+ equal(null, rec.calls[0]['fetchdef']['proxy']);
982
+ });
983
+ // NOTE: the donor's fromEnv case is omitted — Dart cannot mutate
984
+ // Platform.environment at runtime; fromEnv is covered by inspection.
985
+ });
986
+ }
987
+
988
+ if (hasFeature('clienttrack')) {
989
+ describe('clienttrack-edge', () {
990
+ test('real id generation without PostConstruct', (t) async {
991
+ final rec = recordingServer();
992
+ final h = makeClient(features: [
993
+ {'name': 'clienttrack'}
994
+ ], server: rec.server);
995
+ // no ready() -> PreRequest lazily creates the session id
996
+ await h.op({'op': 'load'});
997
+ ok(null != _hdr(rec, 0, 'X-Client-Id'));
998
+ });
999
+ });
1000
+ }
1001
+
1002
+ if (hasFeature('idempotency')) {
1003
+ describe('idempotency-edge', () {
1004
+ test('real key generation', (t) async {
1005
+ final rec = recordingServer();
1006
+ final h = makeClient(features: [
1007
+ {'name': 'idempotency'}
1008
+ ], server: rec.server);
1009
+ await h.op({'op': 'create', 'path': '/w'});
1010
+ ok(RegExp(r'^[0-9a-f]+$')
1011
+ .hasMatch(_hdr(rec, 0, 'Idempotency-Key').toString()));
1012
+ });
1013
+ });
1014
+ }
1015
+
1016
+ if (hasFeature('telemetry')) {
1017
+ describe('telemetry-edge', () {
1018
+ test('default id generation and no exporter', (t) async {
1019
+ final h = makeClient(features: [
1020
+ {'name': 'telemetry'}
1021
+ ]);
1022
+ await h.op({'op': 'load'});
1023
+ ok(h.client.track['telemetry']['spans'][0]['traceId']
1024
+ .toString()
1025
+ .startsWith('t'));
1026
+ });
1027
+ });
1028
+ }
1029
+
1030
+ if (hasFeature('streaming')) {
1031
+ describe('streaming-edge', () {
1032
+ test('non-list op is not streamed', (t) async {
1033
+ final h = makeClient(features: [
1034
+ {'name': 'streaming'}
1035
+ ]);
1036
+ final res = await h.op({'op': 'load'});
1037
+ equal(null, res['result'].streaming);
1038
+ });
1039
+ test('real chunk delay path', (t) async {
1040
+ final rec = recordingServer((n, f) => makeResponse(200, ['a', 'b']));
1041
+ final h = makeClient(features: [
1042
+ {'name': 'streaming', 'options': {'chunkDelay': 1}}
1043
+ ], server: rec.server);
1044
+ final res = await h.op({'op': 'list', 'path': '/w'});
1045
+ final seen = [];
1046
+ await for (final x in res['result'].stream()) {
1047
+ seen.add(x);
1048
+ }
1049
+ equal(2, seen.length);
1050
+ });
1051
+ });
1052
+ }
1053
+
1054
+ if (hasFeature('paging')) {
1055
+ describe('paging-edge', () {
1056
+ test('non-list op is not paged', (t) async {
1057
+ final rec = recordingServer();
1058
+ final h = makeClient(features: [
1059
+ {'name': 'paging'}
1060
+ ], server: rec.server);
1061
+ await h.op({'op': 'load', 'path': '/w/1'});
1062
+ ok(!RegExp(r'[?&]page=').hasMatch(rec.calls[0]['url'].toString()));
1063
+ });
1064
+ });
1065
+ }
1066
+
1067
+ if (hasFeature('metrics')) {
1068
+ describe('metrics-edge', () {
1069
+ test('real clock timing path', (t) async {
1070
+ final h = makeClient(features: [
1071
+ {'name': 'metrics'}
1072
+ ]);
1073
+ await h.op({'op': 'load'});
1074
+ equal(1, h.client.track['metrics']['total']['count']);
1075
+ });
1076
+ });
1077
+ }
1078
+
1079
+ if (hasFeature('audit')) {
1080
+ describe('audit-edge', () {
1081
+ test('default actor + real clock', (t) async {
1082
+ final h = makeClient(features: [
1083
+ {'name': 'audit'}
1084
+ ]);
1085
+ await h.op({'op': 'load'});
1086
+ equal('anonymous', h.client.track['audit']['records'][0]['actor']);
1087
+ });
1088
+ });
1089
+ }
1090
+
1091
+ if (hasFeature('debug')) {
1092
+ describe('debug-edge', () {
1093
+ test('default max ring + real clock', (t) async {
1094
+ final h = makeClient(features: [
1095
+ {'name': 'debug'}
1096
+ ]);
1097
+ await h.op({'op': 'load'});
1098
+ ok(h.client.track['debug']['entries'][0]['durationMs'] >= 0);
1099
+ });
1100
+ });
1101
+ }
1102
+
1103
+ // --- injectable option branches (coverage) --------------------------------
1104
+ // Exercise the injected id/clock callbacks (the default paths are covered
1105
+ // elsewhere).
1106
+
1107
+ if (hasFeature('telemetry')) {
1108
+ test('telemetry: injected idgen + clock', (t) async {
1109
+ final h = makeClient(features: [
1110
+ {
1111
+ 'name': 'telemetry',
1112
+ 'options': {'idgen': (k) => k.toString() + '-X', 'now': () => 5}
1113
+ }
1114
+ ]);
1115
+ await h.op({'op': 'load'});
1116
+ final span = h.client.track['telemetry']['spans'][0];
1117
+ equal('trace-X', span['traceId']);
1118
+ equal(0, span['durationMs']);
1119
+ });
1120
+ }
1121
+
1122
+ if (hasFeature('clienttrack')) {
1123
+ test('clienttrack: injected idgen + fixed session', (t) async {
1124
+ final rec = recordingServer();
1125
+ final h = makeClient(features: [
1126
+ {
1127
+ 'name': 'clienttrack',
1128
+ 'options': {'sessionId': 'S1', 'idgen': (k) => k.toString() + '-1'}
1129
+ }
1130
+ ], server: rec.server);
1131
+ await h.ready();
1132
+ await h.op({'op': 'load'});
1133
+ equal('S1', _hdr(rec, 0, 'X-Client-Id'));
1134
+ equal('request-1', _hdr(rec, 0, 'X-Request-Id'));
1135
+ });
1136
+ }
1137
+
1138
+ if (hasFeature('audit')) {
1139
+ test('audit: injected clock', (t) async {
1140
+ final h = makeClient(features: [
1141
+ {'name': 'audit', 'options': {'now': () => 42}}
1142
+ ]);
1143
+ await h.op({'op': 'load'});
1144
+ equal(42, h.client.track['audit']['records'][0]['ts']);
1145
+ });
1146
+ }
1147
+
1148
+ if (hasFeature('metrics')) {
1149
+ test('metrics: injected clock', (t) async {
1150
+ var tt = 0;
1151
+ final h = makeClient(features: [
1152
+ {'name': 'metrics', 'options': {'now': () => (tt += 10)}}
1153
+ ]);
1154
+ await h.op({'op': 'load'});
1155
+ ok(h.client.track['metrics']['total']['totalMs'] >= 0);
1156
+ });
1157
+ }
1158
+
1159
+ if (hasFeature('debug')) {
1160
+ test('debug: injected clock + custom redact', (t) async {
1161
+ final h = makeClient(features: [
1162
+ {
1163
+ 'name': 'debug',
1164
+ 'options': {
1165
+ 'now': () => 7,
1166
+ 'redact': ['x-secret']
1167
+ }
1168
+ }
1169
+ ]);
1170
+ await h.op({
1171
+ 'op': 'load',
1172
+ 'headers': {'x-secret': 'hide', 'x-ok': 'show'}
1173
+ });
1174
+ final e = h.client.track['debug']['entries'][0];
1175
+ equal('<redacted>', e['headers']['x-secret']);
1176
+ equal('show', e['headers']['x-ok']);
1177
+ });
1178
+ }
1179
+
1180
+ // --- composition ----------------------------------------------------------
1181
+ if (hasFeature('cache') && hasFeature('netsim')) {
1182
+ test('cache + netsim: a hit skips the simulated failure', (t) async {
1183
+ final h = makeClient(features: [
1184
+ {'name': 'netsim', 'options': {'failEvery': 2}},
1185
+ {'name': 'cache', 'options': {'ttl': 10000}},
1186
+ ]);
1187
+ equal(true, (await h.op({'op': 'load', 'path': '/w'}))['ok']);
1188
+ equal(true, (await h.op({'op': 'load', 'path': '/w'}))['ok']);
1189
+ equal(1, h.client.track['netsim']['calls']);
1190
+ });
1191
+ }
1192
+ });
1193
+ }