verdict 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/verdict/experiment.rb +14 -11
- data/lib/verdict/version.rb +1 -1
- data/test/experiment_test.rb +33 -0
- 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: 3a261f90b676053938c42f341b2383b79bb4441ab5a0d2493515f1f90402b5f5
|
4
|
+
data.tar.gz: 1e9759c2062f9671d12bb53dc591f41615e2dd2d43910892fa28bc44042871c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a80328ac1da8ad852d0578df8d16ab435277c39249876b0ed3288d41be8f24fe88155588efd848d7431f053b0d1bcfaa76331451fce7aed8327b81ac59f24484
|
7
|
+
data.tar.gz: 27559293e140391710c4d5cf011bf8cc6418c52fd028943badf21a9e8ce802f39fc0608f479b64d343f9d3ea6c1759f9a53644750dcbf27cde28ef2ee15d470f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
## v0.15.0
|
2
|
+
* Add optional `qualifiers` parameter to the `Verdict::Experiment#switch` method. This parameter accepts an array of procs and is used as additional qualifiers. The purpose of this parameter is to allow users to define qualification logic outside of the experiment definition.
|
3
|
+
|
1
4
|
## v0.14.0
|
2
5
|
* Add optional experiment definition method `schedule_stop_new_assignment_timestamp` to support limiting experiment's assignment lifetime with another pre-determined time interval. It allows users to have an assignment cooldown period for stable analysis of the experiment results. Experiment's lifetime now becomes: start experiment -> stop new assignments -> end experiment.
|
3
6
|
|
data/lib/verdict/experiment.rb
CHANGED
@@ -142,18 +142,18 @@ class Verdict::Experiment
|
|
142
142
|
raise unless disqualify_empty_identifier?
|
143
143
|
end
|
144
144
|
|
145
|
-
def assign(subject, context = nil)
|
145
|
+
def assign(subject, context = nil, dynamic_qualifiers: [])
|
146
146
|
previous_assignment = lookup(subject)
|
147
147
|
|
148
148
|
subject_identifier = retrieve_subject_identifier(subject)
|
149
149
|
assignment = if previous_assignment
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
150
|
+
previous_assignment
|
151
|
+
elsif subject_qualifies?(subject, dynamic_qualifiers, context) && is_make_new_assignments?
|
152
|
+
group = segmenter.assign(subject_identifier, subject, context)
|
153
|
+
subject_assignment(subject, group, nil, group.nil?)
|
154
|
+
else
|
155
|
+
nil_assignment(subject)
|
156
|
+
end
|
157
157
|
|
158
158
|
store_assignment(assignment)
|
159
159
|
rescue Verdict::StorageError
|
@@ -194,9 +194,11 @@ class Verdict::Experiment
|
|
194
194
|
@storage.remove_assignment(self, subject)
|
195
195
|
end
|
196
196
|
|
197
|
-
|
197
|
+
# The qualifiers param accepts an array of procs.
|
198
|
+
# This is intended for qualification logic that cannot be defined in the experiment definition
|
199
|
+
def switch(subject, context = nil, qualifiers: [])
|
198
200
|
return unless is_scheduled?
|
199
|
-
assign(subject, context).to_sym
|
201
|
+
assign(subject, context, dynamic_qualifiers: qualifiers).to_sym
|
200
202
|
end
|
201
203
|
|
202
204
|
def lookup(subject)
|
@@ -241,8 +243,9 @@ class Verdict::Experiment
|
|
241
243
|
@disqualify_empty_identifier
|
242
244
|
end
|
243
245
|
|
244
|
-
def subject_qualifies?(subject, context = nil)
|
246
|
+
def subject_qualifies?(subject, dynamic_qualifiers, context = nil)
|
245
247
|
ensure_experiment_has_started
|
248
|
+
return false unless dynamic_qualifiers.all? { |qualifier| qualifier.call(subject) }
|
246
249
|
everybody_qualifies? || @qualifiers.all? { |qualifier| qualifier.call(subject, context) }
|
247
250
|
end
|
248
251
|
|
data/lib/verdict/version.rb
CHANGED
data/test/experiment_test.rb
CHANGED
@@ -641,6 +641,39 @@ class ExperimentTest < Minitest::Test
|
|
641
641
|
assert_nil e.switch(1)
|
642
642
|
end
|
643
643
|
end
|
644
|
+
|
645
|
+
def test_custom_qualifiers_success
|
646
|
+
e = Verdict::Experiment.new('test') do
|
647
|
+
groups do
|
648
|
+
group :all, 100
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
652
|
+
subject = 2
|
653
|
+
custom_qualifier_a = Proc.new { |subject| subject.even? }
|
654
|
+
custom_qualifier_b = Proc.new { |subject| subject > 0 }
|
655
|
+
|
656
|
+
group = e.switch(subject, qualifiers: [custom_qualifier_a, custom_qualifier_b])
|
657
|
+
assert_equal e.group(:all).to_sym, group
|
658
|
+
end
|
659
|
+
|
660
|
+
def test_custom_qualifiers_failure
|
661
|
+
e = Verdict::Experiment.new('test') do
|
662
|
+
groups do
|
663
|
+
group :all, 100
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
subject = 3
|
668
|
+
custom_qualifier_a = Proc.new { |subject| subject.even? }
|
669
|
+
custom_qualifier_b = Proc.new { |subject| subject > 0 }
|
670
|
+
|
671
|
+
e.switch(subject, qualifiers: [custom_qualifier_a, custom_qualifier_b])
|
672
|
+
|
673
|
+
group = e.switch(subject, qualifiers: [custom_qualifier_a, custom_qualifier_b])
|
674
|
+
assert_nil group
|
675
|
+
end
|
676
|
+
|
644
677
|
private
|
645
678
|
|
646
679
|
def redis
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: verdict
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|