split 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -22
- data/Appraisals +5 -9
- data/{CHANGELOG.mdown → CHANGELOG.md} +17 -0
- data/Gemfile +1 -1
- data/LICENSE +2 -2
- data/{README.mdown → README.md} +3 -14
- data/gemfiles/4.0.gemfile +1 -1
- data/gemfiles/{3.1.gemfile → 4.1.gemfile} +1 -1
- data/lib/split/alternative.rb +1 -1
- data/lib/split/dashboard.rb +6 -6
- data/lib/split/experiment.rb +2 -19
- data/lib/split/experiment_catalog.rb +20 -11
- data/lib/split/helper.rb +36 -99
- data/lib/split/metric.rb +2 -2
- data/lib/split/persistence/redis_adapter.rb +4 -2
- data/lib/split/trial.rb +84 -22
- data/lib/split/version.rb +1 -1
- data/spec/algorithms/weighted_sample_spec.rb +3 -3
- data/spec/algorithms/whiplash_spec.rb +2 -2
- data/spec/alternative_spec.rb +1 -1
- data/spec/dashboard_spec.rb +3 -3
- data/spec/encapsulated_helper_spec.rb +2 -6
- data/spec/experiment_catalog_spec.rb +37 -0
- data/spec/experiment_spec.rb +26 -26
- data/spec/helper_spec.rb +55 -20
- data/spec/metric_spec.rb +5 -5
- data/spec/persistence/redis_adapter_spec.rb +9 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/trial_spec.rb +126 -29
- data/split.gemspec +3 -3
- metadata +28 -30
- data/changes.rtf +0 -14
- data/gemfiles/3.0.gemfile +0 -8
data/spec/helper_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Split::Helper do
|
|
6
6
|
include Split::Helper
|
7
7
|
|
8
8
|
let(:experiment) {
|
9
|
-
Split::
|
9
|
+
Split::ExperimentCatalog.find_or_create('link_color', 'blue', 'red')
|
10
10
|
}
|
11
11
|
|
12
12
|
describe "ab_test" do
|
@@ -53,7 +53,7 @@ describe Split::Helper do
|
|
53
53
|
|
54
54
|
it 'should not increment the counter for an experiment that the user is not participating in' do
|
55
55
|
ab_test('link_color', 'blue', 'red')
|
56
|
-
e = Split::
|
56
|
+
e = Split::ExperimentCatalog.find_or_create('button_size', 'small', 'big')
|
57
57
|
expect(lambda {
|
58
58
|
# User shouldn't participate in this second experiment
|
59
59
|
ab_test('button_size', 'small', 'big')
|
@@ -61,7 +61,7 @@ describe Split::Helper do
|
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'should not increment the counter for an ended experiment' do
|
64
|
-
e = Split::
|
64
|
+
e = Split::ExperimentCatalog.find_or_create('button_size', 'small', 'big')
|
65
65
|
e.winner = 'small'
|
66
66
|
expect(lambda {
|
67
67
|
a = ab_test('button_size', 'small', 'big')
|
@@ -71,7 +71,7 @@ describe Split::Helper do
|
|
71
71
|
|
72
72
|
it 'should not increment the counter for an not started experiment' do
|
73
73
|
expect(Split.configuration).to receive(:start_manually).and_return(true)
|
74
|
-
e = Split::
|
74
|
+
e = Split::ExperimentCatalog.find_or_create('button_size', 'small', 'big')
|
75
75
|
expect(lambda {
|
76
76
|
a = ab_test('button_size', 'small', 'big')
|
77
77
|
expect(a).to eq('small')
|
@@ -162,7 +162,7 @@ describe Split::Helper do
|
|
162
162
|
|
163
163
|
it "should allow alternative weighting interface as a single hash" do
|
164
164
|
ab_test('link_color', {'blue' => 0.01}, 'red' => 0.2)
|
165
|
-
experiment = Split::
|
165
|
+
experiment = Split::ExperimentCatalog.find('link_color')
|
166
166
|
expect(experiment.alternatives.map(&:name)).to eq(['blue', 'red'])
|
167
167
|
# TODO: persist alternative weights
|
168
168
|
# expect(experiment.alternatives.collect{|a| a.weight}).to eq([0.01, 0.2])
|
@@ -202,7 +202,7 @@ describe Split::Helper do
|
|
202
202
|
before(:each) do
|
203
203
|
@experiment_name = 'link_color'
|
204
204
|
@alternatives = ['blue', 'red']
|
205
|
-
@experiment = Split::
|
205
|
+
@experiment = Split::ExperimentCatalog.find_or_create(@experiment_name, *@alternatives)
|
206
206
|
@alternative_name = ab_test(@experiment_name, *@alternatives)
|
207
207
|
@previous_completion_count = Split::Alternative.new(@alternative_name, @experiment_name).completed_count
|
208
208
|
end
|
@@ -237,7 +237,7 @@ describe Split::Helper do
|
|
237
237
|
end
|
238
238
|
|
239
239
|
it 'should not increment the counter for an ended experiment' do
|
240
|
-
e = Split::
|
240
|
+
e = Split::ExperimentCatalog.find_or_create('button_size', 'small', 'big')
|
241
241
|
e.winner = 'small'
|
242
242
|
a = ab_test('button_size', 'small', 'big')
|
243
243
|
expect(a).to eq('small')
|
@@ -278,12 +278,6 @@ describe Split::Helper do
|
|
278
278
|
expect(lambda { finished('some_experiment_not_started_by_the_user') }).not_to raise_exception
|
279
279
|
end
|
280
280
|
|
281
|
-
it 'should not be doing other tests when it has completed one that has :reset => false' do
|
282
|
-
ab_user[@experiment.key] = @alternative_name
|
283
|
-
ab_user[@experiment.finished_key] = true
|
284
|
-
expect(doing_other_tests?(@experiment.key)).to be false
|
285
|
-
end
|
286
|
-
|
287
281
|
context "when on_trial_complete is set" do
|
288
282
|
before { Split.configuration.on_trial_complete = :some_method }
|
289
283
|
it "should call the method" do
|
@@ -308,7 +302,7 @@ describe Split::Helper do
|
|
308
302
|
}
|
309
303
|
}
|
310
304
|
alternative = ab_test(:my_experiment)
|
311
|
-
experiment = Split::
|
305
|
+
experiment = Split::ExperimentCatalog.find :my_experiment
|
312
306
|
|
313
307
|
finished :my_experiment
|
314
308
|
expect(ab_user).to eq(experiment.key => alternative, experiment.finished_key => true)
|
@@ -321,7 +315,7 @@ describe Split::Helper do
|
|
321
315
|
|
322
316
|
def should_finish_experiment(experiment_name, should_finish=true)
|
323
317
|
alts = Split.configuration.experiments[experiment_name][:alternatives]
|
324
|
-
experiment = Split::
|
318
|
+
experiment = Split::ExperimentCatalog.find_or_create(experiment_name, *alts)
|
325
319
|
alt_name = ab_user[experiment.key] = alts.first
|
326
320
|
alt = double('alternative')
|
327
321
|
expect(alt).to receive(:name).at_most(1).times.and_return(alt_name)
|
@@ -372,7 +366,7 @@ describe Split::Helper do
|
|
372
366
|
}
|
373
367
|
}
|
374
368
|
alternative_name = ab_test(:my_exp)
|
375
|
-
exp = Split::
|
369
|
+
exp = Split::ExperimentCatalog.find :my_exp
|
376
370
|
|
377
371
|
finished :my_metric
|
378
372
|
expect(ab_user[exp.key]).to eq(alternative_name)
|
@@ -387,7 +381,7 @@ describe Split::Helper do
|
|
387
381
|
}
|
388
382
|
}
|
389
383
|
alternative_name = ab_test(:my_exp)
|
390
|
-
exp = Split::
|
384
|
+
exp = Split::ExperimentCatalog.find :my_exp
|
391
385
|
|
392
386
|
finished :my_metric, :reset => false
|
393
387
|
expect(ab_user[exp.key]).to eq(alternative_name)
|
@@ -409,6 +403,47 @@ describe Split::Helper do
|
|
409
403
|
end
|
410
404
|
end
|
411
405
|
|
406
|
+
describe 'active experiments' do
|
407
|
+
it 'should show an active test' do
|
408
|
+
alternative = ab_test('def', '4', '5', '6')
|
409
|
+
expect(active_experiments.count).to eq 1
|
410
|
+
expect(active_experiments.first[0]).to eq "def"
|
411
|
+
expect(active_experiments.first[1]).to eq alternative
|
412
|
+
end
|
413
|
+
|
414
|
+
it 'should show a finished test' do
|
415
|
+
alternative = ab_test('def', '4', '5', '6')
|
416
|
+
finished('def', {:reset => false})
|
417
|
+
expect(active_experiments.count).to eq 1
|
418
|
+
expect(active_experiments.first[0]).to eq "def"
|
419
|
+
expect(active_experiments.first[1]).to eq alternative
|
420
|
+
end
|
421
|
+
|
422
|
+
it 'should show multiple tests' do
|
423
|
+
Split.configure do |config|
|
424
|
+
config.allow_multiple_experiments = true
|
425
|
+
end
|
426
|
+
alternative = ab_test('def', '4', '5', '6')
|
427
|
+
another_alternative = ab_test('ghi', '7', '8', '9')
|
428
|
+
expect(active_experiments.count).to eq 2
|
429
|
+
expect(active_experiments['def']).to eq alternative
|
430
|
+
expect(active_experiments['ghi']).to eq another_alternative
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'should not show tests with winners' do
|
434
|
+
Split.configure do |config|
|
435
|
+
config.allow_multiple_experiments = true
|
436
|
+
end
|
437
|
+
e = Split::ExperimentCatalog.find_or_create('def', '4', '5', '6')
|
438
|
+
e.winner = '4'
|
439
|
+
alternative = ab_test('def', '4', '5', '6')
|
440
|
+
another_alternative = ab_test('ghi', '7', '8', '9')
|
441
|
+
expect(active_experiments.count).to eq 1
|
442
|
+
expect(active_experiments.first[0]).to eq "ghi"
|
443
|
+
expect(active_experiments.first[1]).to eq another_alternative
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
412
447
|
describe 'when user is a robot' do
|
413
448
|
before(:each) do
|
414
449
|
@request = OpenStruct.new(:user_agent => 'Googlebot/2.1 (+http://www.google.com/bot.html)')
|
@@ -847,7 +882,7 @@ describe Split::Helper do
|
|
847
882
|
end
|
848
883
|
|
849
884
|
it 'should handle multiple experiments correctly' do
|
850
|
-
experiment2 = Split::
|
885
|
+
experiment2 = Split::ExperimentCatalog.find_or_create('link_color2', 'blue', 'red')
|
851
886
|
alternative_name = ab_test('link_color', 'blue', 'red')
|
852
887
|
alternative_name2 = ab_test('link_color2', 'blue', 'red')
|
853
888
|
finished('link_color2')
|
@@ -861,7 +896,7 @@ describe Split::Helper do
|
|
861
896
|
before do
|
862
897
|
@experiment = {'link_color' => ["purchase", "refund"]}
|
863
898
|
@alternatives = ['blue', 'red']
|
864
|
-
@experiment_name, @goals =
|
899
|
+
@experiment_name, @goals = normalize_metric(@experiment)
|
865
900
|
@goal1 = @goals[0]
|
866
901
|
@goal2 = @goals[1]
|
867
902
|
end
|
@@ -874,7 +909,7 @@ describe Split::Helper do
|
|
874
909
|
describe "ab_test" do
|
875
910
|
it "should allow experiment goals interface as a single hash" do
|
876
911
|
ab_test(@experiment, *@alternatives)
|
877
|
-
experiment = Split::
|
912
|
+
experiment = Split::ExperimentCatalog.find('link_color')
|
878
913
|
expect(experiment.goals).to eq(['purchase', "refund"])
|
879
914
|
end
|
880
915
|
end
|
data/spec/metric_spec.rb
CHANGED
@@ -4,13 +4,13 @@ require 'split/metric'
|
|
4
4
|
describe Split::Metric do
|
5
5
|
describe 'possible experiments' do
|
6
6
|
it "should load the experiment if there is one, but no metric" do
|
7
|
-
experiment = Split::
|
7
|
+
experiment = Split::ExperimentCatalog.find_or_create('color', 'red', 'blue')
|
8
8
|
expect(Split::Metric.possible_experiments('color')).to eq([experiment])
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should load the experiments in a metric" do
|
12
|
-
experiment1 = Split::
|
13
|
-
experiment2 = Split::
|
12
|
+
experiment1 = Split::ExperimentCatalog.find_or_create('color', 'red', 'blue')
|
13
|
+
experiment2 = Split::ExperimentCatalog.find_or_create('size', 'big', 'small')
|
14
14
|
|
15
15
|
metric = Split::Metric.new(:name => 'purchase', :experiments => [experiment1, experiment2])
|
16
16
|
metric.save
|
@@ -18,8 +18,8 @@ describe Split::Metric do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should load both the metric experiments and an experiment with the same name" do
|
21
|
-
experiment1 = Split::
|
22
|
-
experiment2 = Split::
|
21
|
+
experiment1 = Split::ExperimentCatalog.find_or_create('purchase', 'red', 'blue')
|
22
|
+
experiment2 = Split::ExperimentCatalog.find_or_create('size', 'big', 'small')
|
23
23
|
|
24
24
|
metric = Split::Metric.new(:name => 'purchase', :experiments => [experiment2])
|
25
25
|
metric.save
|
@@ -16,6 +16,15 @@ describe Split::Persistence::RedisAdapter do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
context 'config with key' do
|
20
|
+
before { Split::Persistence::RedisAdapter.reset_config! }
|
21
|
+
subject { Split::Persistence::RedisAdapter.new(context, 'manual') }
|
22
|
+
|
23
|
+
it 'should be "persistence:manual"' do
|
24
|
+
expect(subject.redis_key).to eq('persistence:manual')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
19
28
|
context 'config with lookup_by = proc { "block" }' do
|
20
29
|
before { Split::Persistence::RedisAdapter.with_config(:lookup_by => proc{'block'}) }
|
21
30
|
|
data/spec/spec_helper.rb
CHANGED
data/spec/trial_spec.rb
CHANGED
@@ -2,61 +2,158 @@ require 'spec_helper'
|
|
2
2
|
require 'split/trial'
|
3
3
|
|
4
4
|
describe Split::Trial do
|
5
|
+
let(:user) { Split::Persistence.adapter.new(double(session: {})) }
|
6
|
+
let(:experiment) do
|
7
|
+
Split::Experiment.new('basket_text', :alternatives => ['basket', 'cart']).save
|
8
|
+
end
|
9
|
+
|
5
10
|
it "should be initializeable" do
|
6
11
|
experiment = double('experiment')
|
7
12
|
alternative = double('alternative', :kind_of? => Split::Alternative)
|
8
13
|
trial = Split::Trial.new(:experiment => experiment, :alternative => alternative)
|
9
14
|
expect(trial.experiment).to eq(experiment)
|
10
15
|
expect(trial.alternative).to eq(alternative)
|
11
|
-
expect(trial.goals).to eq([])
|
12
16
|
end
|
13
17
|
|
14
18
|
describe "alternative" do
|
15
19
|
it "should use the alternative if specified" do
|
16
20
|
alternative = double('alternative', :kind_of? => Split::Alternative)
|
17
|
-
trial = Split::Trial.new(:experiment => experiment = double('experiment'),
|
21
|
+
trial = Split::Trial.new(:experiment => experiment = double('experiment'),
|
22
|
+
:alternative => alternative, :user => user)
|
18
23
|
expect(trial).not_to receive(:choose)
|
19
24
|
expect(trial.alternative).to eq(alternative)
|
20
25
|
end
|
21
26
|
|
22
|
-
it "should
|
27
|
+
it "should load the alternative when the alternative name is set" do
|
23
28
|
experiment = Split::Experiment.new('basket_text', :alternatives => ['basket', 'cart'])
|
24
29
|
experiment.save
|
25
|
-
trial = Split::Trial.new(:experiment => experiment)
|
26
|
-
trial.choose
|
27
|
-
expect(trial.alternative.class).to eq(Split::Alternative)
|
28
|
-
expect(['basket', 'cart']).to include(trial.alternative.name)
|
29
|
-
end
|
30
30
|
|
31
|
-
|
32
|
-
experiment = Split::Experiment.new('basket_text', :alternatives => ['basket'])
|
33
|
-
experiment.save
|
34
|
-
trial = Split::Trial.new(:experiment => experiment)
|
35
|
-
trial.choose
|
36
|
-
expect(trial.alternative.class).to eq(Split::Alternative)
|
31
|
+
trial = Split::Trial.new(:experiment => experiment, :alternative => 'basket')
|
37
32
|
expect(trial.alternative.name).to eq('basket')
|
38
33
|
end
|
34
|
+
end
|
39
35
|
|
36
|
+
describe "#choose!" do
|
37
|
+
def expect_alternative(trial, alternative_name)
|
38
|
+
3.times do
|
39
|
+
trial.choose!
|
40
|
+
expect(trial.alternative.name).to eq(alternative_name)
|
41
|
+
end
|
42
|
+
end
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
expect(alternative).to receive(:increment_participation)
|
46
|
-
expect(experiment).to receive(:winner).at_most(1).times.and_return(nil)
|
47
|
-
trial.choose!
|
44
|
+
context "when override is present" do
|
45
|
+
it "picks the override" do
|
46
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :override => 'cart')
|
47
|
+
expect(experiment).to_not receive(:next_alternative)
|
48
48
|
|
49
|
-
|
49
|
+
expect_alternative(trial, 'cart')
|
50
|
+
end
|
50
51
|
end
|
51
|
-
end
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
context "when disabled option is true" do
|
54
|
+
it "picks the control" do
|
55
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :disabled => true)
|
56
|
+
expect(experiment).to_not receive(:next_alternative)
|
57
57
|
|
58
|
-
|
59
|
-
|
58
|
+
expect_alternative(trial, 'basket')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when Split is globally disabled" do
|
63
|
+
it "picks the control" do
|
64
|
+
Split.configuration.enabled = false
|
65
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment)
|
66
|
+
expect(experiment).to_not receive(:next_alternative)
|
67
|
+
|
68
|
+
expect_alternative(trial, 'basket')
|
69
|
+
Split.configuration.enabled = true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when experiment has winner" do
|
74
|
+
it "picks the winner" do
|
75
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment)
|
76
|
+
experiment.winner = 'cart'
|
77
|
+
expect(experiment).to_not receive(:next_alternative)
|
78
|
+
|
79
|
+
expect_alternative(trial, 'cart')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when exclude is true" do
|
84
|
+
it "picks the control" do
|
85
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :exclude => true)
|
86
|
+
expect(experiment).to_not receive(:next_alternative)
|
87
|
+
|
88
|
+
expect_alternative(trial, 'basket')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when user is already participating" do
|
93
|
+
it "picks the same alternative" do
|
94
|
+
user[experiment.key] = 'basket'
|
95
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment)
|
96
|
+
expect(experiment).to_not receive(:next_alternative)
|
97
|
+
|
98
|
+
expect_alternative(trial, 'basket')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when user is a new participant" do
|
103
|
+
it "picks a new alternative" do
|
104
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment)
|
105
|
+
expect(experiment).to receive(:next_alternative).and_call_original
|
106
|
+
|
107
|
+
trial.choose!
|
108
|
+
expect(trial.alternative.name).to_not be_empty
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "alternative recording" do
|
113
|
+
before(:each) { Split.configuration.store_override = false }
|
114
|
+
|
115
|
+
context "when override is present" do
|
116
|
+
it "stores when store_override is true" do
|
117
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :override => 'basket')
|
118
|
+
|
119
|
+
Split.configuration.store_override = true
|
120
|
+
expect(user).to receive("[]=")
|
121
|
+
trial.choose!
|
122
|
+
end
|
123
|
+
|
124
|
+
it "does not store when store_override is false" do
|
125
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :override => 'basket')
|
126
|
+
|
127
|
+
expect(user).to_not receive("[]=")
|
128
|
+
trial.choose!
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when disabled is present" do
|
133
|
+
it "stores when store_override is true" do
|
134
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :disabled => true)
|
135
|
+
|
136
|
+
Split.configuration.store_override = true
|
137
|
+
expect(user).to receive("[]=")
|
138
|
+
trial.choose!
|
139
|
+
end
|
140
|
+
|
141
|
+
it "does not store when store_override is false" do
|
142
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :disabled => true)
|
143
|
+
|
144
|
+
expect(user).to_not receive("[]=")
|
145
|
+
trial.choose!
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when exclude is present" do
|
150
|
+
it "does not store" do
|
151
|
+
trial = Split::Trial.new(:user => user, :experiment => experiment, :exclude => true)
|
152
|
+
|
153
|
+
expect(user).to_not receive("[]=")
|
154
|
+
trial.choose!
|
155
|
+
end
|
156
|
+
end
|
60
157
|
end
|
61
158
|
end
|
62
159
|
end
|
data/split.gemspec
CHANGED
@@ -25,9 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_dependency 'sinatra', '>= 1.2.6'
|
26
26
|
s.add_dependency 'simple-random'
|
27
27
|
|
28
|
-
s.add_development_dependency 'rake'
|
29
28
|
s.add_development_dependency 'bundler', '~> 1.6'
|
30
|
-
s.add_development_dependency 'rspec', '~> 3.0'
|
31
|
-
s.add_development_dependency 'rack-test'
|
32
29
|
s.add_development_dependency 'coveralls'
|
30
|
+
s.add_development_dependency 'rack-test'
|
31
|
+
s.add_development_dependency 'rake'
|
32
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
33
33
|
end
|
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
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Nesbitt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rake
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: bundler
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,19 +81,19 @@ dependencies:
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '1.6'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
84
|
+
name: coveralls
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - "
|
87
|
+
- - ">="
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
89
|
+
version: '0'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - "
|
94
|
+
- - ">="
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
96
|
+
version: '0'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: rack-test
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,7 +109,7 @@ dependencies:
|
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: '0'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
112
|
+
name: rake
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
115
|
- - ">="
|
@@ -136,6 +122,20 @@ dependencies:
|
|
136
122
|
- - ">="
|
137
123
|
- !ruby/object:Gem::Version
|
138
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '3.0'
|
139
139
|
description:
|
140
140
|
email:
|
141
141
|
- andrewnez@gmail.com
|
@@ -146,19 +146,15 @@ files:
|
|
146
146
|
- ".gitignore"
|
147
147
|
- ".travis.yml"
|
148
148
|
- Appraisals
|
149
|
-
- CHANGELOG.
|
149
|
+
- CHANGELOG.md
|
150
150
|
- CONTRIBUTING.md
|
151
151
|
- Gemfile
|
152
152
|
- LICENSE
|
153
|
-
- README.
|
153
|
+
- README.md
|
154
154
|
- Rakefile
|
155
|
-
- changes.rtf
|
156
|
-
- gemfiles/3.0.gemfile
|
157
|
-
- gemfiles/3.0.gemfile.lock
|
158
|
-
- gemfiles/3.1.gemfile
|
159
|
-
- gemfiles/3.1.gemfile.lock
|
160
155
|
- gemfiles/3.2.gemfile
|
161
156
|
- gemfiles/4.0.gemfile
|
157
|
+
- gemfiles/4.1.gemfile
|
162
158
|
- lib/split.rb
|
163
159
|
- lib/split/algorithms.rb
|
164
160
|
- lib/split/algorithms/weighted_sample.rb
|
@@ -200,6 +196,7 @@ files:
|
|
200
196
|
- spec/dashboard_helpers_spec.rb
|
201
197
|
- spec/dashboard_spec.rb
|
202
198
|
- spec/encapsulated_helper_spec.rb
|
199
|
+
- spec/experiment_catalog_spec.rb
|
203
200
|
- spec/experiment_spec.rb
|
204
201
|
- spec/helper_spec.rb
|
205
202
|
- spec/metric_spec.rb
|
@@ -231,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
228
|
version: '0'
|
232
229
|
requirements: []
|
233
230
|
rubyforge_project: split
|
234
|
-
rubygems_version: 2.
|
231
|
+
rubygems_version: 2.4.5
|
235
232
|
signing_key:
|
236
233
|
specification_version: 4
|
237
234
|
summary: Rack based split testing framework
|
@@ -243,6 +240,7 @@ test_files:
|
|
243
240
|
- spec/dashboard_helpers_spec.rb
|
244
241
|
- spec/dashboard_spec.rb
|
245
242
|
- spec/encapsulated_helper_spec.rb
|
243
|
+
- spec/experiment_catalog_spec.rb
|
246
244
|
- spec/experiment_spec.rb
|
247
245
|
- spec/helper_spec.rb
|
248
246
|
- spec/metric_spec.rb
|