gitlab-experiment 0.5.1 → 0.5.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/gitlab/experiment/rspec.rb +86 -47
- data/lib/gitlab/experiment/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4b1d80362166d1e86dd434fffe2a8e31676440f48b578e4bfcca4624fc819a8
|
4
|
+
data.tar.gz: 4535076f1c77f3faefc92f59be23689a5412f462bda088b67a4fbbdb58c74254
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9d3445f7ee60be9d445760f103162861b1983c35ed6a9347e8703bc44c4bef2d7b154a62b2b05aa02c84471b8cfa95f91aa5521ee5743b9afa8ea5b4a4088eb
|
7
|
+
data.tar.gz: cb49261fe14971ff76799bac943e5826b04cad84982b8d061cbd7b2843a0817854772f2b3e8e55600023aff9b5266c0ba562df50c47bb90703cb686c4f973ebd
|
@@ -3,44 +3,78 @@
|
|
3
3
|
module Gitlab
|
4
4
|
class Experiment
|
5
5
|
module RSpecHelpers
|
6
|
-
def stub_experiments(experiments)
|
7
|
-
experiments.each
|
8
|
-
|
6
|
+
def stub_experiments(experiments, times = nil)
|
7
|
+
experiments.each { |experiment| wrapped_experiment(experiment, times) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def wrapped_experiment(experiment, times = nil, expected = false, &block)
|
11
|
+
klass, experiment_name, variant_name = *experiment_details(experiment)
|
12
|
+
base_klass = Configuration.base_class.constantize
|
9
13
|
|
10
|
-
|
11
|
-
|
14
|
+
# Set expectations on experiment classes so we can and_wrap_original with more specific args
|
15
|
+
experiment_klasses = base_klass.descendants.reject { |k| k == klass }
|
16
|
+
experiment_klasses.push(base_klass).each do |k|
|
17
|
+
allow(k).to receive(:new).and_call_original
|
18
|
+
end
|
12
19
|
|
13
|
-
|
14
|
-
# not an alternative that allows multiple wrappings of `new`.
|
15
|
-
allow_any_instance_of(klass).to receive(:enabled?).and_return(true)
|
20
|
+
receiver = receive(:new)
|
16
21
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
# Be specific for BaseClass calls
|
23
|
+
receiver = receiver.with(experiment_name, any_args) if experiment_name && klass == base_klass
|
24
|
+
|
25
|
+
receiver.exactly(times).times if times
|
26
|
+
|
27
|
+
# Set expectations on experiment class of interest
|
28
|
+
allow_or_expect_klass = expected ? expect(klass) : allow(klass)
|
29
|
+
allow_or_expect_klass.to receiver.and_wrap_original do |method, *original_args, &original_block|
|
30
|
+
method.call(*original_args).tap do |e|
|
31
|
+
# Stub internal methods before calling the original_block
|
32
|
+
allow(e).to receive(:enabled?).and_return(true)
|
33
|
+
|
34
|
+
if variant_name == true # passing true allows the rollout to do its job
|
35
|
+
allow(e).to receive(:experiment_group?).and_return(true)
|
36
|
+
else
|
37
|
+
allow(e).to receive(:resolve_variant_name).and_return(variant_name.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Stub/set expectations before calling the original_block
|
41
|
+
yield e if block
|
42
|
+
|
43
|
+
original_block.call(e) if original_block.present?
|
21
44
|
end
|
22
45
|
end
|
23
46
|
end
|
24
47
|
|
25
|
-
|
26
|
-
if shallow
|
27
|
-
yield experiment if block.present?
|
28
|
-
return experiment
|
29
|
-
end
|
48
|
+
private
|
30
49
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
instance
|
50
|
+
def experiment_details(experiment)
|
51
|
+
if experiment.is_a?(Symbol)
|
52
|
+
experiment_name = experiment
|
53
|
+
variant_name = nil
|
36
54
|
end
|
37
55
|
|
38
|
-
|
39
|
-
|
40
|
-
|
56
|
+
experiment_name, variant_name = *experiment if experiment.is_a?(Array)
|
57
|
+
|
58
|
+
base_klass = Configuration.base_class.constantize
|
59
|
+
variant_name = experiment.variant.name if experiment.is_a?(base_klass)
|
60
|
+
|
61
|
+
if experiment.class.name.nil? # Anonymous class instance
|
62
|
+
klass = experiment.class
|
63
|
+
elsif experiment.instance_of?(Class) # Class level stubbing, eg. "MyExperiment"
|
64
|
+
klass = experiment
|
41
65
|
else
|
42
|
-
|
66
|
+
experiment_name ||= experiment.instance_variable_get(:@name)
|
67
|
+
klass = base_klass.constantize(experiment_name)
|
68
|
+
end
|
69
|
+
|
70
|
+
if experiment_name && klass == base_klass
|
71
|
+
experiment_name = experiment_name.to_sym
|
72
|
+
|
73
|
+
# For experiment names like: "group/experiment-name"
|
74
|
+
experiment_name = experiment_name.to_s if experiment_name.inspect.include?('"')
|
43
75
|
end
|
76
|
+
|
77
|
+
[klass, experiment_name, variant_name]
|
44
78
|
end
|
45
79
|
end
|
46
80
|
|
@@ -135,34 +169,41 @@ module Gitlab
|
|
135
169
|
end
|
136
170
|
|
137
171
|
chain(:with_context) { |expected_context| @expected_context = expected_context }
|
138
|
-
|
172
|
+
|
173
|
+
chain(:on_next_instance) { @on_next_instance = true }
|
139
174
|
|
140
175
|
def expect_tracking_on(experiment, negated, event, *event_args)
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
176
|
+
klass = experiment.instance_of?(Class) ? experiment : experiment.class
|
177
|
+
unless klass <= Gitlab::Experiment
|
178
|
+
raise(
|
179
|
+
ArgumentError,
|
180
|
+
"track matcher is limited to experiment instances and classes"
|
181
|
+
)
|
182
|
+
end
|
183
|
+
|
184
|
+
expectations = proc do |e|
|
185
|
+
@experiment = e
|
186
|
+
allow(e).to receive(:track).and_call_original
|
146
187
|
|
147
188
|
if negated
|
148
|
-
expect(
|
189
|
+
expect(e).not_to receive(:track).with(*[event, *event_args])
|
149
190
|
else
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
191
|
+
if @expected_variant
|
192
|
+
expect(@experiment.variant.name).to eq(@expected_variant), failure_message(:variant, event)
|
193
|
+
end
|
154
194
|
|
155
|
-
|
156
|
-
|
157
|
-
|
195
|
+
if @expected_context
|
196
|
+
expect(@experiment.context.value).to include(@expected_context), failure_message(:context, event)
|
197
|
+
end
|
158
198
|
|
159
|
-
|
160
|
-
expect(@experiment.variant.name).to eq(@expected_variant), failure_message(:variant, expected_event)
|
199
|
+
expect(e).to receive(:track).with(*[event, *event_args]).and_call_original
|
161
200
|
end
|
201
|
+
end
|
162
202
|
|
163
|
-
|
164
|
-
|
165
|
-
|
203
|
+
if experiment.instance_of?(Class) || @on_next_instance
|
204
|
+
wrapped_experiment(experiment, nil, true) { |e| expectations.call(e) }
|
205
|
+
else
|
206
|
+
expectations.call(experiment)
|
166
207
|
end
|
167
208
|
end
|
168
209
|
|
@@ -180,8 +221,6 @@ module Gitlab
|
|
180
221
|
expected context: #{@expected_context}
|
181
222
|
actual context: #{@experiment.context.value}
|
182
223
|
MESSAGE
|
183
|
-
when :no_new
|
184
|
-
%(expected #{@experiment.inspect} to have tracked #{event.inspect}, but no new instances were created)
|
185
224
|
end
|
186
225
|
end
|
187
226
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-experiment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|