@voxgig/sdkgen 4.8.2 → 4.8.3
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.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/action/doctor.d.ts +1 -0
- package/dist/action/doctor.js +50 -2
- package/dist/action/doctor.js.map +1 -1
- package/dist/helpers/naming.js +4 -2
- package/dist/helpers/naming.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aon +21 -0
- package/package.json +1 -1
- package/project/.sdk/model/feature/secrets.aon +120 -18
- package/project/.sdk/model/target/c.aon +10 -0
- package/project/.sdk/model/target/clojure.aon +13 -0
- package/project/.sdk/model/target/cpp.aon +10 -0
- package/project/.sdk/model/target/csharp.aon +9 -0
- package/project/.sdk/model/target/dart.aon +10 -0
- package/project/.sdk/model/target/elixir.aon +9 -0
- package/project/.sdk/model/target/go.aon +13 -0
- package/project/.sdk/model/target/java.aon +9 -0
- package/project/.sdk/model/target/js.aon +7 -0
- package/project/.sdk/model/target/kotlin.aon +9 -0
- package/project/.sdk/model/target/lean.aon +17 -0
- package/project/.sdk/model/target/lua.aon +8 -0
- package/project/.sdk/model/target/ocaml.aon +9 -0
- package/project/.sdk/model/target/perl.aon +8 -0
- package/project/.sdk/model/target/php.aon +8 -0
- package/project/.sdk/model/target/py.aon +13 -0
- package/project/.sdk/model/target/rb.aon +8 -0
- package/project/.sdk/model/target/rust.aon +10 -0
- package/project/.sdk/model/target/scala.aon +21 -2
- package/project/.sdk/model/target/swift.aon +18 -0
- package/project/.sdk/model/target/ts.aon +13 -0
- package/project/.sdk/src/cmp/clojure/Package_clojure.ts +9 -2
- package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +3 -0
- package/project/.sdk/src/cmp/dart/Test_dart.ts +2 -0
- package/project/.sdk/src/cmp/elixir/Package_elixir.ts +4 -1
- package/project/.sdk/src/cmp/go/Config_go.ts +59 -2
- package/project/.sdk/src/cmp/go/Main_go.ts +8 -2
- package/project/.sdk/src/cmp/java/Test_java.ts +6 -5
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +6 -5
- package/project/.sdk/src/cmp/lean/Package_lean.ts +23 -0
- package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +1 -0
- package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +1 -0
- package/project/.sdk/src/cmp/ocaml/Gitignore_ocaml.ts +1 -0
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +7 -3
- package/project/.sdk/src/cmp/py/Config_py.ts +82 -1
- package/project/.sdk/src/cmp/py/Main_py.ts +44 -0
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +2 -0
- package/project/.sdk/src/cmp/swift/Main_swift.ts +10 -0
- package/project/.sdk/src/cmp/swift/Package_swift.ts +13 -1
- package/project/.sdk/src/cmp/ts/Config_ts.ts +42 -17
- package/project/.sdk/src/cmp/ts/fragment/Config.data.fragment.ts +13 -1
- package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +13 -1
- package/project/.sdk/tm/c/Makefile +38 -3
- package/project/.sdk/tm/c/tests/omni_resolver.h +361 -0
- package/project/.sdk/tm/c/tests/omni_smoke_test.c +237 -0
- package/project/.sdk/tm/c/tests/primary_corpus_test.c +205 -284
- package/project/.sdk/tm/c/tests/struct_corpus_test.c +292 -212
- package/project/.sdk/tm/c/tests/vendor/omni/json.c +811 -0
- package/project/.sdk/tm/c/tests/vendor/omni/omni.h +240 -0
- package/project/.sdk/tm/c/tests/vendor/omni/runner.c +940 -0
- package/project/.sdk/tm/c/tests/vendor/omni/util.c +351 -0
- package/project/.sdk/tm/c/utility/struct/utility.c +7 -2
- package/project/.sdk/tm/clojure/test/sdk/test/omni.clj +401 -0
- package/project/.sdk/tm/clojure/test/sdk/test/omni_smoke.clj +81 -0
- package/project/.sdk/tm/clojure/test/sdk/test/primary.clj +92 -58
- package/project/.sdk/tm/clojure/test/sdk/test/struct_corpus.clj +122 -149
- package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +8 -3
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +145 -0
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +445 -0
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +145 -0
- package/project/.sdk/tm/cpp/Makefile +5 -1
- package/project/.sdk/tm/cpp/test/omni_resolver.hpp +473 -0
- package/project/.sdk/tm/cpp/test/omni_smoke_test.cpp +209 -0
- package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +243 -184
- package/project/.sdk/tm/cpp/test/runner_support.hpp +68 -181
- package/project/.sdk/tm/cpp/test/struct_corpus_test.cpp +183 -56
- package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +406 -0
- package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +751 -0
- package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +256 -0
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +7 -1
- package/project/.sdk/tm/csharp/test/OmniResolver.cs +491 -0
- package/project/.sdk/tm/csharp/test/OmniSmokeTest.cs +106 -0
- package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +299 -316
- package/project/.sdk/tm/csharp/test/Runner.cs +104 -269
- package/project/.sdk/tm/csharp/test/StructUtilityTest.cs +535 -724
- package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +864 -0
- package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +347 -0
- package/project/.sdk/tm/csharp/utility/MakeSpec.cs +3 -1
- package/project/.sdk/tm/csharp/utility/PrepareMethod.cs +6 -1
- package/project/.sdk/tm/csharp/utility/struct/Struct.cs +21 -5
- package/project/.sdk/tm/dart/test/omni.dart +520 -0
- package/project/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
- package/project/.sdk/tm/dart/test/primary_test.dart +86 -28
- package/project/.sdk/tm/dart/test/struct_test.dart +438 -11
- package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
- package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
- package/project/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
- package/project/.sdk/tm/elixir/Makefile +11 -3
- package/project/.sdk/tm/elixir/test/omni_smoke_test.exs +117 -0
- package/project/.sdk/tm/elixir/test/primary_utility_test.exs +341 -16
- package/project/.sdk/tm/elixir/test/struct_corpus_test.exs +554 -9
- package/project/.sdk/tm/elixir/test/support/omni.ex +377 -0
- package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +122 -0
- package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +623 -0
- package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +187 -0
- package/project/.sdk/tm/go/core/context.go +32 -16
- package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +261 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +78 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/config.go +652 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +250 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/env.go +194 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/export.go +80 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +238 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1575 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/order.go +248 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/point.go +184 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +123 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +79 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/types.go +296 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/util.go +87 -0
- package/project/.sdk/tm/go/feature/secrets/plugin/version.go +161 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +292 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +201 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +187 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +184 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +114 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +156 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +209 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +241 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +151 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +152 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +143 -0
- package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +120 -0
- package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +439 -0
- package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +685 -0
- package/project/.sdk/tm/go/feature/secrets_feature.go +675 -0
- package/project/.sdk/tm/go/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +799 -0
- package/project/.sdk/tm/go/test/omni/omni.go +897 -0
- package/project/.sdk/tm/go/test/omni/util.go +360 -0
- package/project/.sdk/tm/go/test/omniresolver_test.go +748 -0
- package/project/.sdk/tm/go/test/omnismoke_test.go +112 -0
- package/project/.sdk/tm/go/test/primary_utility_test.go +123 -191
- package/project/.sdk/tm/go/test/struct_utility_test.go +323 -16
- package/project/.sdk/tm/go/test/testsupport_test.go +294 -0
- package/project/.sdk/tm/go/utility/make_options.go +8 -1
- package/project/.sdk/tm/go/utility/prepare_method.go +5 -1
- package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +2 -2
- package/project/.sdk/tm/java/test/OmniResolver.java +355 -0
- package/project/.sdk/tm/java/test/OmniSmokeTest.java +99 -0
- package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +254 -280
- package/project/.sdk/tm/java/test/RunnerSupport.java +9 -194
- package/project/.sdk/tm/java/test/StructCorpusTest.java +119 -42
- package/project/.sdk/tm/java/test/vendor/omni/Json.java +287 -0
- package/project/.sdk/tm/java/test/vendor/omni/Runner.java +851 -0
- package/project/.sdk/tm/java/test/vendor/omni/Util.java +322 -0
- package/project/.sdk/tm/java/utility/MakeSpec.java +3 -1
- package/project/.sdk/tm/java/utility/PrepareMethod.java +5 -5
- package/project/.sdk/tm/java/utility/struct/Struct.java +17 -4
- package/project/.sdk/tm/js/src/utility/StructUtility.js +3 -3
- package/project/.sdk/tm/js/test/omni.js +251 -0
- package/project/.sdk/tm/js/test/omni.test.js +105 -0
- package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +6 -2
- package/project/.sdk/tm/js/test/utility/StructUtility.test.js +27 -2
- package/project/.sdk/tm/js/test/vendor/omni/index.js +77 -0
- package/project/.sdk/tm/js/test/vendor/omni/runner.js +613 -0
- package/project/.sdk/tm/js/test/vendor/omni/util.js +212 -0
- package/project/.sdk/tm/kotlin/core/Utility.kt +1 -1
- package/project/.sdk/tm/kotlin/test/OmniResolver.kt +343 -0
- package/project/.sdk/tm/kotlin/test/OmniSmokeTest.kt +100 -0
- package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +244 -262
- package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +9 -178
- package/project/.sdk/tm/kotlin/test/StructCorpusTest.kt +121 -32
- package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +264 -0
- package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +615 -0
- package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +139 -0
- package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +6 -3
- package/project/.sdk/tm/kotlin/utility/Prepare.kt +6 -6
- package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +18 -2
- package/project/.sdk/tm/lean/Makefile +12 -5
- package/project/.sdk/tm/lean/src/SdkUtility.lean +14 -1
- package/project/.sdk/tm/lean/test/OmniResolver.lean +358 -0
- package/project/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
- package/project/.sdk/tm/lean/test/StructCorpus.lean +245 -574
- package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +155 -291
- package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
- package/project/.sdk/tm/lua/test/omni.lua +456 -0
- package/project/.sdk/tm/lua/test/omni_smoke_test.lua +103 -0
- package/project/.sdk/tm/lua/test/primary_utility_test.lua +250 -509
- package/project/.sdk/tm/lua/test/struct_utility_test.lua +161 -70
- package/project/.sdk/tm/lua/test/vendor/omni/json.lua +268 -0
- package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +385 -0
- package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +641 -0
- package/project/.sdk/tm/lua/test/vendor/omni/util.lua +282 -0
- package/project/.sdk/tm/lua/utility/prepare_method.lua +5 -1
- package/project/.sdk/tm/lua/utility/struct/regex.lua +663 -0
- package/project/.sdk/tm/lua/utility/struct/struct.lua +660 -420
- package/project/.sdk/tm/ocaml/Makefile +37 -12
- package/project/.sdk/tm/ocaml/test/omni_resolver.ml +284 -0
- package/project/.sdk/tm/ocaml/test/omni_smoke_test.ml +169 -0
- package/project/.sdk/tm/ocaml/test/primary_utility_test.ml +84 -100
- package/project/.sdk/tm/ocaml/test/struct_corpus.ml +225 -201
- package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +1157 -0
- package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +88 -12
- package/project/.sdk/tm/perl/t/omni.pm +647 -0
- package/project/.sdk/tm/perl/t/omni_smoke.t +87 -0
- package/project/.sdk/tm/perl/t/primary_utility.t +189 -487
- package/project/.sdk/tm/perl/t/struct_utility.t +455 -389
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +649 -0
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +253 -0
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +24 -0
- package/project/.sdk/tm/perl/utility/prepare_method.pm +7 -2
- package/project/.sdk/tm/php/test/Omni.php +691 -0
- package/project/.sdk/tm/php/test/OmniSmokeTest.php +93 -0
- package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +210 -571
- package/project/.sdk/tm/php/test/StructUtilityTest.php +320 -342
- package/project/.sdk/tm/php/test/vendor/omni/Runner.php +644 -0
- package/project/.sdk/tm/php/test/vendor/omni/Util.php +283 -0
- package/project/.sdk/tm/php/utility/MakeSpec.php +10 -3
- package/project/.sdk/tm/php/utility/PrepareBody.php +7 -1
- package/project/.sdk/tm/php/utility/PrepareMethod.php +6 -2
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +36 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +141 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +50 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +333 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +198 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +147 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +52 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +139 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1053 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +171 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +95 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +116 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +59 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +87 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +112 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +74 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +116 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +192 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +120 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +140 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +62 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +101 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +152 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +115 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +92 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +101 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +119 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +125 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +211 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +455 -0
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +467 -0
- package/project/.sdk/tm/py/pkg/utility/prepare_method.py +5 -1
- package/project/.sdk/tm/py/pkg/utility/voxgig_struct/__init__.py +0 -2
- package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +780 -529
- package/project/.sdk/tm/py/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/py/test/feature/__init__.py +0 -0
- package/project/.sdk/tm/py/test/feature/secrets/__init__.py +0 -0
- package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +337 -0
- package/project/.sdk/tm/py/test/omni.py +415 -0
- package/project/.sdk/tm/py/test/test_omni_smoke.py +74 -0
- package/project/.sdk/tm/py/test/test_primary_utility.py +144 -668
- package/project/.sdk/tm/py/test/test_struct_utility.py +74 -27
- package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +62 -0
- package/project/.sdk/tm/py/test/voxgig_omni/runner.py +566 -0
- package/project/.sdk/tm/py/test/voxgig_omni/util.py +237 -0
- package/project/.sdk/tm/rb/test/omni.rb +505 -0
- package/project/.sdk/tm/rb/test/omni_smoke_test.rb +72 -0
- package/project/.sdk/tm/rb/test/primary_utility_test.rb +174 -560
- package/project/.sdk/tm/rb/test/struct_utility_test.rb +13 -7
- package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +493 -0
- package/project/.sdk/tm/rb/test/vendor/omni/util.rb +199 -0
- package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +15 -0
- package/project/.sdk/tm/rb/utility/prepare_method.rb +5 -1
- package/project/.sdk/tm/rust/tests/common/mod.rs +19 -242
- package/project/.sdk/tm/rust/tests/omni_resolver/mod.rs +888 -0
- package/project/.sdk/tm/rust/tests/omni_smoke_test.rs +286 -0
- package/project/.sdk/tm/rust/tests/primary_utility_test.rs +318 -312
- package/project/.sdk/tm/rust/tests/struct_utility_test.rs +66 -28
- package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +412 -0
- package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +38 -0
- package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +392 -0
- package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +1001 -0
- package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +161 -0
- package/project/.sdk/tm/rust/utility/prepare_method.rs +5 -1
- package/project/.sdk/tm/scala/Makefile +16 -6
- package/project/.sdk/tm/scala/sdktest/OmniResolver.scala +497 -0
- package/project/.sdk/tm/scala/sdktest/OmniSmoke.scala +192 -0
- package/project/.sdk/tm/scala/sdktest/PrimaryCorpus.scala +47 -19
- package/project/.sdk/tm/scala/sdktest/StructCorpus.scala +0 -0
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +229 -0
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +552 -0
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +104 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Constants.swift +10 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Inject.swift +28 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Injection.swift +5 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Minor.swift +4 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Validate.swift +15 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +6 -1
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniResolver.swift +474 -0
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniSmokeTest.swift +107 -0
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +141 -178
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/Runner.swift +17 -113
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/StructUtilityTest.swift +295 -446
- package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +364 -0
- package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +730 -0
- package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +162 -0
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +7 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +148 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +55 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +344 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +205 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +138 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +46 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +349 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +181 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1132 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +177 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +119 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +102 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +61 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +112 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +100 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +37 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +163 -30
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +27 -22
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/aws.ts +26 -36
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/azuresecrets.ts +19 -21
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/boru.ts +36 -17
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/doppler.ts +14 -21
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/gcpsecrets.ts +27 -27
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/hashicorp.ts +25 -39
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +99 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/infisical.ts +14 -16
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/onepassword.ts +15 -22
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +98 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{Sigv4.ts → plugins/sigv4.ts} +7 -6
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +97 -23
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +37 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +4 -17
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +4 -16
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +11 -25
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +6 -23
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +106 -39
- package/project/.sdk/tm/ts/src/utility/StructUtility.ts +3 -3
- package/project/.sdk/tm/ts/test/omni.ts +104 -32
- package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +27 -0
- package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +32 -5
- package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +2 -2
- package/project/.sdk/tm/ts/test/vendor/omni/index.ts +2 -2
- package/project/.sdk/tm/zig/test/primary_utility_test.zig +1 -1
- package/project/.sdk/tm/zig/test/struct_runner.zig +5 -4
- package/project/sdkgen-package.json +1 -1
- package/src/action/doctor.ts +66 -2
- package/src/helpers/naming.ts +4 -2
- package/project/.sdk/tm/c/tests/runner.h +0 -274
- package/project/.sdk/tm/cpp/test/struct_runner.hpp +0 -314
- package/project/.sdk/tm/csharp/test/StructRunner.cs +0 -276
- package/project/.sdk/tm/dart/test/runner.dart +0 -406
- package/project/.sdk/tm/dart/test/struct_corpus.dart +0 -531
- package/project/.sdk/tm/elixir/test/support/struct_corpus.ex +0 -1088
- package/project/.sdk/tm/go/test/runner_test.go +0 -629
- package/project/.sdk/tm/go/test/struct_runner_test.go +0 -1094
- package/project/.sdk/tm/java/test/StructRunner.java +0 -281
- package/project/.sdk/tm/js/test/runner.js +0 -387
- package/project/.sdk/tm/kotlin/test/StructRunner.kt +0 -177
- package/project/.sdk/tm/lua/test/struct_runner.lua +0 -602
- package/project/.sdk/tm/ocaml/test/corpus_runner.ml +0 -185
- package/project/.sdk/tm/perl/t/struct_runner.pm +0 -275
- package/project/.sdk/tm/php/test/StructRunner.php +0 -275
- package/project/.sdk/tm/py/test/struct_runner.py +0 -411
- package/project/.sdk/tm/rb/test/struct_runner.rb +0 -309
- package/project/.sdk/tm/rust/tests/struct_runner/mod.rs +0 -424
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/Registry.ts +0 -90
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/http.ts +0 -66
- package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +0 -188
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// Drives the shared struct corpus (../../.sdk/test/test.json, root key
|
|
2
|
+
// "struct") against the vendored struct utility THROUGH the vendored omni
|
|
3
|
+
// runner (OmniResolver over test/vendor/omni) - the engine half of the
|
|
4
|
+
// retired StructRunner. Mirrors tm/go/test/struct_utility_test.go.
|
|
5
|
+
// A missing category or section FAILS (the old runner skipped it silently
|
|
6
|
+
// - a renamed fixture reported PASS while running zero assertions); a
|
|
7
|
+
// failing entry throws OmniError with the entry named.
|
|
8
|
+
//
|
|
9
|
+
// RUN: cd test && dotnet test
|
|
10
|
+
// RUN-SOME: dotnet test --filter "DisplayName~MinorIsNode"
|
|
5
11
|
|
|
6
12
|
using Voxgig.Struct;
|
|
7
13
|
using Xunit;
|
|
@@ -11,15 +17,105 @@ namespace ProjectNameSdk.Test;
|
|
|
11
17
|
|
|
12
18
|
public class StructUtilityTest
|
|
13
19
|
{
|
|
14
|
-
private
|
|
15
|
-
private readonly
|
|
20
|
+
private static OmniResolver.Run? RUN;
|
|
21
|
+
private static readonly object RunLock = new();
|
|
22
|
+
|
|
23
|
+
private static OmniResolver.Run StructRun()
|
|
24
|
+
{
|
|
25
|
+
lock (RunLock)
|
|
26
|
+
{
|
|
27
|
+
if (RUN == null)
|
|
28
|
+
{
|
|
29
|
+
RUN = OmniResolver.MakeRunner(StructRunner.TestJsonPath(),
|
|
30
|
+
ProjectNameSDK.TestSDK(null, null))("struct");
|
|
31
|
+
Assert.True(0 < RUN.Spec.Count,
|
|
32
|
+
"struct section not found in test.json");
|
|
33
|
+
}
|
|
34
|
+
return RUN;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// <summary>A subject in the struct-corpus shape: one argument in, one value out.</summary>
|
|
39
|
+
private delegate object? StructSubject(object? input);
|
|
40
|
+
|
|
41
|
+
private static object? Getp(object? input, string key)
|
|
42
|
+
{
|
|
43
|
+
return input is Dictionary<string, object?> m && m.TryGetValue(key, out var v)
|
|
44
|
+
? v : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private static object? GetpDef(object? input, string key, object? def)
|
|
48
|
+
{
|
|
49
|
+
return input is Dictionary<string, object?> m && m.ContainsKey(key)
|
|
50
|
+
? m[key] : def;
|
|
51
|
+
}
|
|
16
52
|
|
|
17
|
-
|
|
53
|
+
private static int? IntArg(object? val)
|
|
54
|
+
=> val == null ? null : (int?)Convert.ToInt32(val);
|
|
55
|
+
|
|
56
|
+
// Run one corpus section, failing loudly when a category or section is
|
|
57
|
+
// missing or EMPTY - a renamed fixture must not report PASS while
|
|
58
|
+
// running zero assertions.
|
|
59
|
+
private static void RunStruct(string category, string name, bool nullFlag,
|
|
60
|
+
StructSubject subject)
|
|
18
61
|
{
|
|
19
|
-
|
|
20
|
-
|
|
62
|
+
var run = StructRun();
|
|
63
|
+
var cat = run.Spec.TryGetValue(category, out var c)
|
|
64
|
+
? c as Dictionary<string, object?> : null;
|
|
65
|
+
Assert.True(null != cat, "struct corpus category missing: " + category +
|
|
66
|
+
" - check .sdk/test/struct/");
|
|
67
|
+
var spec = cat!.TryGetValue(name, out var s)
|
|
68
|
+
? s as Dictionary<string, object?> : null;
|
|
69
|
+
Assert.True(null != spec, "struct corpus section missing: " + category +
|
|
70
|
+
"." + name + " - check .sdk/test/struct/");
|
|
71
|
+
var set = spec!.TryGetValue("set", out var sv) ? sv as List<object?> : null;
|
|
72
|
+
Assert.True(set != null && 0 < set.Count,
|
|
73
|
+
"struct corpus section is EMPTY: " + category + "." + name +
|
|
74
|
+
" - zero cases would run");
|
|
75
|
+
run.RunSetFlags(spec, new Dictionary<string, bool> { ["null"] = nullFlag },
|
|
76
|
+
args => subject(0 < args.Length ? args[0] : StructUtils.NONE));
|
|
21
77
|
}
|
|
22
78
|
|
|
79
|
+
private static Dictionary<string, object?> Section(string category, string name)
|
|
80
|
+
{
|
|
81
|
+
var run = StructRun();
|
|
82
|
+
var cat = run.Spec.TryGetValue(category, out var c)
|
|
83
|
+
? c as Dictionary<string, object?> : null;
|
|
84
|
+
Assert.True(null != cat, "struct corpus category missing: " + category);
|
|
85
|
+
var spec = cat!.TryGetValue(name, out var s)
|
|
86
|
+
? s as Dictionary<string, object?> : null;
|
|
87
|
+
Assert.True(null != spec,
|
|
88
|
+
"struct corpus section missing: " + category + "." + name);
|
|
89
|
+
return spec!;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// The struct-corpus nullModifier (was the old runner's ad-hoc handling):
|
|
93
|
+
// a bare "__NULL__" becomes a real null, and an embedded "__NULL__"
|
|
94
|
+
// inside a larger string is rewritten to the literal text "null".
|
|
95
|
+
// Mirrors omni's NullModifier for struct's own Modify callback shape.
|
|
96
|
+
private static readonly Modify NullModifier = (val, key, parent, inj, store) =>
|
|
97
|
+
{
|
|
98
|
+
if (val is not string text)
|
|
99
|
+
{
|
|
100
|
+
return val;
|
|
101
|
+
}
|
|
102
|
+
object? repl;
|
|
103
|
+
if (OmniResolver.NULLMARK == text)
|
|
104
|
+
{
|
|
105
|
+
repl = null;
|
|
106
|
+
}
|
|
107
|
+
else if (text.Contains(OmniResolver.NULLMARK))
|
|
108
|
+
{
|
|
109
|
+
repl = text.Replace(OmniResolver.NULLMARK, "null");
|
|
110
|
+
}
|
|
111
|
+
else
|
|
112
|
+
{
|
|
113
|
+
return val;
|
|
114
|
+
}
|
|
115
|
+
StructUtils.SetProp(parent, key, repl);
|
|
116
|
+
return repl;
|
|
117
|
+
};
|
|
118
|
+
|
|
23
119
|
|
|
24
120
|
// ========================================================================
|
|
25
121
|
// minor-exists: verify all expected functions exist
|
|
@@ -59,59 +155,49 @@ public class StructUtilityTest
|
|
|
59
155
|
|
|
60
156
|
|
|
61
157
|
// ========================================================================
|
|
62
|
-
// Minor utility tests (driven from test.json)
|
|
158
|
+
// Minor utility tests (driven from test.json through the resolver)
|
|
63
159
|
// ========================================================================
|
|
64
160
|
|
|
65
161
|
[Fact]
|
|
66
162
|
public void MinorIsNode()
|
|
67
163
|
{
|
|
68
|
-
|
|
69
|
-
StructUtils.IsNode(input));
|
|
164
|
+
RunStruct("minor", "isnode", true, input => StructUtils.IsNode(input));
|
|
70
165
|
}
|
|
71
166
|
|
|
72
167
|
[Fact]
|
|
73
168
|
public void MinorIsMap()
|
|
74
169
|
{
|
|
75
|
-
|
|
76
|
-
StructUtils.IsMap(input));
|
|
170
|
+
RunStruct("minor", "ismap", true, input => StructUtils.IsMap(input));
|
|
77
171
|
}
|
|
78
172
|
|
|
79
173
|
[Fact]
|
|
80
174
|
public void MinorIsList()
|
|
81
175
|
{
|
|
82
|
-
|
|
83
|
-
StructUtils.IsList(input));
|
|
176
|
+
RunStruct("minor", "islist", true, input => StructUtils.IsList(input));
|
|
84
177
|
}
|
|
85
178
|
|
|
86
179
|
[Fact]
|
|
87
180
|
public void MinorIsKey()
|
|
88
181
|
{
|
|
89
|
-
|
|
90
|
-
input => StructUtils.IsKey(input),
|
|
91
|
-
flags: new() { ["null"] = false });
|
|
182
|
+
RunStruct("minor", "iskey", false, input => StructUtils.IsKey(input));
|
|
92
183
|
}
|
|
93
184
|
|
|
94
185
|
[Fact]
|
|
95
186
|
public void MinorStrKey()
|
|
96
187
|
{
|
|
97
|
-
|
|
98
|
-
input => StructUtils.StrKey(input),
|
|
99
|
-
flags: new() { ["null"] = false });
|
|
188
|
+
RunStruct("minor", "strkey", false, input => StructUtils.StrKey(input));
|
|
100
189
|
}
|
|
101
190
|
|
|
102
191
|
[Fact]
|
|
103
192
|
public void MinorIsEmpty()
|
|
104
193
|
{
|
|
105
|
-
|
|
106
|
-
input => StructUtils.IsEmpty(input),
|
|
107
|
-
flags: new() { ["null"] = false });
|
|
194
|
+
RunStruct("minor", "isempty", false, input => StructUtils.IsEmpty(input));
|
|
108
195
|
}
|
|
109
196
|
|
|
110
197
|
[Fact]
|
|
111
198
|
public void MinorIsFunc()
|
|
112
199
|
{
|
|
113
|
-
|
|
114
|
-
input => StructUtils.IsFunc(input));
|
|
200
|
+
RunStruct("minor", "isfunc", true, input => StructUtils.IsFunc(input));
|
|
115
201
|
|
|
116
202
|
// Edge: actual delegates should be recognised.
|
|
117
203
|
Func<object?> f0 = () => null;
|
|
@@ -122,9 +208,7 @@ public class StructUtilityTest
|
|
|
122
208
|
[Fact]
|
|
123
209
|
public void MinorClone()
|
|
124
210
|
{
|
|
125
|
-
|
|
126
|
-
input => StructUtils.Clone(input),
|
|
127
|
-
flags: new() { ["null"] = false });
|
|
211
|
+
RunStruct("minor", "clone", false, input => StructUtils.Clone(input));
|
|
128
212
|
|
|
129
213
|
// Edge: functions should be shallow-copied, not cloned.
|
|
130
214
|
Func<object?> f0 = () => null;
|
|
@@ -137,83 +221,92 @@ public class StructUtilityTest
|
|
|
137
221
|
[Fact]
|
|
138
222
|
public void MinorEscRe()
|
|
139
223
|
{
|
|
140
|
-
|
|
141
|
-
input => StructUtils.EscRe(input as string));
|
|
224
|
+
RunStruct("minor", "escre", true, input => StructUtils.EscRe(input as string));
|
|
142
225
|
}
|
|
143
226
|
|
|
144
227
|
[Fact]
|
|
145
228
|
public void MinorEscUrl()
|
|
146
229
|
{
|
|
147
|
-
|
|
148
|
-
input => StructUtils.EscUrl(input as string));
|
|
230
|
+
RunStruct("minor", "escurl", true, input => StructUtils.EscUrl(input as string));
|
|
149
231
|
}
|
|
150
232
|
|
|
151
233
|
[Fact]
|
|
152
234
|
public void MinorStringify()
|
|
153
235
|
{
|
|
154
|
-
|
|
236
|
+
RunStruct("minor", "stringify", false, input =>
|
|
155
237
|
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (val is string s && s == StructRunner.NULLMARK) val = null;
|
|
163
|
-
|
|
164
|
-
if (m.TryGetValue("max", out object? maxObj) && maxObj != null)
|
|
165
|
-
return StructUtils.Stringify(val, (int)Convert.ToInt64(maxObj));
|
|
166
|
-
|
|
167
|
-
return StructUtils.Stringify(val);
|
|
238
|
+
// null:false keeps a JSON-null val as a real null (rendered
|
|
239
|
+
// "null"); an absent val is NONE (rendered ""). Mirrors the
|
|
240
|
+
// canonical harness.
|
|
241
|
+
var val = GetpDef(input, "val", StructUtils.NONE);
|
|
242
|
+
var max = Getp(input, "max");
|
|
243
|
+
return StructUtils.Stringify(val, IntArg(max));
|
|
168
244
|
});
|
|
169
245
|
}
|
|
170
246
|
|
|
171
247
|
[Fact]
|
|
172
|
-
public void
|
|
248
|
+
public void MinorJsonify()
|
|
173
249
|
{
|
|
174
|
-
|
|
175
|
-
|
|
250
|
+
RunStruct("minor", "jsonify", false, input =>
|
|
251
|
+
{
|
|
252
|
+
var val = Getp(input, "val");
|
|
253
|
+
if (Getp(input, "flags") is Dictionary<string, object?> flags)
|
|
176
254
|
{
|
|
177
|
-
var
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
int from = 0;
|
|
187
|
-
if (m.TryGetValue("from", out object? fv) && fv != null)
|
|
188
|
-
from = (int)Convert.ToInt64(fv);
|
|
255
|
+
var indent = flags.TryGetValue("indent", out var iv) && iv != null
|
|
256
|
+
? Convert.ToInt32(iv) : 2;
|
|
257
|
+
var offset = flags.TryGetValue("offset", out var ov) && ov != null
|
|
258
|
+
? Convert.ToInt32(ov) : 0;
|
|
259
|
+
return StructUtils.Jsonify(val, indent, offset);
|
|
260
|
+
}
|
|
261
|
+
return StructUtils.Jsonify(val);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
189
264
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
265
|
+
[Fact]
|
|
266
|
+
public void MinorPathify()
|
|
267
|
+
{
|
|
268
|
+
RunStruct("minor", "pathify", false, input =>
|
|
269
|
+
{
|
|
270
|
+
// null:false keeps a JSON-null path as a real null
|
|
271
|
+
// ("<unknown-path:null>") and an absent path as NONE
|
|
272
|
+
// ("<unknown-path>"); null parts are dropped.
|
|
273
|
+
var path = GetpDef(input, "path", StructUtils.NONE);
|
|
274
|
+
var from = IntArg(Getp(input, "from"));
|
|
275
|
+
var to = IntArg(Getp(input, "to"));
|
|
276
|
+
return null == to
|
|
277
|
+
? (null == from
|
|
278
|
+
? StructUtils.Pathify(path)
|
|
279
|
+
: StructUtils.Pathify(path, from.Value))
|
|
280
|
+
: StructUtils.Pathify(path, from ?? 0, to.Value);
|
|
281
|
+
});
|
|
193
282
|
}
|
|
194
283
|
|
|
195
284
|
[Fact]
|
|
196
285
|
public void MinorItems()
|
|
197
286
|
{
|
|
198
|
-
|
|
199
|
-
input => StructUtils.Items(input));
|
|
287
|
+
RunStruct("minor", "items", true, input => StructUtils.Items(input));
|
|
200
288
|
}
|
|
201
289
|
|
|
202
290
|
[Fact]
|
|
203
291
|
public void MinorGetProp()
|
|
204
292
|
{
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
293
|
+
RunStruct("minor", "getprop", false, input =>
|
|
294
|
+
{
|
|
295
|
+
var val = Getp(input, "val");
|
|
296
|
+
var key = Getp(input, "key");
|
|
297
|
+
// Canonical's default alt is `undefined`, so the no-alt call has
|
|
298
|
+
// to ask for NONE explicitly: `GetProp(val, key)` defaults `alt`
|
|
299
|
+
// to null, which answers "null" where canonical answers
|
|
300
|
+
// "undefined", and under `null: false` the corpus tells them
|
|
301
|
+
// apart. It also omits `alt` only when the KEY is missing
|
|
302
|
+
// (`undefined === vin.alt`), so an explicit `alt: null` is
|
|
303
|
+
// passed through - unlike getelem below, which omits a null alt
|
|
304
|
+
// too (`null == vin.alt`). (The struct repo's own C# suite binds
|
|
305
|
+
// it the same way.)
|
|
306
|
+
if (input is Dictionary<string, object?> m && m.ContainsKey("alt"))
|
|
307
|
+
return StructUtils.GetProp(val, key, m["alt"]);
|
|
308
|
+
return StructUtils.GetProp(val, key, StructUtils.NONE);
|
|
309
|
+
});
|
|
217
310
|
}
|
|
218
311
|
|
|
219
312
|
[Fact]
|
|
@@ -228,34 +321,28 @@ public class StructUtilityTest
|
|
|
228
321
|
[Fact]
|
|
229
322
|
public void MinorGetElem()
|
|
230
323
|
{
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
},
|
|
242
|
-
flags: new() { ["null"] = false });
|
|
324
|
+
RunStruct("minor", "getelem", false, input =>
|
|
325
|
+
{
|
|
326
|
+
var val = Getp(input, "val");
|
|
327
|
+
var key = Getp(input, "key");
|
|
328
|
+
// Canonical's default alt is `undefined`; see MinorGetProp.
|
|
329
|
+
var alt = Getp(input, "alt");
|
|
330
|
+
return null != alt
|
|
331
|
+
? StructUtils.GetElem(val, key, alt)
|
|
332
|
+
: StructUtils.GetElem(val, key, StructUtils.NONE);
|
|
333
|
+
});
|
|
243
334
|
}
|
|
244
335
|
|
|
245
336
|
[Fact]
|
|
246
337
|
public void MinorSetProp()
|
|
247
338
|
{
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
object? val = m.TryGetValue("val", out object? vv) ? vv : null;
|
|
256
|
-
return StructUtils.SetProp(parent, key, val);
|
|
257
|
-
},
|
|
258
|
-
flags: new() { ["null"] = true });
|
|
339
|
+
RunStruct("minor", "setprop", true, input =>
|
|
340
|
+
{
|
|
341
|
+
var parent = Getp(input, "parent");
|
|
342
|
+
var key = Getp(input, "key");
|
|
343
|
+
var val = Getp(input, "val");
|
|
344
|
+
return StructUtils.SetProp(parent, key, val);
|
|
345
|
+
});
|
|
259
346
|
}
|
|
260
347
|
|
|
261
348
|
[Fact]
|
|
@@ -274,121 +361,25 @@ public class StructUtilityTest
|
|
|
274
361
|
[Fact]
|
|
275
362
|
public void MinorDelProp()
|
|
276
363
|
{
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
object? key = m.TryGetValue("key", out object? kv) ? kv : null;
|
|
284
|
-
return StructUtils.DelProp(parent, key);
|
|
285
|
-
},
|
|
286
|
-
flags: new() { ["null"] = true });
|
|
364
|
+
RunStruct("minor", "delprop", true, input =>
|
|
365
|
+
{
|
|
366
|
+
var parent = Getp(input, "parent");
|
|
367
|
+
var key = Getp(input, "key");
|
|
368
|
+
return StructUtils.DelProp(parent, key);
|
|
369
|
+
});
|
|
287
370
|
}
|
|
288
371
|
|
|
289
372
|
[Fact]
|
|
290
373
|
public void MinorKeysOf()
|
|
291
374
|
{
|
|
292
|
-
|
|
293
|
-
input => StructUtils.KeysOf(input));
|
|
375
|
+
RunStruct("minor", "keysof", true, input => StructUtils.KeysOf(input));
|
|
294
376
|
}
|
|
295
377
|
|
|
296
378
|
[Fact]
|
|
297
379
|
public void MinorHasKey()
|
|
298
380
|
{
|
|
299
|
-
|
|
300
|
-
input
|
|
301
|
-
{
|
|
302
|
-
var m = input as Dictionary<string, object?>;
|
|
303
|
-
if (m == null) return false;
|
|
304
|
-
object? val = m.TryGetValue("src", out object? v) ? v : null;
|
|
305
|
-
object? key = m.TryGetValue("key", out object? k) ? k : null;
|
|
306
|
-
return StructUtils.HasKey(val, key);
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
// ========================================================================
|
|
312
|
-
// Sentinels — null / undefined unification across the readers.
|
|
313
|
-
// (Group A: a stored JSON null counts as "no value".)
|
|
314
|
-
// ========================================================================
|
|
315
|
-
|
|
316
|
-
// The sdk-vendored corpus (.sdk/test/test.json) may predate the
|
|
317
|
-
// sentinels section; the tests below no-op when it is absent
|
|
318
|
-
// (StructRunner.RunSet returns on a null spec).
|
|
319
|
-
private Dictionary<string, object?> Sentinels =>
|
|
320
|
-
(_spec.TryGetValue("sentinels", out var s) ? s : null)
|
|
321
|
-
as Dictionary<string, object?> ?? [];
|
|
322
|
-
|
|
323
|
-
[Fact]
|
|
324
|
-
public void SentinelsGetPropUnify()
|
|
325
|
-
{
|
|
326
|
-
StructRunner.RunSet(Sentinels.GetValueOrDefault("getprop_unify"),
|
|
327
|
-
input =>
|
|
328
|
-
{
|
|
329
|
-
var m = input as Dictionary<string, object?>;
|
|
330
|
-
if (m == null) return null;
|
|
331
|
-
object? val = m.TryGetValue("val", out object? v) ? v : null;
|
|
332
|
-
object? key = m.TryGetValue("key", out object? k) ? k : null;
|
|
333
|
-
object? alt = m.TryGetValue("alt", out object? a) ? a : null;
|
|
334
|
-
return StructUtils.GetProp(val, key, alt);
|
|
335
|
-
},
|
|
336
|
-
flags: new() { ["null"] = true });
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
[Fact]
|
|
340
|
-
public void SentinelsGetElemAbsent()
|
|
341
|
-
{
|
|
342
|
-
StructRunner.RunSet(Sentinels.GetValueOrDefault("getelem_absent"),
|
|
343
|
-
input =>
|
|
344
|
-
{
|
|
345
|
-
var m = input as Dictionary<string, object?>;
|
|
346
|
-
if (m == null) return null;
|
|
347
|
-
object? val = m.TryGetValue("val", out object? v) ? v : null;
|
|
348
|
-
object? key = m.TryGetValue("key", out object? k) ? k : null;
|
|
349
|
-
object? alt = m.TryGetValue("alt", out object? a) ? a : null;
|
|
350
|
-
return StructUtils.GetElem(val, key, alt);
|
|
351
|
-
},
|
|
352
|
-
flags: new() { ["null"] = true });
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
[Fact]
|
|
356
|
-
public void SentinelsHasKeyUnify()
|
|
357
|
-
{
|
|
358
|
-
StructRunner.RunSet(Sentinels.GetValueOrDefault("haskey_unify"),
|
|
359
|
-
input =>
|
|
360
|
-
{
|
|
361
|
-
var m = input as Dictionary<string, object?>;
|
|
362
|
-
if (m == null) return false;
|
|
363
|
-
object? val = m.TryGetValue("val", out object? v) ? v : null;
|
|
364
|
-
object? key = m.TryGetValue("key", out object? k) ? k : null;
|
|
365
|
-
return StructUtils.HasKey(val, key);
|
|
366
|
-
},
|
|
367
|
-
flags: new() { ["null"] = true });
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
[Fact]
|
|
371
|
-
public void SentinelsIsEmptyUnify()
|
|
372
|
-
{
|
|
373
|
-
StructRunner.RunSet(Sentinels.GetValueOrDefault("isempty_unify"),
|
|
374
|
-
input => StructUtils.IsEmpty(input),
|
|
375
|
-
flags: new() { ["null"] = true });
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
[Fact]
|
|
379
|
-
public void SentinelsIsNodeUnify()
|
|
380
|
-
{
|
|
381
|
-
StructRunner.RunSet(Sentinels.GetValueOrDefault("isnode_unify"),
|
|
382
|
-
input => StructUtils.IsNode(input),
|
|
383
|
-
flags: new() { ["null"] = true });
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
[Fact]
|
|
387
|
-
public void SentinelsStringifyNull()
|
|
388
|
-
{
|
|
389
|
-
StructRunner.RunSet(Sentinels.GetValueOrDefault("stringify_null"),
|
|
390
|
-
input => StructUtils.Stringify(input),
|
|
391
|
-
flags: new() { ["null"] = true });
|
|
381
|
+
RunStruct("minor", "haskey", false, input =>
|
|
382
|
+
StructUtils.HasKey(Getp(input, "src"), Getp(input, "key")));
|
|
392
383
|
}
|
|
393
384
|
|
|
394
385
|
[Fact]
|
|
@@ -399,64 +390,50 @@ public class StructUtilityTest
|
|
|
399
390
|
Assert.Equal("true", StructUtils.Stringify(true));
|
|
400
391
|
Assert.Equal("hello", StructUtils.Stringify("hello"));
|
|
401
392
|
// Match TS: NONE (undefined) -> ""; JSON null -> "null".
|
|
402
|
-
Assert.Equal(
|
|
393
|
+
Assert.Equal("", StructUtils.Stringify(StructUtils.NONE));
|
|
403
394
|
Assert.Equal("null", StructUtils.Stringify(null));
|
|
404
395
|
}
|
|
405
396
|
|
|
406
|
-
private const string S_MT = "";
|
|
407
|
-
|
|
408
397
|
[Fact]
|
|
409
398
|
public void MinorTypify()
|
|
410
399
|
{
|
|
411
|
-
|
|
412
|
-
input => StructUtils.Typify(input));
|
|
400
|
+
RunStruct("minor", "typify", false, input => StructUtils.Typify(input));
|
|
413
401
|
}
|
|
414
402
|
|
|
415
403
|
[Fact]
|
|
416
404
|
public void MinorTypeName()
|
|
417
405
|
{
|
|
418
|
-
|
|
419
|
-
|
|
406
|
+
RunStruct("minor", "typename", true, input =>
|
|
407
|
+
StructUtils.TypeName(Convert.ToInt32(input)));
|
|
420
408
|
}
|
|
421
409
|
|
|
422
410
|
[Fact]
|
|
423
411
|
public void MinorSize()
|
|
424
412
|
{
|
|
425
|
-
|
|
426
|
-
input => StructUtils.Size(input));
|
|
413
|
+
RunStruct("minor", "size", false, input => StructUtils.Size(input));
|
|
427
414
|
}
|
|
428
415
|
|
|
429
416
|
[Fact]
|
|
430
417
|
public void MinorSlice()
|
|
431
418
|
{
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
int? start = m.TryGetValue("start", out object? sv) && sv != null
|
|
440
|
-
? (int?)Convert.ToInt32(sv) : null;
|
|
441
|
-
int? end = m.TryGetValue("end", out object? ev) && ev != null
|
|
442
|
-
? (int?)Convert.ToInt32(ev) : null;
|
|
443
|
-
return StructUtils.Slice(val, start, end);
|
|
444
|
-
});
|
|
419
|
+
RunStruct("minor", "slice", false, input =>
|
|
420
|
+
{
|
|
421
|
+
var val = Getp(input, "val");
|
|
422
|
+
var start = IntArg(Getp(input, "start"));
|
|
423
|
+
var end = IntArg(Getp(input, "end"));
|
|
424
|
+
return StructUtils.Slice(val, start, end);
|
|
425
|
+
});
|
|
445
426
|
}
|
|
446
427
|
|
|
447
428
|
[Fact]
|
|
448
429
|
public void MinorFlatten()
|
|
449
430
|
{
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
int depth = m.TryGetValue("depth", out object? d) && d != null
|
|
457
|
-
? (int)Convert.ToInt64(d) : 1;
|
|
458
|
-
return StructUtils.Flatten(val ?? [], depth);
|
|
459
|
-
});
|
|
431
|
+
RunStruct("minor", "flatten", true, input =>
|
|
432
|
+
{
|
|
433
|
+
var val = Getp(input, "val") as List<object?>;
|
|
434
|
+
var depth = IntArg(Getp(input, "depth"));
|
|
435
|
+
return StructUtils.Flatten(val ?? [], depth ?? 1);
|
|
436
|
+
});
|
|
460
437
|
}
|
|
461
438
|
|
|
462
439
|
// Named filter predicates used in test.json.
|
|
@@ -469,54 +446,123 @@ public class StructUtilityTest
|
|
|
469
446
|
[Fact]
|
|
470
447
|
public void MinorFilter()
|
|
471
448
|
{
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
return StructUtils.Filter(val, check);
|
|
481
|
-
return StructUtils.Filter(val, n => n[1] is string s && s.Length > 0);
|
|
482
|
-
});
|
|
449
|
+
RunStruct("minor", "filter", true, input =>
|
|
450
|
+
{
|
|
451
|
+
var val = Getp(input, "val");
|
|
452
|
+
var chk = Getp(input, "check") as string;
|
|
453
|
+
if (chk != null && FilterChecks.TryGetValue(chk, out var check))
|
|
454
|
+
return StructUtils.Filter(val, check);
|
|
455
|
+
return StructUtils.Filter(val, n => n[1] is string s && s.Length > 0);
|
|
456
|
+
});
|
|
483
457
|
}
|
|
484
458
|
|
|
485
459
|
[Fact]
|
|
486
460
|
public void MinorPad()
|
|
487
461
|
{
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
object? padding = m.TryGetValue("pad", out object? pv) ? pv : null;
|
|
495
|
-
// spec uses "char" as key for the pad character
|
|
496
|
-
object? padchar = m.TryGetValue("char", out object? cv) ? cv
|
|
497
|
-
: m.TryGetValue("padchar", out object? cv2) ? cv2 : null;
|
|
462
|
+
RunStruct("minor", "pad", false, input =>
|
|
463
|
+
{
|
|
464
|
+
var str = Getp(input, "val");
|
|
465
|
+
var padding = Getp(input, "pad");
|
|
466
|
+
// spec uses "char" as key for the pad character
|
|
467
|
+
var padchar = Getp(input, "char") ?? Getp(input, "padchar");
|
|
498
468
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
});
|
|
469
|
+
var pad = padding != null ? Convert.ToInt32(padding) : 44;
|
|
470
|
+
return StructUtils.Pad(str, pad, padchar as string);
|
|
471
|
+
});
|
|
503
472
|
}
|
|
504
473
|
|
|
505
474
|
[Fact]
|
|
506
475
|
public void MinorJoin()
|
|
507
476
|
{
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
477
|
+
RunStruct("minor", "join", false, input =>
|
|
478
|
+
{
|
|
479
|
+
if (input is not Dictionary<string, object?>)
|
|
480
|
+
return StructUtils.Join([input]);
|
|
481
|
+
var arr = Getp(input, "val");
|
|
482
|
+
var sep = Getp(input, "sep");
|
|
483
|
+
var url = Getp(input, "url") is bool b && b;
|
|
484
|
+
return StructUtils.Join(arr as List<object?> ?? [], sep as string, url);
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
[Fact]
|
|
489
|
+
public void MinorSetPath()
|
|
490
|
+
{
|
|
491
|
+
RunStruct("minor", "setpath", false, input =>
|
|
492
|
+
{
|
|
493
|
+
var store = Getp(input, "store");
|
|
494
|
+
var path = Getp(input, "path");
|
|
495
|
+
var val = Getp(input, "val");
|
|
496
|
+
return StructUtils.SetPath(store, path, val);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
// ========================================================================
|
|
502
|
+
// The struct.nullsem section: does a PRESENT key holding a JSON null
|
|
503
|
+
// read as "no value"? Opt-in per target (create-sdkgen ships it; an
|
|
504
|
+
// older project corpus may predate it - the skip below says so OUT
|
|
505
|
+
// LOUD rather than passing vacuously). All lanes run {null: false}:
|
|
506
|
+
// without the flag the runner rewrites every null to '__NULL__' and
|
|
507
|
+
// the section asserts nothing about null at all.
|
|
508
|
+
// ========================================================================
|
|
509
|
+
|
|
510
|
+
[Fact]
|
|
511
|
+
public void Nullsem()
|
|
512
|
+
{
|
|
513
|
+
var run = StructRun();
|
|
514
|
+
var nullsem = run.Spec.TryGetValue("nullsem", out var ns)
|
|
515
|
+
? ns as Dictionary<string, object?> : null;
|
|
516
|
+
if (nullsem == null)
|
|
517
|
+
{
|
|
518
|
+
// xUnit has no runtime skip without extra packages; say it loudly.
|
|
519
|
+
Console.Error.WriteLine("SKIP: corpus predates struct.nullsem - " +
|
|
520
|
+
"refresh .sdk/test/struct from create-sdkgen");
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
var flags = new Dictionary<string, bool> { ["null"] = false };
|
|
524
|
+
|
|
525
|
+
run.RunSetFlags(nullsem["getprop"], flags, args =>
|
|
526
|
+
{
|
|
527
|
+
var input = args[0];
|
|
528
|
+
// Canonical's default alt is `undefined` -> NONE; see MinorGetProp.
|
|
529
|
+
if (input is Dictionary<string, object?> m && m.ContainsKey("alt"))
|
|
530
|
+
return StructUtils.GetProp(Getp(input, "val"), Getp(input, "key"), m["alt"]);
|
|
531
|
+
return StructUtils.GetProp(Getp(input, "val"), Getp(input, "key"),
|
|
532
|
+
StructUtils.NONE);
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
run.RunSetFlags(nullsem["getelem"], flags, args =>
|
|
536
|
+
{
|
|
537
|
+
var input = args[0];
|
|
538
|
+
var alt = Getp(input, "alt");
|
|
539
|
+
return null != alt
|
|
540
|
+
? StructUtils.GetElem(Getp(input, "val"), Getp(input, "key"), alt)
|
|
541
|
+
: StructUtils.GetElem(Getp(input, "val"), Getp(input, "key"),
|
|
542
|
+
StructUtils.NONE);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
run.RunSetFlags(nullsem["getpath"], flags, args =>
|
|
546
|
+
{
|
|
547
|
+
// The port's GetPath spells "no value" as null - for a plain
|
|
548
|
+
// MISS and for a stored null alike (its alt parameter is not
|
|
549
|
+
// consulted on the path walk), where canonical answers
|
|
550
|
+
// undefined for both. Map that spelling to omni absence at the
|
|
551
|
+
// boundary; the distinction the lane guards (null-as-VALUE vs
|
|
552
|
+
// no-value) stays observable, because a port that read a
|
|
553
|
+
// stored null as a value would fail the getprop/haskey lanes.
|
|
554
|
+
var res = StructUtils.GetPath(Getp(args[0], "store"), Getp(args[0], "path"));
|
|
555
|
+
return res ?? StructUtils.NONE;
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
run.RunSetFlags(nullsem["haskey"], flags, args =>
|
|
559
|
+
StructUtils.HasKey(Getp(args[0], "src"), Getp(args[0], "key")));
|
|
560
|
+
|
|
561
|
+
run.RunSetFlags(nullsem["keysof"], flags, args =>
|
|
562
|
+
StructUtils.KeysOf(args[0]));
|
|
518
563
|
}
|
|
519
564
|
|
|
565
|
+
|
|
520
566
|
// ========================================================================
|
|
521
567
|
// Walk tests
|
|
522
568
|
// ========================================================================
|
|
@@ -528,28 +574,24 @@ public class StructUtilityTest
|
|
|
528
574
|
WalkApply walkpath = (key, val, parent, path) =>
|
|
529
575
|
{
|
|
530
576
|
if (val is string s)
|
|
531
|
-
return s + "~" + string.Join(".", path.
|
|
577
|
+
return s + "~" + string.Join(".", path.Select(p => p?.ToString()));
|
|
532
578
|
return val;
|
|
533
579
|
};
|
|
534
580
|
|
|
535
|
-
|
|
536
|
-
input => StructUtils.Walk(input, walkpath));
|
|
581
|
+
RunStruct("walk", "basic", true, input => StructUtils.Walk(input, walkpath));
|
|
537
582
|
}
|
|
538
583
|
|
|
539
584
|
[Fact]
|
|
540
585
|
public void WalkLog()
|
|
541
586
|
{
|
|
542
|
-
var
|
|
543
|
-
var
|
|
544
|
-
if (logSpec == null) return;
|
|
545
|
-
|
|
546
|
-
var testIn = StructUtils.Clone(logSpec["in"]);
|
|
587
|
+
var logSpec = Section("walk", "log");
|
|
588
|
+
var testIn = StructUtils.Clone(logSpec["in"]);
|
|
547
589
|
var outSpec = logSpec["out"] as Dictionary<string, object?>;
|
|
548
590
|
|
|
549
591
|
WalkApply makeWalkLog(List<object?> log)
|
|
550
592
|
{
|
|
551
593
|
// TS Stringify(undefined)="" but Stringify(null)="null". The C#
|
|
552
|
-
// walk passes null at root for both key and parent
|
|
594
|
+
// walk passes null at root for both key and parent - render those
|
|
553
595
|
// as empty string to match the corpus log format ("p=", "k=").
|
|
554
596
|
string Render(object? v) =>
|
|
555
597
|
v == null ? "" : StructUtils.Stringify(v);
|
|
@@ -590,84 +632,74 @@ public class StructUtilityTest
|
|
|
590
632
|
[Fact]
|
|
591
633
|
public void WalkDepth()
|
|
592
634
|
{
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
input
|
|
596
|
-
|
|
597
|
-
var m = input as Dictionary<string, object?>;
|
|
598
|
-
if (m == null) return null;
|
|
599
|
-
|
|
600
|
-
object? src = m.TryGetValue("src", out object? sv) ? sv : null;
|
|
601
|
-
int? md = m.TryGetValue("maxdepth", out object? dv) && dv != null
|
|
602
|
-
? (int?)Convert.ToInt32(dv) : null;
|
|
635
|
+
RunStruct("walk", "depth", false, input =>
|
|
636
|
+
{
|
|
637
|
+
var src = Getp(input, "src");
|
|
638
|
+
var md = IntArg(Getp(input, "maxdepth"));
|
|
603
639
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
640
|
+
// Build a copy using a single current-node pointer (matches the
|
|
641
|
+
// go walk-depth test).
|
|
642
|
+
object? top = null;
|
|
643
|
+
object? cur = null;
|
|
607
644
|
|
|
608
|
-
|
|
645
|
+
WalkApply copy = (key, val, parent, path) =>
|
|
646
|
+
{
|
|
647
|
+
if (StructUtils.IsNode(val))
|
|
609
648
|
{
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
return val;
|
|
621
|
-
};
|
|
649
|
+
object? child = StructUtils.IsList(val)
|
|
650
|
+
? (object?)new List<object?>()
|
|
651
|
+
: new Dictionary<string, object?>();
|
|
652
|
+
if (key == null) { top = child; cur = child; }
|
|
653
|
+
else { StructUtils.SetProp(cur, key, child); cur = child; }
|
|
654
|
+
}
|
|
655
|
+
else if (key != null)
|
|
656
|
+
StructUtils.SetProp(cur, key, val);
|
|
657
|
+
return val;
|
|
658
|
+
};
|
|
622
659
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
flags: new() { ["null"] = false });
|
|
660
|
+
StructUtils.Walk(src, copy, null, md);
|
|
661
|
+
return top;
|
|
662
|
+
});
|
|
627
663
|
}
|
|
628
664
|
|
|
629
665
|
[Fact]
|
|
630
666
|
public void WalkCopy()
|
|
631
667
|
{
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
{
|
|
636
|
-
var cur = new object?[MAXDEPTH + 1];
|
|
668
|
+
RunStruct("walk", "copy", true, input =>
|
|
669
|
+
{
|
|
670
|
+
var cur = new object?[StructUtils.MAXDEPTH + 1];
|
|
637
671
|
|
|
638
|
-
|
|
672
|
+
WalkApply walkcopy = (key, val, parent, path) =>
|
|
673
|
+
{
|
|
674
|
+
if (key == null) // root
|
|
639
675
|
{
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
?
|
|
644
|
-
:
|
|
645
|
-
? new List<object?>()
|
|
646
|
-
: val;
|
|
647
|
-
return val;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
int i = path.Count;
|
|
651
|
-
object? v = val;
|
|
652
|
-
|
|
653
|
-
if (StructUtils.IsNode(val))
|
|
654
|
-
{
|
|
655
|
-
cur[i] = StructUtils.IsMap(val)
|
|
656
|
-
? (object?)new Dictionary<string, object?>()
|
|
657
|
-
: new List<object?>();
|
|
658
|
-
v = cur[i];
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
cur[i - 1] = StructUtils.SetProp(cur[i - 1], key, v) ?? cur[i - 1];
|
|
676
|
+
cur[0] = StructUtils.IsMap(val)
|
|
677
|
+
? (object?)new Dictionary<string, object?>()
|
|
678
|
+
: StructUtils.IsList(val)
|
|
679
|
+
? new List<object?>()
|
|
680
|
+
: val;
|
|
662
681
|
return val;
|
|
663
|
-
}
|
|
682
|
+
}
|
|
664
683
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
684
|
+
int i = path.Count;
|
|
685
|
+
object? v = val;
|
|
686
|
+
|
|
687
|
+
if (StructUtils.IsNode(val))
|
|
688
|
+
{
|
|
689
|
+
cur[i] = StructUtils.IsMap(val)
|
|
690
|
+
? (object?)new Dictionary<string, object?>()
|
|
691
|
+
: new List<object?>();
|
|
692
|
+
v = cur[i];
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
cur[i - 1] = StructUtils.SetProp(cur[i - 1], key, v) ?? cur[i - 1];
|
|
696
|
+
return val;
|
|
697
|
+
};
|
|
669
698
|
|
|
670
|
-
|
|
699
|
+
StructUtils.Walk(input, walkcopy);
|
|
700
|
+
return cur[0];
|
|
701
|
+
});
|
|
702
|
+
}
|
|
671
703
|
|
|
672
704
|
|
|
673
705
|
// ========================================================================
|
|
@@ -677,10 +709,7 @@ public class StructUtilityTest
|
|
|
677
709
|
[Fact]
|
|
678
710
|
public void MergeBasic()
|
|
679
711
|
{
|
|
680
|
-
var
|
|
681
|
-
var basic = mergeSpec?["basic"] as Dictionary<string, object?>;
|
|
682
|
-
if (basic == null) return;
|
|
683
|
-
|
|
712
|
+
var basic = Section("merge", "basic");
|
|
684
713
|
object? result = StructUtils.Merge(basic["in"]);
|
|
685
714
|
Assert.True(StructRunner.DeepEqual(basic["out"], result),
|
|
686
715
|
$"merge-basic: expected {StructUtils.Stringify(basic["out"])} but got {StructUtils.Stringify(result)}");
|
|
@@ -689,42 +718,30 @@ public class StructUtilityTest
|
|
|
689
718
|
[Fact]
|
|
690
719
|
public void MergeCases()
|
|
691
720
|
{
|
|
692
|
-
|
|
693
|
-
StructRunner.RunSet(mergeSpec?["cases"],
|
|
694
|
-
input => StructUtils.Merge(input));
|
|
721
|
+
RunStruct("merge", "cases", true, input => StructUtils.Merge(input));
|
|
695
722
|
}
|
|
696
723
|
|
|
697
724
|
[Fact]
|
|
698
725
|
public void MergeArray()
|
|
699
726
|
{
|
|
700
|
-
|
|
701
|
-
StructRunner.RunSet(mergeSpec?["array"],
|
|
702
|
-
input => StructUtils.Merge(input));
|
|
727
|
+
RunStruct("merge", "array", true, input => StructUtils.Merge(input));
|
|
703
728
|
}
|
|
704
729
|
|
|
705
730
|
[Fact]
|
|
706
731
|
public void MergeIntegrity()
|
|
707
732
|
{
|
|
708
|
-
|
|
709
|
-
StructRunner.RunSet(mergeSpec?["integrity"],
|
|
710
|
-
input => StructUtils.Merge(input));
|
|
733
|
+
RunStruct("merge", "integrity", true, input => StructUtils.Merge(input));
|
|
711
734
|
}
|
|
712
735
|
|
|
713
736
|
[Fact]
|
|
714
737
|
public void MergeDepth()
|
|
715
738
|
{
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
input
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
object? val = m.TryGetValue("val", out object? v) ? v : null;
|
|
724
|
-
int? depth = m.TryGetValue("depth", out object? d) && d != null
|
|
725
|
-
? (int?)Convert.ToInt32(d) : null;
|
|
726
|
-
return StructUtils.Merge(val, depth);
|
|
727
|
-
});
|
|
739
|
+
RunStruct("merge", "depth", true, input =>
|
|
740
|
+
{
|
|
741
|
+
var val = Getp(input, "val");
|
|
742
|
+
var depth = IntArg(Getp(input, "depth"));
|
|
743
|
+
return StructUtils.Merge(val, depth);
|
|
744
|
+
});
|
|
728
745
|
}
|
|
729
746
|
|
|
730
747
|
[Fact]
|
|
@@ -750,26 +767,80 @@ public class StructUtilityTest
|
|
|
750
767
|
Assert.Equal(f0(), fr2!());
|
|
751
768
|
}
|
|
752
769
|
|
|
770
|
+
|
|
771
|
+
// ========================================================================
|
|
772
|
+
// GetPath tests
|
|
773
|
+
// ========================================================================
|
|
774
|
+
|
|
775
|
+
[Fact]
|
|
776
|
+
public void GetpathExists()
|
|
777
|
+
{
|
|
778
|
+
Delegate fn = (Func<object?, object?, object?, InjectState?, object?>)StructUtils.GetPath;
|
|
779
|
+
Assert.NotNull(fn);
|
|
780
|
+
}
|
|
781
|
+
|
|
753
782
|
[Fact]
|
|
754
|
-
public void
|
|
783
|
+
public void GetpathBasic()
|
|
784
|
+
{
|
|
785
|
+
RunStruct("getpath", "basic", true, input =>
|
|
786
|
+
StructUtils.GetPath(Getp(input, "store"), Getp(input, "path")));
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
[Fact]
|
|
790
|
+
public void GetpathRelative()
|
|
791
|
+
{
|
|
792
|
+
RunStruct("getpath", "relative", true, input =>
|
|
793
|
+
{
|
|
794
|
+
var state = new InjectState { DParent = Getp(input, "dparent") };
|
|
795
|
+
|
|
796
|
+
if (Getp(input, "dpath") is string dpathStr && dpathStr.Length > 0)
|
|
797
|
+
state.DPath = dpathStr.Split('.').Cast<object?>().ToList();
|
|
798
|
+
|
|
799
|
+
return StructUtils.GetPath(Getp(input, "store"), Getp(input, "path"),
|
|
800
|
+
null, state);
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
[Fact]
|
|
805
|
+
public void GetpathSpecial()
|
|
755
806
|
{
|
|
756
|
-
|
|
757
|
-
|
|
807
|
+
RunStruct("getpath", "special", true, input =>
|
|
808
|
+
{
|
|
809
|
+
InjectState? state = null;
|
|
810
|
+
if (Getp(input, "inj") is Dictionary<string, object?> injMap)
|
|
758
811
|
{
|
|
759
|
-
|
|
760
|
-
if (
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
}
|
|
766
|
-
|
|
812
|
+
state = new InjectState();
|
|
813
|
+
if (injMap.TryGetValue("key", out var kv) && kv != null)
|
|
814
|
+
state.Key = StructUtils.Stringify(kv);
|
|
815
|
+
if (injMap.TryGetValue("meta", out var mv) &&
|
|
816
|
+
mv is Dictionary<string, object?> metaMap)
|
|
817
|
+
state.Meta = metaMap;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return StructUtils.GetPath(Getp(input, "store"), Getp(input, "path"),
|
|
821
|
+
null, state);
|
|
822
|
+
});
|
|
767
823
|
}
|
|
768
824
|
|
|
825
|
+
[Fact]
|
|
826
|
+
public void GetpathHandler()
|
|
827
|
+
{
|
|
828
|
+
// Handler that turns any ref lookup into "<ref>" (e.g. "$FOO" → "foo").
|
|
829
|
+
var refMap = new Dictionary<string, object?> { ["$FOO"] = "foo" };
|
|
830
|
+
|
|
831
|
+
RunStruct("getpath", "handler", true, input =>
|
|
832
|
+
{
|
|
833
|
+
var state = new InjectState
|
|
834
|
+
{
|
|
835
|
+
Handler = (inj, val, refStr, st) =>
|
|
836
|
+
refStr != null && refMap.TryGetValue(refStr, out var mapped)
|
|
837
|
+
? mapped : val,
|
|
838
|
+
};
|
|
839
|
+
return StructUtils.GetPath(Getp(input, "store"), Getp(input, "path"),
|
|
840
|
+
null, state);
|
|
841
|
+
});
|
|
842
|
+
}
|
|
769
843
|
|
|
770
|
-
// ========================================================================
|
|
771
|
-
// GetPath tests
|
|
772
|
-
// ========================================================================
|
|
773
844
|
|
|
774
845
|
// ========================================================================
|
|
775
846
|
// Inject tests
|
|
@@ -785,15 +856,12 @@ public class StructUtilityTest
|
|
|
785
856
|
[Fact]
|
|
786
857
|
public void InjectBasic()
|
|
787
858
|
{
|
|
788
|
-
var
|
|
789
|
-
var basic = injectSpec?["basic"] as Dictionary<string, object?>;
|
|
790
|
-
if (basic == null) return;
|
|
791
|
-
|
|
859
|
+
var basic = Section("inject", "basic");
|
|
792
860
|
var inVal = basic["in"] as Dictionary<string, object?>;
|
|
793
|
-
|
|
794
|
-
object? val
|
|
795
|
-
object? store = inVal.TryGetValue("store", out
|
|
796
|
-
object? expected = basic
|
|
861
|
+
Assert.NotNull(inVal);
|
|
862
|
+
object? val = inVal!.TryGetValue("val", out var v) ? v : null;
|
|
863
|
+
object? store = inVal.TryGetValue("store", out var s) ? s : null;
|
|
864
|
+
object? expected = basic.TryGetValue("out", out var o) ? o : null;
|
|
797
865
|
|
|
798
866
|
object? result = StructUtils.Inject(val, store);
|
|
799
867
|
Assert.True(StructRunner.DeepEqual(expected, result),
|
|
@@ -803,32 +871,20 @@ public class StructUtilityTest
|
|
|
803
871
|
[Fact]
|
|
804
872
|
public void InjectString()
|
|
805
873
|
{
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
object? store = m.TryGetValue("store", out object? s) ? s : null;
|
|
814
|
-
return StructUtils.Inject(val, store);
|
|
815
|
-
},
|
|
816
|
-
flags: new() { ["null"] = true });
|
|
874
|
+
// The nullModifier renders a resolved JSON null (encoded by the
|
|
875
|
+
// runner as "__NULL__") as the literal text "null".
|
|
876
|
+
RunStruct("inject", "string", true, input =>
|
|
877
|
+
{
|
|
878
|
+
var state = new InjectState { ModifyFn = NullModifier };
|
|
879
|
+
return StructUtils.Inject(Getp(input, "val"), Getp(input, "store"), state);
|
|
880
|
+
});
|
|
817
881
|
}
|
|
818
882
|
|
|
819
883
|
[Fact]
|
|
820
884
|
public void InjectDeep()
|
|
821
885
|
{
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
input =>
|
|
825
|
-
{
|
|
826
|
-
var m = input as Dictionary<string, object?>;
|
|
827
|
-
if (m == null) return null;
|
|
828
|
-
object? val = m.TryGetValue("val", out object? v) ? v : null;
|
|
829
|
-
object? store = m.TryGetValue("store", out object? s) ? s : null;
|
|
830
|
-
return StructUtils.Inject(val, store);
|
|
831
|
-
});
|
|
886
|
+
RunStruct("inject", "deep", true, input =>
|
|
887
|
+
StructUtils.Inject(Getp(input, "val"), Getp(input, "store")));
|
|
832
888
|
}
|
|
833
889
|
|
|
834
890
|
|
|
@@ -846,15 +902,12 @@ public class StructUtilityTest
|
|
|
846
902
|
[Fact]
|
|
847
903
|
public void TransformBasic()
|
|
848
904
|
{
|
|
849
|
-
var
|
|
850
|
-
var
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
object? data = inVal.TryGetValue("data", out object? d) ? d : null;
|
|
856
|
-
object? spec = inVal.TryGetValue("spec", out object? s) ? s : null;
|
|
857
|
-
object? expected = basic["out"];
|
|
905
|
+
var basic = Section("transform", "basic");
|
|
906
|
+
var inVal = basic["in"] as Dictionary<string, object?>;
|
|
907
|
+
Assert.NotNull(inVal);
|
|
908
|
+
object? data = inVal!.TryGetValue("data", out var d) ? d : null;
|
|
909
|
+
object? spec = inVal.TryGetValue("spec", out var s) ? s : null;
|
|
910
|
+
object? expected = basic.TryGetValue("out", out var o) ? o : null;
|
|
858
911
|
|
|
859
912
|
object? result = StructUtils.Transform(data, spec);
|
|
860
913
|
Assert.True(StructRunner.DeepEqual(expected, result),
|
|
@@ -865,262 +918,73 @@ public class StructUtilityTest
|
|
|
865
918
|
[Fact]
|
|
866
919
|
public void TransformPaths()
|
|
867
920
|
{
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
{
|
|
871
|
-
var m = input as Dictionary<string, object?>;
|
|
872
|
-
if (m == null) return null;
|
|
873
|
-
object? data = m.TryGetValue("data", out object? d) ? d : null;
|
|
874
|
-
object? spec = m.TryGetValue("spec", out object? s) ? s : null;
|
|
875
|
-
return StructUtils.Transform(data, spec);
|
|
876
|
-
});
|
|
921
|
+
RunStruct("transform", "paths", true, input =>
|
|
922
|
+
StructUtils.Transform(Getp(input, "data"), Getp(input, "spec")));
|
|
877
923
|
}
|
|
878
924
|
|
|
879
925
|
[Fact]
|
|
880
926
|
public void TransformCmds()
|
|
881
927
|
{
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
{
|
|
885
|
-
var m = input as Dictionary<string, object?>;
|
|
886
|
-
if (m == null) return null;
|
|
887
|
-
object? data = m.TryGetValue("data", out object? d) ? d : null;
|
|
888
|
-
object? spec = m.TryGetValue("spec", out object? s) ? s : null;
|
|
889
|
-
return StructUtils.Transform(data, spec);
|
|
890
|
-
});
|
|
928
|
+
RunStruct("transform", "cmds", true, input =>
|
|
929
|
+
StructUtils.Transform(Getp(input, "data"), Getp(input, "spec")));
|
|
891
930
|
}
|
|
892
931
|
|
|
893
932
|
[Fact]
|
|
894
933
|
public void TransformEach()
|
|
895
934
|
{
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
{
|
|
899
|
-
var m = input as Dictionary<string, object?>;
|
|
900
|
-
if (m == null) return null;
|
|
901
|
-
object? data = m.TryGetValue("data", out object? d) ? d : null;
|
|
902
|
-
object? spec = m.TryGetValue("spec", out object? s) ? s : null;
|
|
903
|
-
return StructUtils.Transform(data, spec);
|
|
904
|
-
});
|
|
935
|
+
RunStruct("transform", "each", true, input =>
|
|
936
|
+
StructUtils.Transform(Getp(input, "data"), Getp(input, "spec")));
|
|
905
937
|
}
|
|
906
938
|
|
|
907
939
|
[Fact]
|
|
908
940
|
public void TransformPack()
|
|
909
941
|
{
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
{
|
|
913
|
-
var m = input as Dictionary<string, object?>;
|
|
914
|
-
if (m == null) return null;
|
|
915
|
-
object? data = m.TryGetValue("data", out object? d) ? d : null;
|
|
916
|
-
object? spec = m.TryGetValue("spec", out object? s) ? s : null;
|
|
917
|
-
return StructUtils.Transform(data, spec);
|
|
918
|
-
});
|
|
942
|
+
RunStruct("transform", "pack", true, input =>
|
|
943
|
+
StructUtils.Transform(Getp(input, "data"), Getp(input, "spec")));
|
|
919
944
|
}
|
|
920
945
|
|
|
921
946
|
[Fact]
|
|
922
947
|
public void TransformRef()
|
|
923
948
|
{
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
{
|
|
927
|
-
var m = input as Dictionary<string, object?>;
|
|
928
|
-
if (m == null) return null;
|
|
929
|
-
object? data = m.TryGetValue("data", out object? d) ? d : null;
|
|
930
|
-
object? spec = m.TryGetValue("spec", out object? s) ? s : null;
|
|
931
|
-
return StructUtils.Transform(data, spec);
|
|
932
|
-
});
|
|
949
|
+
RunStruct("transform", "ref", true, input =>
|
|
950
|
+
StructUtils.Transform(Getp(input, "data"), Getp(input, "spec")));
|
|
933
951
|
}
|
|
934
952
|
|
|
935
953
|
[Fact]
|
|
936
954
|
public void TransformFormat()
|
|
937
955
|
{
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
{
|
|
941
|
-
var m = input as Dictionary<string, object?>;
|
|
942
|
-
if (m == null) return null;
|
|
943
|
-
object? data = m.TryGetValue("data", out object? d) ? d : null;
|
|
944
|
-
object? spec = m.TryGetValue("spec", out object? s) ? s : null;
|
|
945
|
-
return StructUtils.Transform(data, spec);
|
|
946
|
-
}, flags: new() { ["null"] = true });
|
|
956
|
+
RunStruct("transform", "format", false, input =>
|
|
957
|
+
StructUtils.Transform(Getp(input, "data"), Getp(input, "spec")));
|
|
947
958
|
}
|
|
948
959
|
|
|
949
960
|
[Fact]
|
|
950
961
|
public void TransformModify()
|
|
951
962
|
{
|
|
952
|
-
|
|
953
|
-
var modSet = tSpec?["modify"] as Dictionary<string, object?>;
|
|
954
|
-
if (modSet == null) return;
|
|
955
|
-
|
|
956
|
-
var set = modSet.TryGetValue("set", out object? sv) ? sv as List<object?> : null;
|
|
957
|
-
if (set == null || set.Count == 0) return;
|
|
958
|
-
|
|
959
|
-
var entry = set[0] as Dictionary<string, object?>;
|
|
960
|
-
if (entry == null || !entry.ContainsKey("out")) return;
|
|
961
|
-
|
|
962
|
-
var inVal = entry["in"] as Dictionary<string, object?>;
|
|
963
|
-
if (inVal == null) return;
|
|
964
|
-
|
|
965
|
-
object? data = inVal.TryGetValue("data", out object? d) ? d : null;
|
|
966
|
-
object? spec = inVal.TryGetValue("spec", out object? s) ? s : null;
|
|
967
|
-
object? expected = entry["out"];
|
|
968
|
-
|
|
969
|
-
// Modify callback that prefixes every injected string value with "@".
|
|
970
|
-
Modify myModify = (val, key, parent, inj, store) =>
|
|
971
|
-
{
|
|
972
|
-
if (val is string sv2 && sv2.Length > 0)
|
|
973
|
-
StructUtils.SetProp(parent, key, "@" + sv2);
|
|
974
|
-
return val;
|
|
975
|
-
};
|
|
976
|
-
|
|
977
|
-
var injState = new InjectState { ModifyFn = myModify };
|
|
978
|
-
object? result = StructUtils.Transform(data, spec, injState);
|
|
979
|
-
|
|
980
|
-
Assert.True(StructRunner.DeepEqual(expected, result),
|
|
981
|
-
$"transform-modify: expected {StructUtils.Stringify(expected)} " +
|
|
982
|
-
$"but got {StructUtils.Stringify(result)}");
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
// ========================================================================
|
|
986
|
-
// GetPath tests
|
|
987
|
-
// ========================================================================
|
|
988
|
-
|
|
989
|
-
[Fact]
|
|
990
|
-
public void GetpathExists()
|
|
991
|
-
{
|
|
992
|
-
Delegate fn = (Func<object?, object?, object?, InjectState?, object?>)StructUtils.GetPath;
|
|
993
|
-
Assert.NotNull(fn);
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
[Fact]
|
|
997
|
-
public void GetpathBasic()
|
|
998
|
-
{
|
|
999
|
-
var getpathSpec = _spec["getpath"] as Dictionary<string, object?>;
|
|
1000
|
-
StructRunner.RunSet(getpathSpec?["basic"],
|
|
1001
|
-
input =>
|
|
1002
|
-
{
|
|
1003
|
-
var m = input as Dictionary<string, object?>;
|
|
1004
|
-
if (m == null) return null;
|
|
1005
|
-
object? path = m.TryGetValue("path", out object? pv) ? pv : null;
|
|
1006
|
-
object? store = m.TryGetValue("store", out object? sv) ? sv : null;
|
|
1007
|
-
return StructUtils.GetPath(store, path);
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
[Fact]
|
|
1012
|
-
public void GetpathRelative()
|
|
1013
|
-
{
|
|
1014
|
-
var getpathSpec = _spec["getpath"] as Dictionary<string, object?>;
|
|
1015
|
-
StructRunner.RunSet(getpathSpec?["relative"],
|
|
1016
|
-
input =>
|
|
1017
|
-
{
|
|
1018
|
-
var m = input as Dictionary<string, object?>;
|
|
1019
|
-
if (m == null) return null;
|
|
1020
|
-
object? path = m.TryGetValue("path", out object? pv) ? pv : null;
|
|
1021
|
-
object? store = m.TryGetValue("store", out object? sv) ? sv : null;
|
|
1022
|
-
object? dparent = m.TryGetValue("dparent", out object? dv) ? dv : null;
|
|
1023
|
-
|
|
1024
|
-
var state = new InjectState { DParent = dparent };
|
|
1025
|
-
|
|
1026
|
-
if (m.TryGetValue("dpath", out object? dpv) && dpv is string dpathStr && dpathStr.Length > 0)
|
|
1027
|
-
state.DPath = dpathStr.Split('.').Cast<object?>().ToList();
|
|
1028
|
-
|
|
1029
|
-
return StructUtils.GetPath(store, path, null, state);
|
|
1030
|
-
});
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
[Fact]
|
|
1034
|
-
public void GetpathSpecial()
|
|
1035
|
-
{
|
|
1036
|
-
var getpathSpec = _spec["getpath"] as Dictionary<string, object?>;
|
|
1037
|
-
StructRunner.RunSet(getpathSpec?["special"],
|
|
1038
|
-
input =>
|
|
1039
|
-
{
|
|
1040
|
-
var m = input as Dictionary<string, object?>;
|
|
1041
|
-
if (m == null) return null;
|
|
1042
|
-
object? path = m.TryGetValue("path", out object? pv) ? pv : null;
|
|
1043
|
-
object? store = m.TryGetValue("store", out object? sv) ? sv : null;
|
|
1044
|
-
|
|
1045
|
-
InjectState? state = null;
|
|
1046
|
-
if (m.TryGetValue("inj", out object? injv) && injv is Dictionary<string, object?> injMap)
|
|
1047
|
-
{
|
|
1048
|
-
state = new InjectState();
|
|
1049
|
-
if (injMap.TryGetValue("key", out object? kv) && kv != null)
|
|
1050
|
-
state.Key = StructUtils.Stringify(kv);
|
|
1051
|
-
if (injMap.TryGetValue("meta", out object? mv) && mv is Dictionary<string, object?> metaMap)
|
|
1052
|
-
state.Meta = metaMap;
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
return StructUtils.GetPath(store, path, null, state);
|
|
1056
|
-
});
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
[Fact]
|
|
1060
|
-
public void GetpathHandler()
|
|
1061
|
-
{
|
|
1062
|
-
var getpathSpec = _spec["getpath"] as Dictionary<string, object?>;
|
|
1063
|
-
var handlerSpec = getpathSpec?["handler"] as Dictionary<string, object?>;
|
|
1064
|
-
if (handlerSpec == null) return;
|
|
1065
|
-
|
|
1066
|
-
// Handler that turns any ref lookup into "<ref>" (e.g. "$FOO" → "foo").
|
|
1067
|
-
var refMap = new Dictionary<string, object?> { ["$FOO"] = "foo" };
|
|
1068
|
-
|
|
1069
|
-
var state = new InjectState
|
|
963
|
+
RunStruct("transform", "modify", true, input =>
|
|
1070
964
|
{
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
};
|
|
1074
|
-
|
|
1075
|
-
StructRunner.RunSet(handlerSpec,
|
|
1076
|
-
input =>
|
|
965
|
+
// Match the JS test guard: only mutate string leaves.
|
|
966
|
+
Modify myModify = (val, key, parent, inj, store) =>
|
|
1077
967
|
{
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
// ── minor.jsonify ────────────────────────────────────────────────────────
|
|
1087
|
-
|
|
1088
|
-
[Fact]
|
|
1089
|
-
public void MinorJsonify()
|
|
1090
|
-
{
|
|
1091
|
-
var jsonifySpec = _minor["jsonify"] as Dictionary<string, object?>;
|
|
1092
|
-
StructRunner.RunSet(jsonifySpec,
|
|
1093
|
-
input =>
|
|
1094
|
-
{
|
|
1095
|
-
var m = input as Dictionary<string, object?>;
|
|
1096
|
-
if (m == null) return null;
|
|
1097
|
-
object? val = m.TryGetValue("val", out object? vv) ? vv : null;
|
|
1098
|
-
if (m.TryGetValue("flags", out object? fv) && fv is Dictionary<string, object?> flags)
|
|
1099
|
-
{
|
|
1100
|
-
int indent = flags.TryGetValue("indent", out object? iv) && iv is long li ? (int)li : 2;
|
|
1101
|
-
int offset = flags.TryGetValue("offset", out object? ov) && ov is long lo ? (int)lo : 0;
|
|
1102
|
-
return StructUtils.Jsonify(val, indent, offset);
|
|
1103
|
-
}
|
|
1104
|
-
return StructUtils.Jsonify(val);
|
|
1105
|
-
}, new() { ["null"] = true });
|
|
968
|
+
if (key != null && val is string s && s.Length > 0)
|
|
969
|
+
StructUtils.SetProp(parent, key, "@" + s);
|
|
970
|
+
return val;
|
|
971
|
+
};
|
|
972
|
+
var state = new InjectState { ModifyFn = myModify };
|
|
973
|
+
return StructUtils.Transform(Getp(input, "data"), Getp(input, "spec"), state);
|
|
974
|
+
});
|
|
1106
975
|
}
|
|
1107
976
|
|
|
1108
|
-
// ── transform.apply ──────────────────────────────────────────────────────
|
|
1109
|
-
|
|
1110
977
|
[Fact]
|
|
1111
978
|
public void TransformApply()
|
|
1112
979
|
{
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
input =>
|
|
1116
|
-
{
|
|
1117
|
-
object? data = input?.GetValueOrDefault("data");
|
|
1118
|
-
object? spec = input?.GetValueOrDefault("spec");
|
|
1119
|
-
return StructUtils.Transform(data, spec);
|
|
1120
|
-
}, new() { ["null"] = true });
|
|
980
|
+
RunStruct("transform", "apply", true, input =>
|
|
981
|
+
StructUtils.Transform(Getp(input, "data"), Getp(input, "spec")));
|
|
1121
982
|
}
|
|
1122
983
|
|
|
1123
|
-
|
|
984
|
+
|
|
985
|
+
// ========================================================================
|
|
986
|
+
// Validate tests
|
|
987
|
+
// ========================================================================
|
|
1124
988
|
|
|
1125
989
|
[Fact]
|
|
1126
990
|
public void ValidateExists()
|
|
@@ -1131,83 +995,58 @@ public class StructUtilityTest
|
|
|
1131
995
|
[Fact]
|
|
1132
996
|
public void ValidateBasic()
|
|
1133
997
|
{
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
{
|
|
1137
|
-
object? data = input?.GetValueOrDefault("data");
|
|
1138
|
-
object? spec = input?.GetValueOrDefault("spec");
|
|
1139
|
-
return StructUtils.Validate(data, spec);
|
|
1140
|
-
}, new() { ["null"] = true });
|
|
998
|
+
RunStruct("validate", "basic", false, input =>
|
|
999
|
+
StructUtils.Validate(Getp(input, "data"), Getp(input, "spec")));
|
|
1141
1000
|
}
|
|
1142
1001
|
|
|
1143
1002
|
[Fact]
|
|
1144
1003
|
public void ValidateChild()
|
|
1145
1004
|
{
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
{
|
|
1149
|
-
object? data = input?.GetValueOrDefault("data");
|
|
1150
|
-
object? spec = input?.GetValueOrDefault("spec");
|
|
1151
|
-
return StructUtils.Validate(data, spec);
|
|
1152
|
-
}, new() { ["null"] = true });
|
|
1005
|
+
RunStruct("validate", "child", true, input =>
|
|
1006
|
+
StructUtils.Validate(Getp(input, "data"), Getp(input, "spec")));
|
|
1153
1007
|
}
|
|
1154
1008
|
|
|
1155
1009
|
[Fact]
|
|
1156
1010
|
public void ValidateOne()
|
|
1157
1011
|
{
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
{
|
|
1161
|
-
object? data = input?.GetValueOrDefault("data");
|
|
1162
|
-
object? spec = input?.GetValueOrDefault("spec");
|
|
1163
|
-
return StructUtils.Validate(data, spec);
|
|
1164
|
-
}, new() { ["null"] = true });
|
|
1012
|
+
RunStruct("validate", "one", true, input =>
|
|
1013
|
+
StructUtils.Validate(Getp(input, "data"), Getp(input, "spec")));
|
|
1165
1014
|
}
|
|
1166
1015
|
|
|
1167
1016
|
[Fact]
|
|
1168
1017
|
public void ValidateExact()
|
|
1169
1018
|
{
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
{
|
|
1173
|
-
object? data = input?.GetValueOrDefault("data");
|
|
1174
|
-
object? spec = input?.GetValueOrDefault("spec");
|
|
1175
|
-
return StructUtils.Validate(data, spec);
|
|
1176
|
-
}, new() { ["null"] = true });
|
|
1019
|
+
RunStruct("validate", "exact", true, input =>
|
|
1020
|
+
StructUtils.Validate(Getp(input, "data"), Getp(input, "spec")));
|
|
1177
1021
|
}
|
|
1178
1022
|
|
|
1179
1023
|
[Fact]
|
|
1180
1024
|
public void ValidateInvalid()
|
|
1181
1025
|
{
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
{
|
|
1185
|
-
object? data = input?.GetValueOrDefault("data");
|
|
1186
|
-
object? spec = input?.GetValueOrDefault("spec");
|
|
1187
|
-
return StructUtils.Validate(data, spec);
|
|
1188
|
-
}, new() { ["null"] = true });
|
|
1026
|
+
RunStruct("validate", "invalid", false, input =>
|
|
1027
|
+
StructUtils.Validate(Getp(input, "data"), Getp(input, "spec")));
|
|
1189
1028
|
}
|
|
1190
1029
|
|
|
1191
1030
|
[Fact]
|
|
1192
1031
|
public void ValidateSpecial()
|
|
1193
1032
|
{
|
|
1194
|
-
|
|
1195
|
-
StructRunner.RunSetFull(validateSpec, input =>
|
|
1033
|
+
RunStruct("validate", "special", true, input =>
|
|
1196
1034
|
{
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
if (injEntry != null)
|
|
1035
|
+
var injdef = new InjectState();
|
|
1036
|
+
if (Getp(input, "inj") is Dictionary<string, object?> injEntry &&
|
|
1037
|
+
injEntry.TryGetValue("meta", out var mv) &&
|
|
1038
|
+
mv is Dictionary<string, object?> meta)
|
|
1202
1039
|
{
|
|
1203
|
-
|
|
1204
|
-
if (meta != null) injdef.Meta = meta;
|
|
1040
|
+
injdef.Meta = meta;
|
|
1205
1041
|
}
|
|
1206
|
-
return StructUtils.Validate(data, spec, injdef);
|
|
1207
|
-
}
|
|
1042
|
+
return StructUtils.Validate(Getp(input, "data"), Getp(input, "spec"), injdef);
|
|
1043
|
+
});
|
|
1208
1044
|
}
|
|
1209
1045
|
|
|
1210
|
-
|
|
1046
|
+
|
|
1047
|
+
// ========================================================================
|
|
1048
|
+
// Select tests
|
|
1049
|
+
// ========================================================================
|
|
1211
1050
|
|
|
1212
1051
|
[Fact]
|
|
1213
1052
|
public void SelectExists()
|
|
@@ -1218,56 +1057,28 @@ public class StructUtilityTest
|
|
|
1218
1057
|
[Fact]
|
|
1219
1058
|
public void SelectBasic()
|
|
1220
1059
|
{
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
input =>
|
|
1224
|
-
{
|
|
1225
|
-
var m = input as Dictionary<string, object?>;
|
|
1226
|
-
object? query = m?.GetValueOrDefault("query");
|
|
1227
|
-
object? obj = m?.GetValueOrDefault("obj");
|
|
1228
|
-
return (object?)StructUtils.Select(obj, query);
|
|
1229
|
-
}, new() { ["null"] = true });
|
|
1060
|
+
RunStruct("select", "basic", true, input =>
|
|
1061
|
+
StructUtils.Select(Getp(input, "obj"), Getp(input, "query")));
|
|
1230
1062
|
}
|
|
1231
1063
|
|
|
1232
1064
|
[Fact]
|
|
1233
1065
|
public void SelectOperators()
|
|
1234
1066
|
{
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
input =>
|
|
1238
|
-
{
|
|
1239
|
-
var m = input as Dictionary<string, object?>;
|
|
1240
|
-
object? query = m?.GetValueOrDefault("query");
|
|
1241
|
-
object? obj = m?.GetValueOrDefault("obj");
|
|
1242
|
-
return (object?)StructUtils.Select(obj, query);
|
|
1243
|
-
}, new() { ["null"] = true });
|
|
1067
|
+
RunStruct("select", "operators", true, input =>
|
|
1068
|
+
StructUtils.Select(Getp(input, "obj"), Getp(input, "query")));
|
|
1244
1069
|
}
|
|
1245
1070
|
|
|
1246
1071
|
[Fact]
|
|
1247
1072
|
public void SelectEdge()
|
|
1248
1073
|
{
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
input =>
|
|
1252
|
-
{
|
|
1253
|
-
var m = input as Dictionary<string, object?>;
|
|
1254
|
-
object? query = m?.GetValueOrDefault("query");
|
|
1255
|
-
object? obj = m?.GetValueOrDefault("obj");
|
|
1256
|
-
return (object?)StructUtils.Select(obj, query);
|
|
1257
|
-
}, new() { ["null"] = true });
|
|
1074
|
+
RunStruct("select", "edge", true, input =>
|
|
1075
|
+
StructUtils.Select(Getp(input, "obj"), Getp(input, "query")));
|
|
1258
1076
|
}
|
|
1259
1077
|
|
|
1260
1078
|
[Fact]
|
|
1261
1079
|
public void SelectAlts()
|
|
1262
1080
|
{
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
input =>
|
|
1266
|
-
{
|
|
1267
|
-
var m = input as Dictionary<string, object?>;
|
|
1268
|
-
object? query = m?.GetValueOrDefault("query");
|
|
1269
|
-
object? obj = m?.GetValueOrDefault("obj");
|
|
1270
|
-
return (object?)StructUtils.Select(obj, query);
|
|
1271
|
-
}, new() { ["null"] = true });
|
|
1081
|
+
RunStruct("select", "alts", true, input =>
|
|
1082
|
+
StructUtils.Select(Getp(input, "obj"), Getp(input, "query")));
|
|
1272
1083
|
}
|
|
1273
1084
|
}
|