bitfab 0.38.1 → 0.38.2
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.
- checksums.yaml +4 -4
- data/lib/bitfab/client.rb +43 -14
- data/lib/bitfab/mock_override.rb +14 -6
- data/lib/bitfab/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29901e7611834921e9378870830af40c08e5af02d1ca0708585a02b169b12e6e
|
|
4
|
+
data.tar.gz: b42984a3710e9399159fd44af3aaac7b76e3155bd3121eaa5482aa27570fbb2e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 576a44cbe7e2fdf7270f14af3d8a98541bb2e15cd2b02289c18d58f033688d6797b2b3a0cfc8153f1ba8adbf0d72f9b9b9241e1bfd5fbd3ffcc687a4cb9adb44
|
|
7
|
+
data.tar.gz: ce3586fbdc541ffad387d87ca4299ee34df5e0c61a5c01a6b5112ee11084cb7900d6616f9e3db45ec0386fc019bc1712f267ea3c5799809880ae3611d3d30cb9
|
data/lib/bitfab/client.rb
CHANGED
|
@@ -122,14 +122,15 @@ module Bitfab
|
|
|
122
122
|
# traces were captured. Receives (args, kwargs, ctx) where ctx is
|
|
123
123
|
# { original_trace_id:, original_span_id: } (with deprecated
|
|
124
124
|
# source_trace_id/source_span_id aliases), and returns [new_args, new_kwargs].
|
|
125
|
-
# @param mock_override [Hash, Array<Hash>, nil] optional selective
|
|
126
|
-
# override(s),
|
|
125
|
+
# @param mock_override [Hash, Proc, Array<Hash, Proc>, nil] optional selective
|
|
126
|
+
# mock override(s), as { match:, value: } hashes or global resolvers. match is a callable:
|
|
127
127
|
# match.call(node) selects spans to substitute (node is
|
|
128
128
|
# { trace_function_key:, span_name:, type:, original_span_id: }). value is
|
|
129
129
|
# EITHER a flat value injected directly OR a callable invoked with
|
|
130
130
|
# { node:, inputs:, kwargs:, get_original_output: }; its result becomes
|
|
131
131
|
# the span's output (full replacement), so downstream real code runs against it. The
|
|
132
|
-
# first matching override
|
|
132
|
+
# first matching override that does not return NO_MOCK_OVERRIDE wins.
|
|
133
|
+
# Per-call overrides take precedence over
|
|
133
134
|
# those registered via register_mock_override, and both take precedence
|
|
134
135
|
# over the base mock strategy. The root span is never overridden.
|
|
135
136
|
# @param db_branch [Boolean, Hash, nil] +true+ or a Hash enables database
|
|
@@ -169,10 +170,9 @@ module Bitfab
|
|
|
169
170
|
# clear_mock_overrides to reset. Per-call replay(mock_override:) overrides
|
|
170
171
|
# take precedence, and both take precedence over the base mock strategy.
|
|
171
172
|
#
|
|
172
|
-
# Accepts
|
|
173
|
-
#
|
|
174
|
-
#
|
|
175
|
-
# with the ctx hash.
|
|
173
|
+
# Accepts the (match, value) positional form, the keyword/hash form, one
|
|
174
|
+
# global resolver callable, or (trace_function_key, override_or_resolver).
|
|
175
|
+
# A resolver can return Bitfab::NO_MOCK_OVERRIDE to decline the span.
|
|
176
176
|
#
|
|
177
177
|
# @example keyword form (primary), flat value
|
|
178
178
|
# client.register_mock_override(
|
|
@@ -186,19 +186,43 @@ module Bitfab
|
|
|
186
186
|
# ->(ctx) { {label: "refund", inputs: ctx[:inputs]} }
|
|
187
187
|
# )
|
|
188
188
|
#
|
|
189
|
-
# @param positional [Array]
|
|
190
|
-
#
|
|
189
|
+
# @param positional [Array] a (match, value) pair, one { match:, value: }
|
|
190
|
+
# hash, one global resolver, or a trace function key followed by a
|
|
191
|
+
# resolver or override hash
|
|
191
192
|
# @param match [#call, nil] keyword form matcher
|
|
192
193
|
# @param value [Object, #call, nil] keyword form injected value or producer
|
|
193
194
|
# @return [void]
|
|
194
195
|
def register_mock_override(*positional, match: nil, value: VALUE_UNSET)
|
|
195
196
|
if match.nil? && value.equal?(VALUE_UNSET)
|
|
196
|
-
if positional.length ==
|
|
197
|
+
if positional.length == 2 && positional[0].is_a?(String)
|
|
198
|
+
trace_function_key, keyed_override = positional
|
|
199
|
+
if keyed_override.is_a?(Hash) && keyed_override[:match].respond_to?(:call) && keyed_override.key?(:value)
|
|
200
|
+
keyed_match = keyed_override[:match]
|
|
201
|
+
@mock_overrides << {
|
|
202
|
+
match: ->(node) { node[:trace_function_key] == trace_function_key && keyed_match.call(node) },
|
|
203
|
+
value: keyed_override[:value]
|
|
204
|
+
}
|
|
205
|
+
return nil
|
|
206
|
+
end
|
|
207
|
+
if keyed_override.respond_to?(:call)
|
|
208
|
+
@mock_overrides << {
|
|
209
|
+
match: ->(node) { node[:trace_function_key] == trace_function_key },
|
|
210
|
+
value: keyed_override
|
|
211
|
+
}
|
|
212
|
+
return nil
|
|
213
|
+
end
|
|
214
|
+
raise ArgumentError,
|
|
215
|
+
"register_mock_override(trace_function_key, override) requires " \
|
|
216
|
+
"a { match:, value: } hash or callable resolver."
|
|
217
|
+
elsif positional.length == 1 && positional[0].is_a?(Hash)
|
|
197
218
|
override = positional[0]
|
|
198
219
|
match = override[:match]
|
|
199
220
|
# Distinguish an omitted :value from an explicit `value: nil`: the
|
|
200
221
|
# key's presence, not a nil read, is what marks it provided.
|
|
201
222
|
value = override.key?(:value) ? override[:value] : VALUE_UNSET
|
|
223
|
+
elsif positional.length == 1 && positional[0].respond_to?(:call)
|
|
224
|
+
@mock_overrides << {match: ->(_) { true }, value: positional[0]}
|
|
225
|
+
return nil
|
|
202
226
|
elsif positional.length == 2
|
|
203
227
|
match, value = positional
|
|
204
228
|
end
|
|
@@ -782,8 +806,9 @@ module Bitfab
|
|
|
782
806
|
type: span_type,
|
|
783
807
|
original_span_id: mock_entry && mock_entry[:source_span_id]
|
|
784
808
|
}
|
|
785
|
-
|
|
786
|
-
|
|
809
|
+
overrides.each do |override|
|
|
810
|
+
next unless override[:match].call(node)
|
|
811
|
+
|
|
787
812
|
value = override[:value]
|
|
788
813
|
# value is EITHER a flat value (injected directly) OR a callable
|
|
789
814
|
# invoked with the ctx hash. The result IS the span's output (full
|
|
@@ -791,7 +816,10 @@ module Bitfab
|
|
|
791
816
|
# override always injects, execute_span short-circuits even when this
|
|
792
817
|
# is nil (nil != MOCK_REPLAY_MISS). To inject a proc as the literal
|
|
793
818
|
# output, wrap it in a callable value.
|
|
794
|
-
|
|
819
|
+
unless value.respond_to?(:call)
|
|
820
|
+
return [value, "override"] unless value.equal?(NO_MOCK_OVERRIDE)
|
|
821
|
+
next
|
|
822
|
+
end
|
|
795
823
|
|
|
796
824
|
get_original_output = lambda do
|
|
797
825
|
unless mock_entry
|
|
@@ -799,7 +827,8 @@ module Bitfab
|
|
|
799
827
|
end
|
|
800
828
|
resolve_recorded_output(mock_entry, replay_ctx)
|
|
801
829
|
end
|
|
802
|
-
|
|
830
|
+
resolved = value.call({node:, inputs: args, kwargs:, get_original_output:})
|
|
831
|
+
return [resolved, "override"] unless resolved.equal?(NO_MOCK_OVERRIDE)
|
|
803
832
|
end
|
|
804
833
|
end
|
|
805
834
|
|
data/lib/bitfab/mock_override.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Bitfab
|
|
4
|
+
# Return from an override resolver to continue to the next override and then
|
|
5
|
+
# the replay's base mock strategy.
|
|
6
|
+
NO_MOCK_OVERRIDE = Object.new.freeze
|
|
7
|
+
|
|
4
8
|
# Selective mock overrides for replay. Mirrors the TypeScript SDK's
|
|
5
9
|
# mockOverride feature.
|
|
6
10
|
#
|
|
@@ -10,8 +14,10 @@ module Bitfab
|
|
|
10
14
|
# substituted output. This is a third mock mode alongside "run real code" and
|
|
11
15
|
# "replay recorded output" (see MOCK_STRATEGIES in replay.rb).
|
|
12
16
|
#
|
|
13
|
-
# An override is a (match, value) pair
|
|
14
|
-
#
|
|
17
|
+
# An override is a (match, value) pair represented as { match:, value: }, or
|
|
18
|
+
# one global resolver invoked for every child span. A resolver can route on
|
|
19
|
+
# ctx[:node][:trace_function_key] and return Bitfab::NO_MOCK_OVERRIDE to
|
|
20
|
+
# decline the current span.
|
|
15
21
|
#
|
|
16
22
|
# - match is a callable (proc/lambda): match.call(node) -> boolean. node is a
|
|
17
23
|
# structural-metadata hash { trace_function_key:, span_name:, type:,
|
|
@@ -38,9 +44,8 @@ module Bitfab
|
|
|
38
44
|
module MockOverride
|
|
39
45
|
module_function
|
|
40
46
|
|
|
41
|
-
# Normalize the per-call `mock_override` option (
|
|
42
|
-
#
|
|
43
|
-
# order is preserved.
|
|
47
|
+
# Normalize the per-call `mock_override` option (an override hash, a global
|
|
48
|
+
# resolver callable, an array, or nil) into an ordered override array.
|
|
44
49
|
#
|
|
45
50
|
# Each override is validated: it must be a hash with a callable `:match` and
|
|
46
51
|
# must include a `:value` key. A forgotten `:value` raises rather than
|
|
@@ -49,12 +54,15 @@ module Bitfab
|
|
|
49
54
|
# `register_mock_override`, and the Python/TypeScript SDKs, where the per-call
|
|
50
55
|
# override object requires a value.
|
|
51
56
|
#
|
|
52
|
-
# @param mock_override [Hash, Array<Hash>, nil]
|
|
57
|
+
# @param mock_override [Hash, Proc, Array<Hash, Proc>, nil]
|
|
53
58
|
# @return [Array<Hash>]
|
|
54
59
|
def normalize(mock_override)
|
|
55
60
|
return [] if mock_override.nil?
|
|
56
61
|
|
|
57
62
|
overrides = mock_override.is_a?(Array) ? mock_override : [mock_override]
|
|
63
|
+
overrides = overrides.map do |override|
|
|
64
|
+
override.respond_to?(:call) ? {match: ->(_) { true }, value: override} : override
|
|
65
|
+
end
|
|
58
66
|
overrides.each do |override|
|
|
59
67
|
unless override.is_a?(Hash) && override[:match].respond_to?(:call)
|
|
60
68
|
raise ArgumentError,
|
data/lib/bitfab/version.rb
CHANGED