split 1.4.3 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|