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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f05448f375933cba0d01c10a4e302b684242297e779d96cd3bf45cff2f6fea74
4
- data.tar.gz: d8782ab103377d758a550f36f16fa40cec2caa2662333a99d180aab637985126
3
+ metadata.gz: 3a261f90b676053938c42f341b2383b79bb4441ab5a0d2493515f1f90402b5f5
4
+ data.tar.gz: 1e9759c2062f9671d12bb53dc591f41615e2dd2d43910892fa28bc44042871c7
5
5
  SHA512:
6
- metadata.gz: 14317430460d1fcb88748507d20fd8be9f0a271d434951c6deb4b89203eeb3a5675a7c88e5e1d79bd6404c275bc3a9a3b35558a09df51284c100613963c4ba51
7
- data.tar.gz: 39ad70804de5c962785117525ccd668155efd228860735de13569316d22e6e3ed65e050842753c7283bc21c299ee237a00885686d6963a94e3130594f5c61b21
6
+ metadata.gz: a80328ac1da8ad852d0578df8d16ab435277c39249876b0ed3288d41be8f24fe88155588efd848d7431f053b0d1bcfaa76331451fce7aed8327b81ac59f24484
7
+ data.tar.gz: 27559293e140391710c4d5cf011bf8cc6418c52fd028943badf21a9e8ce802f39fc0608f479b64d343f9d3ea6c1759f9a53644750dcbf27cde28ef2ee15d470f
@@ -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
 
@@ -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
- previous_assignment
151
- elsif subject_qualifies?(subject, 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
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
- def switch(subject, context = nil)
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
 
@@ -1,3 +1,3 @@
1
1
  module Verdict
2
- VERSION = "0.14.0"
2
+ VERSION = "0.15.0"
3
3
  end
@@ -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.14.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-04-29 00:00:00.000000000 Z
11
+ date: 2020-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest