split 1.4.3 → 1.4.4
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/CHANGELOG.md +13 -0
- data/README.md +20 -10
- data/lib/split/encapsulated_helper.rb +3 -3
- data/lib/split/helper.rb +8 -12
- data/lib/split/trial.rb +6 -13
- data/lib/split/user.rb +29 -1
- data/lib/split/version.rb +1 -1
- data/spec/helper_spec.rb +30 -30
- data/spec/trial_spec.rb +1 -0
- data/spec/user_spec.rb +15 -8
- data/split.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3272611f8e1b67b852c92022c86d10c79d60adfa
|
4
|
+
data.tar.gz: 560dc5662f892e2dd5909c1d1588954bedf11feb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17cdb89c56142fccc390986303f156d1a71a6c65e1e2759c1ad96394dc8620ccf2515e9d3ecc8fad0f6db7503381c5cb056ac985b2ba235d6130a171f7d82441
|
7
|
+
data.tar.gz: 330ae49fc82430ec36f810f6b07e0a6b78802f9610b531d86995955284e4252fcc37d7d7ed63c69056f6a4c069d125492ceab2f40183ae11864b00a15cf86a4f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 1.4.4 (May 9th, 2016)
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- Increment participation if store override is true and no experiment key exists (@spheric, #380)
|
6
|
+
|
7
|
+
Misc:
|
8
|
+
|
9
|
+
- Deprecated `finished` method in favour of `ab_finished` (@andreibondarev, #389)
|
10
|
+
- Added minimum version requirement to simple-random
|
11
|
+
- Clarify finished with first option being a hash in Readme (@henrik, #382)
|
12
|
+
- Refactoring the User abstraction (@andreibondarev, #384)
|
13
|
+
|
1
14
|
## 1.4.3 (April 28th, 2016)
|
2
15
|
|
3
16
|
Features:
|
data/README.md
CHANGED
@@ -62,7 +62,7 @@ To begin your ab test use the `ab_test` method, naming your experiment with the
|
|
62
62
|
|
63
63
|
It can be used to render different templates, show different text or any other case based logic.
|
64
64
|
|
65
|
-
`
|
65
|
+
`ab_finished` is used to make a completion of an experiment, or conversion.
|
66
66
|
|
67
67
|
Example: View
|
68
68
|
|
@@ -86,14 +86,14 @@ Example: Conversion tracking (in a controller!)
|
|
86
86
|
```ruby
|
87
87
|
def buy_new_points
|
88
88
|
# some business logic
|
89
|
-
|
89
|
+
ab_finished(:new_user_free_points)
|
90
90
|
end
|
91
91
|
```
|
92
92
|
|
93
93
|
Example: Conversion tracking (in a view)
|
94
94
|
|
95
95
|
```erb
|
96
|
-
Thanks for signing up, dude! <%
|
96
|
+
Thanks for signing up, dude! <% ab_finished(:signup_page_redesign) %>
|
97
97
|
```
|
98
98
|
|
99
99
|
You can find more examples, tutorials and guides on the [wiki](https://github.com/splitrb/split/wiki).
|
@@ -157,10 +157,10 @@ After choosing this option tests won't be started right after deploy, but after
|
|
157
157
|
|
158
158
|
When a user completes a test their session is reset so that they may start the test again in the future.
|
159
159
|
|
160
|
-
To stop this behaviour you can pass the following option to the `
|
160
|
+
To stop this behaviour you can pass the following option to the `ab_finished` method:
|
161
161
|
|
162
162
|
```ruby
|
163
|
-
|
163
|
+
ab_finished(:experiment_name, reset: false)
|
164
164
|
```
|
165
165
|
|
166
166
|
The user will then always see the alternative they started with.
|
@@ -445,7 +445,7 @@ ab_test(:my_first_experiment)
|
|
445
445
|
and:
|
446
446
|
|
447
447
|
```ruby
|
448
|
-
|
448
|
+
ab_finished(:my_first_experiment)
|
449
449
|
```
|
450
450
|
|
451
451
|
You can also add meta data for each experiment, very useful when you need more than an alternative name to change behaviour:
|
@@ -515,7 +515,7 @@ Your code may then track a completion using the metric instead of
|
|
515
515
|
the experiment name:
|
516
516
|
|
517
517
|
```ruby
|
518
|
-
|
518
|
+
ab_finished(:my_metric)
|
519
519
|
```
|
520
520
|
|
521
521
|
You can also create a new metric by instantiating and saving a new Metric object.
|
@@ -550,20 +550,30 @@ end
|
|
550
550
|
To complete a goal conversion, you do it like:
|
551
551
|
|
552
552
|
```ruby
|
553
|
-
|
553
|
+
ab_finished(link_color: "purchase")
|
554
554
|
```
|
555
555
|
|
556
|
-
|
556
|
+
Note that if you pass additional options, that should be a separate hash:
|
557
|
+
|
558
|
+
```ruby
|
559
|
+
ab_finished({ link_color: "purchase" }, reset: false)
|
560
|
+
```
|
561
|
+
|
562
|
+
**NOTE:** This does not mean that a single experiment can complete more than one goal.
|
563
|
+
|
564
|
+
Once you finish one of the goals, the test is considered to be completed, and finishing the other goal will no longer register. (Assuming the test runs with `reset: false`.)
|
557
565
|
|
558
566
|
**Good Example**: Test if listing Plan A first result in more conversions to Plan A (goal: "plana_conversion") or Plan B (goal: "planb_conversion").
|
559
567
|
|
560
568
|
**Bad Example**: Test if button color increases conversion rate through multiple steps of a funnel. THIS WILL NOT WORK.
|
561
569
|
|
570
|
+
**Bad Example**: Test both how button color affects signup *and* how it affects login, at the same time. THIS WILL NOT WORK.
|
571
|
+
|
562
572
|
### DB failover solution
|
563
573
|
|
564
574
|
Due to the fact that Redis has no automatic failover mechanism, it's
|
565
575
|
possible to switch on the `db_failover` config option, so that `ab_test`
|
566
|
-
and `
|
576
|
+
and `ab_finished` will not crash in case of a db failure. `ab_test` always
|
567
577
|
delivers alternative A (the first one) in that case.
|
568
578
|
|
569
579
|
It's also possible to set a `db_failover_on_db_error` callback (proc)
|
@@ -4,7 +4,7 @@
|
|
4
4
|
#
|
5
5
|
# This module exposes only two methods:
|
6
6
|
# - ab_test()
|
7
|
-
# -
|
7
|
+
# - ab_finished()
|
8
8
|
# that can safely be mixed into any class.
|
9
9
|
#
|
10
10
|
# Passes the instance of the class that it's mixed into to the
|
@@ -15,7 +15,7 @@ module Split
|
|
15
15
|
|
16
16
|
class ContextShim
|
17
17
|
include Split::Helper
|
18
|
-
public :ab_test, :finished
|
18
|
+
public :ab_test, :finished, :ab_finished
|
19
19
|
|
20
20
|
def initialize(context)
|
21
21
|
@context = context
|
@@ -44,7 +44,7 @@ module Split
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def ab_test_finished(*arguments)
|
47
|
-
warn 'DEPRECATION WARNING: ab_test_finished is deprecated and will be removed from Split
|
47
|
+
warn 'DEPRECATION WARNING: ab_test_finished is deprecated and will be removed from Split 2.0.0'
|
48
48
|
split_context_shim.finished *arguments
|
49
49
|
end
|
50
50
|
|
data/lib/split/helper.rb
CHANGED
@@ -59,7 +59,7 @@ module Split
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
62
|
+
def ab_finished(metric_descriptor, options = {:reset => true})
|
63
63
|
return if exclude_visitor? || Split.configuration.disabled?
|
64
64
|
metric_descriptor, goals = normalize_metric(metric_descriptor)
|
65
65
|
experiments = Metric.possible_experiments(metric_descriptor)
|
@@ -74,6 +74,11 @@ module Split
|
|
74
74
|
Split.configuration.db_failover_on_db_error.call(e)
|
75
75
|
end
|
76
76
|
|
77
|
+
def finished(metric_descriptor, options = {:reset => true})
|
78
|
+
warn 'DEPRECATION WARNING: finished method was renamed to ab_finished and will be removed in Split 2.0.0'
|
79
|
+
ab_finished(metric_descriptor, options)
|
80
|
+
end
|
81
|
+
|
77
82
|
def override_present?(experiment_name)
|
78
83
|
defined?(params) && params[experiment_name]
|
79
84
|
end
|
@@ -87,7 +92,7 @@ module Split
|
|
87
92
|
end
|
88
93
|
|
89
94
|
def begin_experiment(experiment, alternative_name = nil)
|
90
|
-
warn 'DEPRECATION WARNING: begin_experiment is deprecated and will be removed from Split
|
95
|
+
warn 'DEPRECATION WARNING: begin_experiment is deprecated and will be removed from Split 2.0.0'
|
91
96
|
alternative_name ||= experiment.control.name
|
92
97
|
ab_user[experiment.key] = alternative_name
|
93
98
|
alternative_name
|
@@ -115,16 +120,7 @@ module Split
|
|
115
120
|
end
|
116
121
|
|
117
122
|
def active_experiments
|
118
|
-
|
119
|
-
ab_user.keys.each do |key|
|
120
|
-
key_without_version = key.split(/\:\d(?!\:)/)[0]
|
121
|
-
Metric.possible_experiments(key_without_version).each do |experiment|
|
122
|
-
if !experiment.has_winner?
|
123
|
-
experiment_pairs[key_without_version] = ab_user[key]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
return experiment_pairs
|
123
|
+
ab_user.active_experiments
|
128
124
|
end
|
129
125
|
|
130
126
|
def normalize_metric(metric_descriptor)
|
data/lib/split/trial.rb
CHANGED
@@ -49,12 +49,15 @@ module Split
|
|
49
49
|
# method is guaranteed to only run once, and will skip the alternative choosing process if run
|
50
50
|
# a second time.
|
51
51
|
def choose!(context = nil)
|
52
|
-
@user.cleanup_old_experiments
|
52
|
+
@user.cleanup_old_experiments!
|
53
53
|
# Only run the process once
|
54
54
|
return alternative if @alternative_choosen
|
55
55
|
|
56
56
|
if override_is_alternative?
|
57
57
|
self.alternative = @options[:override]
|
58
|
+
if should_store_alternative? && !@user[@experiment.key]
|
59
|
+
self.alternative.increment_participation
|
60
|
+
end
|
58
61
|
elsif @options[:disabled] || Split.configuration.disabled?
|
59
62
|
self.alternative = @experiment.control
|
60
63
|
elsif @experiment.has_winner?
|
@@ -102,22 +105,12 @@ module Split
|
|
102
105
|
|
103
106
|
def cleanup_old_versions
|
104
107
|
if @experiment.version > 0
|
105
|
-
|
106
|
-
keys_without_experiment(keys).each { |key| @user.delete(key) }
|
108
|
+
@user.cleanup_old_versions!(@experiment)
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
110
112
|
def exclude_user?
|
111
|
-
@options[:exclude] || @experiment.start_time.nil? || max_experiments_reached?
|
112
|
-
end
|
113
|
-
|
114
|
-
def max_experiments_reached?
|
115
|
-
!Split.configuration.allow_multiple_experiments &&
|
116
|
-
keys_without_experiment(@user.keys).length > 0
|
117
|
-
end
|
118
|
-
|
119
|
-
def keys_without_experiment(keys)
|
120
|
-
keys.reject { |k| k.match(Regexp.new("^#{@experiment.key}(:finished)?$")) }
|
113
|
+
@options[:exclude] || @experiment.start_time.nil? || @user.max_experiments_reached?(@experiment.key)
|
121
114
|
end
|
122
115
|
end
|
123
116
|
end
|
data/lib/split/user.rb
CHANGED
@@ -8,7 +8,7 @@ module Split
|
|
8
8
|
@user = Split::Persistence.adapter.new(context)
|
9
9
|
end
|
10
10
|
|
11
|
-
def cleanup_old_experiments
|
11
|
+
def cleanup_old_experiments!
|
12
12
|
user.keys.each do |key|
|
13
13
|
experiment = ExperimentCatalog.find key_without_version(key)
|
14
14
|
if experiment.nil? || experiment.has_winner? || experiment.start_time.nil?
|
@@ -17,6 +17,34 @@ module Split
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
def max_experiments_reached?(experiment_key)
|
21
|
+
!Split.configuration.allow_multiple_experiments &&
|
22
|
+
keys_without_experiment(user.keys, experiment_key).length > 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def cleanup_old_versions!(experiment)
|
26
|
+
keys = user.keys.select { |k| k.match(Regexp.new(experiment.name)) }
|
27
|
+
keys_without_experiment(keys, experiment.key).each { |key| user.delete(key) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def active_experiments
|
31
|
+
experiment_pairs = {}
|
32
|
+
user.keys.each do |key|
|
33
|
+
Metric.possible_experiments(key_without_version(key)).each do |experiment|
|
34
|
+
if !experiment.has_winner?
|
35
|
+
experiment_pairs[key_without_version(key)] = user[key]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
experiment_pairs
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def keys_without_experiment(keys, experiment_key)
|
45
|
+
keys.reject { |k| k.match(Regexp.new("^#{experiment_key}(:finished)?$")) }
|
46
|
+
end
|
47
|
+
|
20
48
|
def key_without_version(key)
|
21
49
|
key.split(/\:\d(?!\:)/)[0]
|
22
50
|
end
|
data/lib/split/version.rb
CHANGED
data/spec/helper_spec.rb
CHANGED
@@ -231,7 +231,7 @@ describe Split::Helper do
|
|
231
231
|
end
|
232
232
|
end
|
233
233
|
|
234
|
-
describe '
|
234
|
+
describe 'ab_finished' do
|
235
235
|
before(:each) do
|
236
236
|
@experiment_name = 'link_color'
|
237
237
|
@alternatives = ['blue', 'red']
|
@@ -241,19 +241,19 @@ describe Split::Helper do
|
|
241
241
|
end
|
242
242
|
|
243
243
|
it 'should increment the counter for the completed alternative' do
|
244
|
-
|
244
|
+
ab_finished(@experiment_name)
|
245
245
|
new_completion_count = Split::Alternative.new(@alternative_name, @experiment_name).completed_count
|
246
246
|
expect(new_completion_count).to eq(@previous_completion_count + 1)
|
247
247
|
end
|
248
248
|
|
249
249
|
it "should set experiment's finished key if reset is false" do
|
250
|
-
|
250
|
+
ab_finished(@experiment_name, {:reset => false})
|
251
251
|
expect(ab_user[@experiment.key]).to eq(@alternative_name)
|
252
252
|
expect(ab_user[@experiment.finished_key]).to eq(true)
|
253
253
|
end
|
254
254
|
|
255
255
|
it 'should not increment the counter if reset is false and the experiment has been already finished' do
|
256
|
-
2.times {
|
256
|
+
2.times { ab_finished(@experiment_name, {:reset => false}) }
|
257
257
|
new_completion_count = Split::Alternative.new(@alternative_name, @experiment_name).completed_count
|
258
258
|
expect(new_completion_count).to eq(@previous_completion_count + 1)
|
259
259
|
end
|
@@ -266,7 +266,7 @@ describe Split::Helper do
|
|
266
266
|
# the button size experiment, finishing it should not increase the
|
267
267
|
# completion count for that alternative.
|
268
268
|
expect(lambda {
|
269
|
-
|
269
|
+
ab_finished('button_size')
|
270
270
|
}).not_to change { Split::Alternative.new('small', 'button_size').completed_count }
|
271
271
|
end
|
272
272
|
|
@@ -276,26 +276,26 @@ describe Split::Helper do
|
|
276
276
|
a = ab_test('button_size', 'small', 'big')
|
277
277
|
expect(a).to eq('small')
|
278
278
|
expect(lambda {
|
279
|
-
|
279
|
+
ab_finished('button_size')
|
280
280
|
}).not_to change { Split::Alternative.new(a, 'button_size').completed_count }
|
281
281
|
end
|
282
282
|
|
283
283
|
it "should clear out the user's participation from their session" do
|
284
284
|
expect(ab_user[@experiment.key]).to eq(@alternative_name)
|
285
|
-
|
285
|
+
ab_finished(@experiment_name)
|
286
286
|
expect(ab_user.keys).to be_empty
|
287
287
|
end
|
288
288
|
|
289
289
|
it "should not clear out the users session if reset is false" do
|
290
290
|
expect(ab_user[@experiment.key]).to eq(@alternative_name)
|
291
|
-
|
291
|
+
ab_finished(@experiment_name, {:reset => false})
|
292
292
|
expect(ab_user[@experiment.key]).to eq(@alternative_name)
|
293
293
|
expect(ab_user[@experiment.finished_key]).to eq(true)
|
294
294
|
end
|
295
295
|
|
296
296
|
it "should reset the users session when experiment is not versioned" do
|
297
297
|
expect(ab_user[@experiment.key]).to eq(@alternative_name)
|
298
|
-
|
298
|
+
ab_finished(@experiment_name)
|
299
299
|
expect(ab_user.keys).to be_empty
|
300
300
|
end
|
301
301
|
|
@@ -304,26 +304,26 @@ describe Split::Helper do
|
|
304
304
|
@alternative_name = ab_test(@experiment_name, *@alternatives)
|
305
305
|
|
306
306
|
expect(ab_user[@experiment.key]).to eq(@alternative_name)
|
307
|
-
|
307
|
+
ab_finished(@experiment_name)
|
308
308
|
expect(ab_user.keys).to be_empty
|
309
309
|
end
|
310
310
|
|
311
311
|
it "should do nothing where the experiment was not started by this user" do
|
312
312
|
ab_user = nil
|
313
|
-
expect(lambda {
|
313
|
+
expect(lambda { ab_finished('some_experiment_not_started_by_the_user') }).not_to raise_exception
|
314
314
|
end
|
315
315
|
|
316
316
|
context "when on_trial_complete is set" do
|
317
317
|
before { Split.configuration.on_trial_complete = :some_method }
|
318
318
|
it "should call the method" do
|
319
319
|
expect(self).to receive(:some_method)
|
320
|
-
|
320
|
+
ab_finished(@experiment_name)
|
321
321
|
end
|
322
322
|
|
323
323
|
it "should not call the method without alternative" do
|
324
324
|
ab_user[@experiment.key] = nil
|
325
325
|
expect(self).not_to receive(:some_method)
|
326
|
-
|
326
|
+
ab_finished(@experiment_name)
|
327
327
|
end
|
328
328
|
end
|
329
329
|
end
|
@@ -339,7 +339,7 @@ describe Split::Helper do
|
|
339
339
|
alternative = ab_test(:my_experiment)
|
340
340
|
experiment = Split::ExperimentCatalog.find :my_experiment
|
341
341
|
|
342
|
-
|
342
|
+
ab_finished :my_experiment
|
343
343
|
expect(ab_user[experiment.key]).to eq(alternative)
|
344
344
|
expect(ab_user[experiment.finished_key]).to eq(true)
|
345
345
|
end
|
@@ -369,7 +369,7 @@ describe Split::Helper do
|
|
369
369
|
:metric => :my_metric
|
370
370
|
}
|
371
371
|
should_finish_experiment :my_experiment
|
372
|
-
|
372
|
+
ab_finished :my_metric
|
373
373
|
end
|
374
374
|
|
375
375
|
it "completes all relevant tests" do
|
@@ -390,7 +390,7 @@ describe Split::Helper do
|
|
390
390
|
should_finish_experiment :exp_1
|
391
391
|
should_finish_experiment :exp_2, false
|
392
392
|
should_finish_experiment :exp_3
|
393
|
-
|
393
|
+
ab_finished :my_metric
|
394
394
|
end
|
395
395
|
|
396
396
|
it "passes reset option" do
|
@@ -404,7 +404,7 @@ describe Split::Helper do
|
|
404
404
|
alternative_name = ab_test(:my_exp)
|
405
405
|
exp = Split::ExperimentCatalog.find :my_exp
|
406
406
|
|
407
|
-
|
407
|
+
ab_finished :my_metric
|
408
408
|
expect(ab_user[exp.key]).to eq(alternative_name)
|
409
409
|
expect(ab_user[exp.finished_key]).to be_truthy
|
410
410
|
end
|
@@ -419,7 +419,7 @@ describe Split::Helper do
|
|
419
419
|
alternative_name = ab_test(:my_exp)
|
420
420
|
exp = Split::ExperimentCatalog.find :my_exp
|
421
421
|
|
422
|
-
|
422
|
+
ab_finished :my_metric, :reset => false
|
423
423
|
expect(ab_user[exp.key]).to eq(alternative_name)
|
424
424
|
expect(ab_user[exp.finished_key]).to be_truthy
|
425
425
|
end
|
@@ -432,7 +432,7 @@ describe Split::Helper do
|
|
432
432
|
previous_convertion_rate = Split::Alternative.new(alternative_name, 'link_color').conversion_rate
|
433
433
|
expect(previous_convertion_rate).to eq(0.0)
|
434
434
|
|
435
|
-
|
435
|
+
ab_finished('link_color')
|
436
436
|
|
437
437
|
new_convertion_rate = Split::Alternative.new(alternative_name, 'link_color').conversion_rate
|
438
438
|
expect(new_convertion_rate).to eq(1.0)
|
@@ -449,7 +449,7 @@ describe Split::Helper do
|
|
449
449
|
|
450
450
|
it 'should show a finished test' do
|
451
451
|
alternative = ab_test('def', '4', '5', '6')
|
452
|
-
|
452
|
+
ab_finished('def', {:reset => false})
|
453
453
|
expect(active_experiments.count).to eq 1
|
454
454
|
expect(active_experiments.first[0]).to eq "def"
|
455
455
|
expect(active_experiments.first[1]).to eq alternative
|
@@ -519,7 +519,7 @@ describe Split::Helper do
|
|
519
519
|
|
520
520
|
previous_completion_count = Split::Alternative.new(alternative_name, 'link_color').completed_count
|
521
521
|
|
522
|
-
|
522
|
+
ab_finished('link_color')
|
523
523
|
|
524
524
|
new_completion_count = Split::Alternative.new(alternative_name, 'link_color').completed_count
|
525
525
|
|
@@ -573,7 +573,7 @@ describe Split::Helper do
|
|
573
573
|
|
574
574
|
previous_completion_count = Split::Alternative.new(alternative_name, 'link_color').completed_count
|
575
575
|
|
576
|
-
|
576
|
+
ab_finished('link_color')
|
577
577
|
|
578
578
|
new_completion_count = Split::Alternative.new(alternative_name, 'link_color').completed_count
|
579
579
|
|
@@ -681,7 +681,7 @@ describe Split::Helper do
|
|
681
681
|
experiment.reset
|
682
682
|
expect(experiment.version).to eq(1)
|
683
683
|
|
684
|
-
|
684
|
+
ab_finished('link_color')
|
685
685
|
alternative = Split::Alternative.new(alternative_name, 'link_color')
|
686
686
|
expect(alternative.completed_count).to eq(0)
|
687
687
|
end
|
@@ -707,7 +707,7 @@ describe Split::Helper do
|
|
707
707
|
|
708
708
|
describe 'finished' do
|
709
709
|
it 'should raise an exception' do
|
710
|
-
expect(lambda {
|
710
|
+
expect(lambda { ab_finished('link_color') }).to raise_error(Errno::ECONNREFUSED)
|
711
711
|
end
|
712
712
|
end
|
713
713
|
|
@@ -724,7 +724,7 @@ describe Split::Helper do
|
|
724
724
|
|
725
725
|
it "should return control variable" do
|
726
726
|
expect(ab_test('link_color', 'blue', 'red')).to eq('blue')
|
727
|
-
expect(lambda {
|
727
|
+
expect(lambda { ab_finished('link_color') }).not_to raise_error
|
728
728
|
end
|
729
729
|
end
|
730
730
|
end
|
@@ -797,7 +797,7 @@ describe Split::Helper do
|
|
797
797
|
|
798
798
|
describe 'finished' do
|
799
799
|
it 'should not raise an exception' do
|
800
|
-
expect(lambda {
|
800
|
+
expect(lambda { ab_finished('link_color') }).not_to raise_error
|
801
801
|
end
|
802
802
|
|
803
803
|
it 'should call db_failover_on_db_error proc with error as parameter' do
|
@@ -808,7 +808,7 @@ describe Split::Helper do
|
|
808
808
|
end
|
809
809
|
|
810
810
|
expect(Split.configuration.db_failover_on_db_error).to receive(:call)
|
811
|
-
|
811
|
+
ab_finished('link_color')
|
812
812
|
end
|
813
813
|
end
|
814
814
|
end
|
@@ -929,7 +929,7 @@ describe Split::Helper do
|
|
929
929
|
experiment2 = Split::ExperimentCatalog.find_or_create('link_color2', 'blue', 'red')
|
930
930
|
alternative_name = ab_test('link_color', 'blue', 'red')
|
931
931
|
alternative_name2 = ab_test('link_color2', 'blue', 'red')
|
932
|
-
|
932
|
+
ab_finished('link_color2')
|
933
933
|
|
934
934
|
experiment2.alternatives.each do |alt|
|
935
935
|
expect(alt.unfinished_count).to eq(0)
|
@@ -958,7 +958,7 @@ describe Split::Helper do
|
|
958
958
|
end
|
959
959
|
end
|
960
960
|
|
961
|
-
describe "
|
961
|
+
describe "ab_finished" do
|
962
962
|
before do
|
963
963
|
@alternative_name = ab_test(@experiment, *@alternatives)
|
964
964
|
end
|
@@ -966,7 +966,7 @@ describe Split::Helper do
|
|
966
966
|
it "should increment the counter for the specified-goal completed alternative" do
|
967
967
|
expect(lambda {
|
968
968
|
expect(lambda {
|
969
|
-
|
969
|
+
ab_finished({"link_color" => ["purchase"]})
|
970
970
|
}).not_to change {
|
971
971
|
Split::Alternative.new(@alternative_name, @experiment_name).completed_count(@goal2)
|
972
972
|
}
|
data/spec/trial_spec.rb
CHANGED
data/spec/user_spec.rb
CHANGED
@@ -4,9 +4,9 @@ require 'split/experiment'
|
|
4
4
|
require 'split/user'
|
5
5
|
|
6
6
|
describe Split::User do
|
7
|
-
let(:
|
8
|
-
|
9
|
-
|
7
|
+
let(:user_keys) { { 'link_color' => 'blue' } }
|
8
|
+
let(:context) { double(:session => { split: user_keys }) }
|
9
|
+
let(:experiment) { Split::Experiment.new('link_color') }
|
10
10
|
|
11
11
|
before(:each) do
|
12
12
|
@subject = described_class.new(context)
|
@@ -16,11 +16,18 @@ describe Split::User do
|
|
16
16
|
expect(@subject['link_color']).to eq(@subject.user['link_color'])
|
17
17
|
end
|
18
18
|
|
19
|
-
context '#
|
20
|
-
let(:
|
19
|
+
context '#cleanup_old_versions!' do
|
20
|
+
let(:user_keys) { { 'link_color:1' => 'blue' } }
|
21
|
+
|
22
|
+
it 'removes key if old experiment is found' do
|
23
|
+
@subject.cleanup_old_versions!(experiment)
|
24
|
+
expect(@subject.keys).to be_empty
|
25
|
+
end
|
26
|
+
end
|
21
27
|
|
28
|
+
context '#cleanup_old_experiments!' do
|
22
29
|
it 'removes key if experiment is not found' do
|
23
|
-
@subject.cleanup_old_experiments
|
30
|
+
@subject.cleanup_old_experiments!
|
24
31
|
expect(@subject.keys).to be_empty
|
25
32
|
end
|
26
33
|
|
@@ -28,14 +35,14 @@ describe Split::User do
|
|
28
35
|
allow(Split::ExperimentCatalog).to receive(:find).with('link_color').and_return(experiment)
|
29
36
|
allow(experiment).to receive(:start_time).and_return(Date.today)
|
30
37
|
allow(experiment).to receive(:has_winner?).and_return(true)
|
31
|
-
@subject.cleanup_old_experiments
|
38
|
+
@subject.cleanup_old_experiments!
|
32
39
|
expect(@subject.keys).to be_empty
|
33
40
|
end
|
34
41
|
|
35
42
|
it 'removes key if experiment has not started yet' do
|
36
43
|
allow(Split::ExperimentCatalog).to receive(:find).with('link_color').and_return(experiment)
|
37
44
|
allow(experiment).to receive(:has_winner?).and_return(false)
|
38
|
-
@subject.cleanup_old_experiments
|
45
|
+
@subject.cleanup_old_experiments!
|
39
46
|
expect(@subject.keys).to be_empty
|
40
47
|
end
|
41
48
|
end
|
data/split.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_dependency 'redis', '>= 2.1'
|
24
24
|
s.add_dependency 'redis-namespace', '>= 1.1.0'
|
25
25
|
s.add_dependency 'sinatra', '>= 1.2.6'
|
26
|
-
s.add_dependency 'simple-random'
|
26
|
+
s.add_dependency 'simple-random', '>= 0.9.3'
|
27
27
|
|
28
28
|
s.add_development_dependency 'bundler', '~> 1.10'
|
29
29
|
s.add_development_dependency 'coveralls', '~> 0.8'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: split
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Nesbitt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.9.3
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.9.3
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -247,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
247
|
version: '0'
|
248
248
|
requirements: []
|
249
249
|
rubyforge_project: split
|
250
|
-
rubygems_version: 2.
|
250
|
+
rubygems_version: 2.6.4
|
251
251
|
signing_key:
|
252
252
|
specification_version: 4
|
253
253
|
summary: Rack based split testing framework
|