@voxgig/sdkgen 0.36.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/cmp/Main.js +0 -12
- package/dist/cmp/Main.js.map +1 -1
- package/package.json +1 -1
- package/project/.sdk/src/cmp/go/Config_go.ts +6 -2
- package/project/.sdk/src/cmp/js/EntityBase_js.ts +34 -0
- package/project/.sdk/src/cmp/js/Main_js.ts +10 -0
- package/project/.sdk/src/cmp/js/ReadmeExplanation_js.ts +33 -0
- package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +123 -0
- package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +152 -0
- package/project/.sdk/src/cmp/js/ReadmeTopHowto_js.ts +25 -0
- package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +65 -0
- package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +36 -0
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +53 -5
- package/project/.sdk/src/cmp/js/TestEntity_js.ts +114 -20
- package/project/.sdk/src/cmp/js/fragment/Entity.fragment.js +7 -139
- package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +149 -0
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +6 -10
- package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +6 -10
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -11
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -11
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -11
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +2 -0
- package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +0 -2
- package/project/.sdk/src/cmp/lua/Config_lua.ts +6 -2
- package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +3 -1
- package/project/.sdk/src/cmp/php/Config_php.ts +6 -2
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +2 -2
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +10 -15
- package/project/.sdk/src/cmp/py/Config_py.ts +6 -2
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +3 -1
- package/project/.sdk/src/cmp/rb/Config_rb.ts +6 -2
- package/project/.sdk/src/cmp/ts/Main_ts.ts +7 -0
- package/project/.sdk/tm/go/feature/log_feature.go +1 -1
- package/project/.sdk/tm/go/test/runner_test.go +16 -2
- package/project/.sdk/tm/js/src/Context.js +142 -0
- package/project/.sdk/tm/js/src/Control.js +16 -0
- package/project/.sdk/tm/js/src/Operation.js +19 -0
- package/project/.sdk/tm/js/src/Point.js +24 -0
- package/project/.sdk/tm/js/src/README.md +1 -0
- package/project/.sdk/tm/js/src/Response.js +19 -0
- package/project/.sdk/tm/js/src/Result.js +21 -0
- package/project/.sdk/tm/js/src/Spec.js +26 -0
- package/project/.sdk/tm/js/src/feature/README.md +1 -0
- package/project/.sdk/tm/js/src/feature/base/BaseFeature.js +45 -0
- package/project/.sdk/tm/js/src/feature/log/LogFeature.js +46 -47
- package/project/.sdk/tm/js/src/feature/test/TestFeature.js +207 -0
- package/project/.sdk/tm/js/src/types.js +22 -0
- package/project/.sdk/tm/js/src/utility/CleanUtility.js +31 -0
- package/project/.sdk/tm/js/src/utility/DoneUtility.js +11 -4
- package/project/.sdk/tm/js/src/utility/FeatureAddUtility.js +42 -0
- package/project/.sdk/tm/js/src/utility/FeatureHookUtility.js +25 -0
- package/project/.sdk/tm/js/src/utility/FeatureInitUtility.js +11 -0
- package/project/.sdk/tm/js/src/utility/FetcherUtility.js +28 -0
- package/project/.sdk/tm/js/src/utility/MakeContextUtility.js +11 -0
- package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +55 -0
- package/project/.sdk/tm/js/src/utility/MakeFetchDefUtility.js +44 -0
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +93 -0
- package/project/.sdk/tm/js/src/utility/MakePointUtility.js +77 -0
- package/project/.sdk/tm/js/src/utility/MakeRequestUtility.js +63 -0
- package/project/.sdk/tm/js/src/utility/MakeResponseUtility.js +55 -0
- package/project/.sdk/tm/js/src/utility/MakeResultUtility.js +54 -0
- package/project/.sdk/tm/js/src/utility/MakeSpecUtility.js +58 -0
- package/project/.sdk/tm/js/src/utility/MakeUrlUtility.js +40 -0
- package/project/.sdk/tm/js/src/utility/ParamUtility.js +61 -0
- package/project/.sdk/tm/js/src/utility/PrepareAuthUtility.js +41 -0
- package/project/.sdk/tm/js/src/utility/PrepareBodyUtility.js +25 -0
- package/project/.sdk/tm/js/src/utility/PrepareHeadersUtility.js +18 -0
- package/project/.sdk/tm/js/src/utility/{MethodUtility.js → PrepareMethodUtility.js} +7 -7
- package/project/.sdk/tm/js/src/utility/PrepareParamsUtility.js +25 -0
- package/project/.sdk/tm/js/src/utility/PreparePathUtility.js +13 -0
- package/project/.sdk/tm/js/src/utility/PrepareQueryUtility.js +26 -0
- package/project/.sdk/tm/js/src/utility/README.md +1 -0
- package/project/.sdk/tm/js/src/utility/ResultBasicUtility.js +34 -0
- package/project/.sdk/tm/js/src/utility/ResultBodyUtility.js +18 -0
- package/project/.sdk/tm/js/src/utility/ResultHeadersUtility.js +22 -0
- package/project/.sdk/tm/js/src/utility/StructUtility.js +2219 -1078
- package/project/.sdk/tm/js/src/utility/TransformRequestUtility.js +28 -0
- package/project/.sdk/tm/js/src/utility/TransformResponseUtility.js +31 -0
- package/project/.sdk/tm/js/src/utility/Utility.js +61 -61
- package/project/.sdk/tm/js/test/README.md +1 -0
- package/project/.sdk/tm/js/test/exists.test.js +16 -0
- package/project/.sdk/tm/js/test/runner.js +323 -107
- package/project/.sdk/tm/js/test/utility/Custom.test.js +41 -63
- package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +390 -116
- package/project/.sdk/tm/js/test/utility/StructUtility.test.js +728 -175
- package/project/.sdk/tm/js/test/utility/index.js +9 -0
- package/project/.sdk/tm/js/test/utility.js +72 -0
- package/project/.sdk/tm/lua/test/primary_utility_test.lua +1213 -0
- package/project/.sdk/tm/lua/test/runner.lua +2 -2
- package/project/.sdk/tm/lua/test/struct_runner.lua +602 -0
- package/project/.sdk/tm/lua/test/struct_utility_test.lua +959 -0
- package/project/.sdk/tm/lua/utility/struct/struct.lua +10 -0
- package/project/.sdk/tm/php/feature/TestFeature.php +59 -96
- package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +1309 -0
- package/project/.sdk/tm/php/test/Runner.php +24 -1
- package/project/.sdk/tm/php/test/StructRunner.php +275 -0
- package/project/.sdk/tm/php/test/StructUtilityTest.php +1336 -0
- package/project/.sdk/tm/php/utility/Fetcher.php +6 -2
- package/project/.sdk/tm/php/utility/MakeOptions.php +5 -1
- package/project/.sdk/tm/php/utility/MakeResult.php +3 -0
- package/project/.sdk/tm/php/utility/Param.php +9 -7
- package/project/.sdk/tm/php/utility/struct/Struct.php +312 -208
- package/project/.sdk/tm/py/test/runner.py +13 -0
- package/project/.sdk/tm/py/test/struct_runner.py +411 -0
- package/project/.sdk/tm/py/test/test_primary_utility.py +1101 -0
- package/project/.sdk/tm/py/test/test_struct_utility.py +751 -0
- package/project/.sdk/tm/rb/test/primary_utility_test.rb +1083 -0
- package/project/.sdk/tm/rb/test/runner.rb +5 -0
- package/project/.sdk/tm/rb/test/struct_runner.rb +309 -0
- package/project/.sdk/tm/rb/test/struct_utility_test.rb +670 -0
- package/src/cmp/Main.ts +1 -16
- package/project/.sdk/src/cmp/js/Quick_js.ts +0 -78
- package/project/.sdk/src/cmp/js/TestAcceptEntity_js.ts +0 -13
- package/project/.sdk/src/cmp/js/TestAccept_js.ts +0 -18
- package/project/.sdk/tm/js/src/utility/AuthUtility.js +0 -21
- package/project/.sdk/tm/js/src/utility/BodyUtility.js +0 -29
- package/project/.sdk/tm/js/src/utility/ErrorUtility.js +0 -33
- package/project/.sdk/tm/js/src/utility/FindparamUtility.js +0 -31
- package/project/.sdk/tm/js/src/utility/FullurlUtility.js +0 -39
- package/project/.sdk/tm/js/src/utility/HeadersUtility.js +0 -13
- package/project/.sdk/tm/js/src/utility/JoinurlUtility.js +0 -14
- package/project/.sdk/tm/js/src/utility/OperatorUtility.js +0 -44
- package/project/.sdk/tm/js/src/utility/OptionsUtility.js +0 -54
- package/project/.sdk/tm/js/src/utility/ParamsUtility.js +0 -21
- package/project/.sdk/tm/js/src/utility/QueryUtility.js +0 -21
- package/project/.sdk/tm/js/src/utility/ReqformUtility.js +0 -32
- package/project/.sdk/tm/js/src/utility/RequestUtility.js +0 -48
- package/project/.sdk/tm/js/src/utility/ResbasicUtility.js +0 -27
- package/project/.sdk/tm/js/src/utility/ResbodyUtility.js +0 -15
- package/project/.sdk/tm/js/src/utility/ResformUtility.js +0 -34
- package/project/.sdk/tm/js/src/utility/ResheadersUtility.js +0 -19
- package/project/.sdk/tm/js/src/utility/ResponseUtility.js +0 -37
- package/project/.sdk/tm/js/src/utility/ResultUtility.js +0 -28
- package/project/.sdk/tm/js/src/utility/SpecUtility.js +0 -35
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Vendored from voxgig/struct/rb
|
|
2
|
+
# Test runner that uses the test model in .sdk/test.
|
|
3
|
+
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'pathname'
|
|
6
|
+
require_relative '../utility/struct/voxgig_struct'
|
|
7
|
+
|
|
8
|
+
module StructRunner
|
|
9
|
+
NULLMARK = "__NULL__" # Represents a JSON null in tests
|
|
10
|
+
UNDEFMARK = "__UNDEF__" # Represents an undefined value
|
|
11
|
+
|
|
12
|
+
# make_runner(testfile, client)
|
|
13
|
+
# Returns a lambda that accepts a name (e.g. "struct") and an optional store,
|
|
14
|
+
# and returns a hash (runpack) with:
|
|
15
|
+
# :spec -> the extracted spec for that name,
|
|
16
|
+
# :runset -> a lambda to run a test set without extra flags,
|
|
17
|
+
# :runsetflags -> a lambda to run a test set with flags,
|
|
18
|
+
# :subject -> the function (or object method) under test,
|
|
19
|
+
# :client -> the client instance.
|
|
20
|
+
def self.make_runner(testfile, client)
|
|
21
|
+
lambda do |name, store = {}|
|
|
22
|
+
store ||= {}
|
|
23
|
+
|
|
24
|
+
utility = client.utility
|
|
25
|
+
struct_utils = utility.struct
|
|
26
|
+
|
|
27
|
+
spec = resolve_spec(name, testfile)
|
|
28
|
+
clients = resolve_clients(client, spec, store, struct_utils)
|
|
29
|
+
subject = resolve_subject(name, utility)
|
|
30
|
+
|
|
31
|
+
runsetflags = lambda do |testspec, flags, testsubject|
|
|
32
|
+
subject = testsubject || subject
|
|
33
|
+
flags = resolve_flags(flags)
|
|
34
|
+
testspecmap = fix_json(testspec, flags)
|
|
35
|
+
testset = testspecmap["set"] || []
|
|
36
|
+
testset.each do |entry|
|
|
37
|
+
begin
|
|
38
|
+
entry = resolve_entry(entry, flags)
|
|
39
|
+
# Log the test entry details if DEBUG is enabled.
|
|
40
|
+
puts "DEBUG: Running test entry: in=#{entry['in'].inspect} expected=#{entry['out'].inspect}" if ENV['DEBUG']
|
|
41
|
+
testpack = resolve_test_pack(name, entry, subject, client, clients)
|
|
42
|
+
args = resolve_args(entry, testpack, struct_utils)
|
|
43
|
+
# Log the arguments passed to subject.
|
|
44
|
+
puts "DEBUG: Arguments for subject: #{args.inspect}" if ENV['DEBUG']
|
|
45
|
+
# In Ruby we assume the subject is a Proc/lambda or a callable object.
|
|
46
|
+
res = testpack[:subject].call(*args)
|
|
47
|
+
entry["args"] = args
|
|
48
|
+
res = fix_json(res, flags)
|
|
49
|
+
entry["res"] = res
|
|
50
|
+
# Log the result obtained.
|
|
51
|
+
puts "DEBUG: Result obtained: #{struct_utils.stringify(res)}" if ENV['DEBUG']
|
|
52
|
+
check_result(entry, res, struct_utils)
|
|
53
|
+
rescue => err
|
|
54
|
+
handle_error(entry, err, struct_utils)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
runset = lambda do |testspec, testsubject|
|
|
60
|
+
runsetflags.call(testspec, {}, testsubject)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
{ spec: spec, runset: runset, runsetflags: runsetflags, subject: subject, client: client }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Loads the test JSON file and extracts the spec for the given name.
|
|
68
|
+
# Follows the pattern: alltests.primary?[name] || alltests[name] || alltests.
|
|
69
|
+
def self.resolve_spec(name, testfile)
|
|
70
|
+
full_path = testfile
|
|
71
|
+
all_tests = JSON.parse(File.read(full_path))
|
|
72
|
+
if all_tests.key?("primary") && all_tests["primary"].key?(name)
|
|
73
|
+
spec = all_tests["primary"][name]
|
|
74
|
+
elsif all_tests.key?(name)
|
|
75
|
+
spec = all_tests[name]
|
|
76
|
+
else
|
|
77
|
+
spec = all_tests
|
|
78
|
+
end
|
|
79
|
+
spec
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# If the spec contains a DEF section with client definitions, resolve them.
|
|
83
|
+
# For each defined client, obtain its test instance via client.test(options).
|
|
84
|
+
def self.resolve_clients(client, spec, store, struct_utils)
|
|
85
|
+
clients = {}
|
|
86
|
+
if spec["DEF"] && spec["DEF"]["client"]
|
|
87
|
+
spec["DEF"]["client"].each do |cn, cdef|
|
|
88
|
+
copts = (cdef["test"] && cdef["test"]["options"]) || {}
|
|
89
|
+
# If there is an injection method defined, apply it.
|
|
90
|
+
if store.is_a?(Hash) && struct_utils.respond_to?(:inject)
|
|
91
|
+
struct_utils.inject(copts, store)
|
|
92
|
+
end
|
|
93
|
+
clients[cn] = client.test(copts)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
clients
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Returns the subject under test.
|
|
100
|
+
# In TS, resolveSubject returns container?.[name] (or the provided subject).
|
|
101
|
+
def self.resolve_subject(name, container, subject = nil)
|
|
102
|
+
if subject
|
|
103
|
+
subject
|
|
104
|
+
elsif container.respond_to?(name)
|
|
105
|
+
container.send(name)
|
|
106
|
+
else
|
|
107
|
+
container[name]
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Ensure flags is a hash and set "null" flag to true if not provided.
|
|
112
|
+
def self.resolve_flags(flags)
|
|
113
|
+
flags ||= {}
|
|
114
|
+
flags["null"] = true unless flags.key?("null")
|
|
115
|
+
flags
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# If the entry's "out" field is nil and the flag "null" is true, substitute NULLMARK.
|
|
119
|
+
def self.resolve_entry(entry, flags)
|
|
120
|
+
entry["out"] = (entry["out"].nil? && flags["null"]) ? NULLMARK : entry["out"]
|
|
121
|
+
entry
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Checks that the actual result matches the expected output.
|
|
125
|
+
# Uses a deep equality check (via JSON round-trip) and may use a "match" clause.
|
|
126
|
+
def self.check_result(entry, res, struct_utils)
|
|
127
|
+
matched = false
|
|
128
|
+
if entry.key?("match")
|
|
129
|
+
result = { "in" => entry["in"], "out" => entry["res"], "ctx" => entry["ctx"], "args" => entry["args"] }
|
|
130
|
+
match(entry["match"], result, struct_utils)
|
|
131
|
+
matched = true
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Log expected and actual values before comparison.
|
|
135
|
+
puts "DEBUG check_result: expected=#{struct_utils.stringify(entry['out'])} actual=#{struct_utils.stringify(res)}" if ENV['DEBUG']
|
|
136
|
+
|
|
137
|
+
if entry["out"] == res
|
|
138
|
+
return
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
if matched && (entry["out"] == NULLMARK || entry["out"].nil?)
|
|
142
|
+
return
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
unless deep_equal?(res, entry["out"])
|
|
146
|
+
raise "Mismatch: Expected #{struct_utils.stringify(entry['out'])} but got #{struct_utils.stringify(res)}"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# In case of error during test execution, handle it.
|
|
151
|
+
def self.handle_error(entry, err, struct_utils)
|
|
152
|
+
entry["thrown"] = err
|
|
153
|
+
if entry.key?("err")
|
|
154
|
+
if entry["err"] === true || matchval(entry["err"], err.message, struct_utils)
|
|
155
|
+
if entry.key?("match")
|
|
156
|
+
match(entry["match"], { "in" => entry["in"], "out" => entry["res"], "ctx" => entry["ctx"], "err" => err }, struct_utils)
|
|
157
|
+
end
|
|
158
|
+
return
|
|
159
|
+
end
|
|
160
|
+
raise "ERROR MATCH: [#{struct_utils.stringify(entry['err'])}] <=> [#{err.message}]"
|
|
161
|
+
else
|
|
162
|
+
raise err
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Resolves arguments for the test subject.
|
|
167
|
+
# By default, it passes a clone of entry["in"].
|
|
168
|
+
# If entry["ctx"] or entry["args"] is provided, use that instead.
|
|
169
|
+
# Also, if passing an object, inject client and utility.
|
|
170
|
+
def self.resolve_args(entry, testpack, struct_utils)
|
|
171
|
+
args = entry.key?("in") ? [struct_utils.clone(entry["in"])] : [VoxgigStruct::UNDEF]
|
|
172
|
+
if entry.key?("ctx")
|
|
173
|
+
args = [entry["ctx"]]
|
|
174
|
+
elsif entry.key?("args")
|
|
175
|
+
args = entry["args"]
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
if entry.key?("ctx") || entry.key?("args")
|
|
179
|
+
first = args[0]
|
|
180
|
+
if first.is_a?(Hash) && !first.nil?
|
|
181
|
+
entry["ctx"] = struct_utils.clone(first)
|
|
182
|
+
first["client"] = testpack[:client]
|
|
183
|
+
first["utility"] = testpack[:utility]
|
|
184
|
+
args[0] = first
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
args
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Resolves the test pack for a test entry.
|
|
191
|
+
# If the entry specifies a client override, use that client's utility and subject.
|
|
192
|
+
def self.resolve_test_pack(name, entry, subject, client, clients)
|
|
193
|
+
testpack = { client: client, subject: subject, utility: client.utility }
|
|
194
|
+
if entry.key?("client")
|
|
195
|
+
testpack[:client] = clients[entry["client"]]
|
|
196
|
+
testpack[:utility] = testpack[:client].utility
|
|
197
|
+
testpack[:subject] = resolve_subject(name, testpack[:utility])
|
|
198
|
+
end
|
|
199
|
+
testpack
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# A simple recursive walk function that iterates over scalars in a structure.
|
|
203
|
+
def self.walk(obj, path = [], &block)
|
|
204
|
+
if obj.is_a?(Hash)
|
|
205
|
+
obj.each do |k, v|
|
|
206
|
+
new_path = path + [k]
|
|
207
|
+
if v.is_a?(Hash) || v.is_a?(Array)
|
|
208
|
+
walk(v, new_path, &block)
|
|
209
|
+
else
|
|
210
|
+
yield(k, v, obj, new_path)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
elsif obj.is_a?(Array)
|
|
214
|
+
obj.each_with_index do |v, i|
|
|
215
|
+
new_path = path + [i]
|
|
216
|
+
if v.is_a?(Hash) || v.is_a?(Array)
|
|
217
|
+
walk(v, new_path, &block)
|
|
218
|
+
else
|
|
219
|
+
yield(i, v, obj, new_path)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Compares scalar values along each path of the check structure against the base.
|
|
226
|
+
def self.match(check, base, struct_utils)
|
|
227
|
+
walk(check) do |_key, val, _parent, path|
|
|
228
|
+
scalar = !(val.is_a?(Hash) || val.is_a?(Array))
|
|
229
|
+
if scalar
|
|
230
|
+
baseval = struct_utils.getpath(base, path)
|
|
231
|
+
next if baseval == val
|
|
232
|
+
next if val == UNDEFMARK && baseval.nil?
|
|
233
|
+
unless matchval(val, baseval, struct_utils)
|
|
234
|
+
raise "MATCH: #{path.join('.')} : [#{struct_utils.stringify(val)}] <=> [#{struct_utils.stringify(baseval)}]"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Returns true if check and base are considered matching.
|
|
241
|
+
# For strings, it allows regular expression-like syntax.
|
|
242
|
+
def self.matchval(check, base, struct_utils)
|
|
243
|
+
pass = (check == base)
|
|
244
|
+
unless pass
|
|
245
|
+
if check.is_a?(String)
|
|
246
|
+
basestr = struct_utils.stringify(base)
|
|
247
|
+
if check =~ /^\/(.+)\/$/
|
|
248
|
+
regex = Regexp.new($1)
|
|
249
|
+
pass = regex.match?(basestr)
|
|
250
|
+
else
|
|
251
|
+
pass = basestr.downcase.include?(struct_utils.stringify(check).downcase)
|
|
252
|
+
end
|
|
253
|
+
elsif check.respond_to?(:call)
|
|
254
|
+
pass = true
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
pass
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Uses JSON round-trip to test deep equality.
|
|
261
|
+
def self.deep_equal?(a, b)
|
|
262
|
+
normalize = lambda { |v|
|
|
263
|
+
case v
|
|
264
|
+
when Hash
|
|
265
|
+
sorted = {}
|
|
266
|
+
v.keys.sort.each { |k| sorted[k] = normalize.call(v[k]) }
|
|
267
|
+
sorted
|
|
268
|
+
when Array
|
|
269
|
+
v.map { |e| normalize.call(e) }
|
|
270
|
+
else
|
|
271
|
+
v
|
|
272
|
+
end
|
|
273
|
+
}
|
|
274
|
+
JSON.generate(normalize.call(a)) == JSON.generate(normalize.call(b))
|
|
275
|
+
rescue
|
|
276
|
+
a == b
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# Returns a deep copy of a value via JSON round-trip.
|
|
280
|
+
def self.fix_json(val, flags)
|
|
281
|
+
return flags["null"] ? NULLMARK : val if val.nil?
|
|
282
|
+
return flags["null"] ? NULLMARK : val if val.equal?(VoxgigStruct::UNDEF)
|
|
283
|
+
JSON.parse(JSON.generate(val))
|
|
284
|
+
rescue
|
|
285
|
+
val
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Applies a null modifier: if a value is "__NULL__", it replaces it with nil.
|
|
289
|
+
def self.null_modifier(val, key, parent)
|
|
290
|
+
if val == "__NULL__"
|
|
291
|
+
parent[key] = nil
|
|
292
|
+
elsif val.is_a?(String)
|
|
293
|
+
parent[key] = val.gsub("__NULL__", "null")
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# StructTestClient is a minimal shim that provides the client interface
|
|
299
|
+
# needed by the struct test runner within the SDK context.
|
|
300
|
+
class StructTestClient
|
|
301
|
+
def utility
|
|
302
|
+
require 'ostruct'
|
|
303
|
+
OpenStruct.new(struct: VoxgigStruct)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def test(options = {})
|
|
307
|
+
self
|
|
308
|
+
end
|
|
309
|
+
end
|