split 0.7.2 → 0.7.3
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/.travis.yml +1 -0
- data/Appraisals +1 -5
- data/CHANGELOG.mdown +34 -2
- data/README.mdown +18 -5
- data/gemfiles/3.0.gemfile +1 -2
- data/gemfiles/3.0.gemfile.lock +59 -31
- data/gemfiles/3.1.gemfile +1 -2
- data/gemfiles/3.1.gemfile.lock +56 -31
- data/gemfiles/3.2.gemfile +1 -2
- data/gemfiles/4.0.gemfile +1 -2
- data/lib/split/dashboard/helpers.rb +4 -0
- data/lib/split/dashboard/views/_experiment.erb +1 -1
- data/lib/split/helper.rb +11 -3
- data/lib/split/version.rb +1 -1
- data/spec/algorithms/weighted_sample_spec.rb +4 -4
- data/spec/algorithms/whiplash_spec.rb +8 -8
- data/spec/alternative_spec.rb +51 -51
- data/spec/configuration_spec.rb +26 -26
- data/spec/dashboard_helpers_spec.rb +7 -7
- data/spec/dashboard_spec.rb +21 -20
- data/spec/experiment_spec.rb +63 -63
- data/spec/helper_spec.rb +164 -145
- data/spec/metric_spec.rb +3 -3
- data/spec/persistence/cookie_adapter_spec.rb +5 -5
- data/spec/persistence/redis_adapter_spec.rb +7 -7
- data/spec/persistence/session_adapter_spec.rb +4 -4
- data/spec/persistence_spec.rb +8 -8
- data/spec/trial_spec.rb +14 -14
- data/split.gemspec +3 -3
- metadata +8 -10
- data/gemfiles/3.2.gemfile.lock +0 -123
- data/gemfiles/4.0.gemfile.lock +0 -118
@@ -71,7 +71,7 @@
|
|
71
71
|
<% end %>
|
72
72
|
<% else %>
|
73
73
|
<form action="<%= url experiment.name %>" method='post' onclick="return confirmWinner()">
|
74
|
-
<input type='hidden' name='alternative' value='<%= alternative.name %>'>
|
74
|
+
<input type='hidden' name='alternative' value='<%= h alternative.name %>'>
|
75
75
|
<input type="submit" value="Use this" class="green">
|
76
76
|
</form>
|
77
77
|
<% end %>
|
data/lib/split/helper.rb
CHANGED
@@ -27,12 +27,13 @@ module Split
|
|
27
27
|
else
|
28
28
|
control_variable(control)
|
29
29
|
end
|
30
|
-
rescue Errno::ECONNREFUSED => e
|
30
|
+
rescue Errno::ECONNREFUSED, Redis::CannotConnectError => e
|
31
31
|
raise(e) unless Split.configuration.db_failover
|
32
32
|
Split.configuration.db_failover_on_db_error.call(e)
|
33
33
|
|
34
|
-
if Split.configuration.db_failover_allow_parameter_override
|
35
|
-
ret = override_alternative(experiment_name)
|
34
|
+
if Split.configuration.db_failover_allow_parameter_override
|
35
|
+
ret = override_alternative(experiment_name) if override_present?(experiment_name)
|
36
|
+
ret = control_variable(control) if split_generically_disabled?
|
36
37
|
end
|
37
38
|
ensure
|
38
39
|
ret ||= control_variable(control)
|
@@ -97,6 +98,10 @@ module Split
|
|
97
98
|
params[experiment_name] if override_present?(experiment_name)
|
98
99
|
end
|
99
100
|
|
101
|
+
def split_generically_disabled?
|
102
|
+
defined?(params) && params['SPLIT_DISABLE']
|
103
|
+
end
|
104
|
+
|
100
105
|
def begin_experiment(experiment, alternative_name = nil)
|
101
106
|
alternative_name ||= experiment.control.name
|
102
107
|
ab_user[experiment.key] = alternative_name
|
@@ -169,6 +174,9 @@ module Split
|
|
169
174
|
if override_present?(experiment.name) and experiment[override_alternative(experiment.name)]
|
170
175
|
ret = override_alternative(experiment.name)
|
171
176
|
ab_user[experiment.key] = ret if Split.configuration.store_override
|
177
|
+
elsif split_generically_disabled?
|
178
|
+
ret = experiment.control.name
|
179
|
+
ab_user[experiment.key] = ret if Split.configuration.store_override
|
172
180
|
elsif experiment.has_winner?
|
173
181
|
ret = experiment.winner.name
|
174
182
|
else
|
data/lib/split/version.rb
CHANGED
@@ -3,16 +3,16 @@ require "spec_helper"
|
|
3
3
|
describe Split::Algorithms::WeightedSample do
|
4
4
|
it "should return an alternative" do
|
5
5
|
experiment = Split::Experiment.find_or_create('link_color', {'blue' => 100}, {'red' => 0 })
|
6
|
-
Split::Algorithms::WeightedSample.choose_alternative(experiment).class.
|
6
|
+
expect(Split::Algorithms::WeightedSample.choose_alternative(experiment).class).to eq(Split::Alternative)
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should always return a heavily weighted option" do
|
10
10
|
experiment = Split::Experiment.find_or_create('link_color', {'blue' => 100}, {'red' => 0 })
|
11
|
-
Split::Algorithms::WeightedSample.choose_alternative(experiment).name.
|
11
|
+
expect(Split::Algorithms::WeightedSample.choose_alternative(experiment).name).to eq('blue')
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should return one of the results" do
|
15
15
|
experiment = Split::Experiment.find_or_create('link_color', {'blue' => 1}, {'red' => 1 })
|
16
|
-
['red', 'blue'].
|
16
|
+
expect(['red', 'blue']).to include Split::Algorithms::WeightedSample.choose_alternative(experiment).name
|
17
17
|
end
|
18
|
-
end
|
18
|
+
end
|
@@ -4,20 +4,20 @@ describe Split::Algorithms::Whiplash do
|
|
4
4
|
|
5
5
|
it "should return an algorithm" do
|
6
6
|
experiment = Split::Experiment.find_or_create('link_color', {'blue' => 1}, {'red' => 1 })
|
7
|
-
Split::Algorithms::Whiplash.choose_alternative(experiment).class.
|
7
|
+
expect(Split::Algorithms::Whiplash.choose_alternative(experiment).class).to eq(Split::Alternative)
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should return one of the results" do
|
11
11
|
experiment = Split::Experiment.find_or_create('link_color', {'blue' => 1}, {'red' => 1 })
|
12
|
-
['red', 'blue'].
|
12
|
+
expect(['red', 'blue']).to include Split::Algorithms::Whiplash.choose_alternative(experiment).name
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should guess floats" do
|
16
|
-
Split::Algorithms::Whiplash.send(:arm_guess, 0, 0).class.
|
17
|
-
Split::Algorithms::Whiplash.send(:arm_guess, 1, 0).class.
|
18
|
-
Split::Algorithms::Whiplash.send(:arm_guess, 2, 1).class.
|
19
|
-
Split::Algorithms::Whiplash.send(:arm_guess, 1000, 5).class.
|
20
|
-
Split::Algorithms::Whiplash.send(:arm_guess, 10, -2).class.
|
16
|
+
expect(Split::Algorithms::Whiplash.send(:arm_guess, 0, 0).class).to eq(Float)
|
17
|
+
expect(Split::Algorithms::Whiplash.send(:arm_guess, 1, 0).class).to eq(Float)
|
18
|
+
expect(Split::Algorithms::Whiplash.send(:arm_guess, 2, 1).class).to eq(Float)
|
19
|
+
expect(Split::Algorithms::Whiplash.send(:arm_guess, 1000, 5).class).to eq(Float)
|
20
|
+
expect(Split::Algorithms::Whiplash.send(:arm_guess, 10, -2).class).to eq(Float)
|
21
21
|
end
|
22
22
|
|
23
|
-
end
|
23
|
+
end
|
data/spec/alternative_spec.rb
CHANGED
@@ -19,23 +19,23 @@ describe Split::Alternative do
|
|
19
19
|
let(:goal2) { "refund" }
|
20
20
|
|
21
21
|
it "should have goals" do
|
22
|
-
alternative.goals.
|
22
|
+
expect(alternative.goals).to eq(["purchase", "refund"])
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should have and only return the name" do
|
26
|
-
alternative.name.
|
26
|
+
expect(alternative.name).to eq('Basket')
|
27
27
|
end
|
28
28
|
|
29
29
|
describe 'weights' do
|
30
30
|
it "should set the weights" do
|
31
31
|
experiment = Split::Experiment.new('basket_text', :alternatives => [{'Basket' => 0.6}, {"Cart" => 0.4}])
|
32
32
|
first = experiment.alternatives[0]
|
33
|
-
first.name.
|
34
|
-
first.weight.
|
33
|
+
expect(first.name).to eq('Basket')
|
34
|
+
expect(first.weight).to eq(0.6)
|
35
35
|
|
36
36
|
second = experiment.alternatives[1]
|
37
|
-
second.name.
|
38
|
-
second.weight.
|
37
|
+
expect(second.name).to eq('Cart')
|
38
|
+
expect(second.weight).to eq(0.4)
|
39
39
|
end
|
40
40
|
|
41
41
|
it "accepts probability on alternatives" do
|
@@ -50,12 +50,12 @@ describe Split::Alternative do
|
|
50
50
|
}
|
51
51
|
experiment = Split::Experiment.new(:my_experiment)
|
52
52
|
first = experiment.alternatives[0]
|
53
|
-
first.name.
|
54
|
-
first.weight.
|
53
|
+
expect(first.name).to eq('control_opt')
|
54
|
+
expect(first.weight).to eq(0.67)
|
55
55
|
|
56
56
|
second = experiment.alternatives[1]
|
57
|
-
second.name.
|
58
|
-
second.weight.
|
57
|
+
expect(second.name).to eq('second_opt')
|
58
|
+
expect(second.weight).to eq(0.1)
|
59
59
|
end
|
60
60
|
|
61
61
|
it "accepts probability on some alternatives" do
|
@@ -79,8 +79,8 @@ describe Split::Alternative do
|
|
79
79
|
].each do |h|
|
80
80
|
name, weight = h
|
81
81
|
alt = alts.shift
|
82
|
-
alt.name.
|
83
|
-
alt.weight.
|
82
|
+
expect(alt.name).to eq(name)
|
83
|
+
expect(alt.weight).to eq(weight)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
#
|
@@ -103,35 +103,35 @@ describe Split::Alternative do
|
|
103
103
|
].each do |h|
|
104
104
|
name, weight = h
|
105
105
|
alt = alts.shift
|
106
|
-
alt.name.
|
107
|
-
alt.weight.
|
106
|
+
expect(alt.name).to eq(name)
|
107
|
+
expect(alt.weight).to eq(weight)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
112
|
it "should have a default participation count of 0" do
|
113
|
-
alternative.participant_count.
|
113
|
+
expect(alternative.participant_count).to eq(0)
|
114
114
|
end
|
115
115
|
|
116
116
|
it "should have a default completed count of 0 for each goal" do
|
117
|
-
alternative.completed_count.
|
118
|
-
alternative.completed_count(goal1).
|
119
|
-
alternative.completed_count(goal2).
|
117
|
+
expect(alternative.completed_count).to eq(0)
|
118
|
+
expect(alternative.completed_count(goal1)).to eq(0)
|
119
|
+
expect(alternative.completed_count(goal2)).to eq(0)
|
120
120
|
end
|
121
121
|
|
122
122
|
it "should belong to an experiment" do
|
123
|
-
alternative.experiment.name.
|
123
|
+
expect(alternative.experiment.name).to eq(experiment.name)
|
124
124
|
end
|
125
125
|
|
126
126
|
it "should save to redis" do
|
127
127
|
alternative.save
|
128
|
-
Split.redis.exists('basket_text:Basket').
|
128
|
+
expect(Split.redis.exists('basket_text:Basket')).to be true
|
129
129
|
end
|
130
130
|
|
131
131
|
it "should increment participation count" do
|
132
132
|
old_participant_count = alternative.participant_count
|
133
133
|
alternative.increment_participation
|
134
|
-
alternative.participant_count.
|
134
|
+
expect(alternative.participant_count).to eq(old_participant_count+1)
|
135
135
|
end
|
136
136
|
|
137
137
|
it "should increment completed count for each goal" do
|
@@ -143,9 +143,9 @@ describe Split::Alternative do
|
|
143
143
|
alternative.increment_completion(goal1)
|
144
144
|
alternative.increment_completion(goal2)
|
145
145
|
|
146
|
-
alternative.completed_count.
|
147
|
-
alternative.completed_count(goal1).
|
148
|
-
alternative.completed_count(goal2).
|
146
|
+
expect(alternative.completed_count).to eq(old_default_completed_count+1)
|
147
|
+
expect(alternative.completed_count(goal1)).to eq(old_completed_count_for_goal1+1)
|
148
|
+
expect(alternative.completed_count(goal2)).to eq(old_completed_count_for_goal2+1)
|
149
149
|
end
|
150
150
|
|
151
151
|
it "can be reset" do
|
@@ -154,21 +154,21 @@ describe Split::Alternative do
|
|
154
154
|
alternative.set_completed_count(5, goal2)
|
155
155
|
alternative.set_completed_count(6)
|
156
156
|
alternative.reset
|
157
|
-
alternative.participant_count.
|
158
|
-
alternative.completed_count(goal1).
|
159
|
-
alternative.completed_count(goal2).
|
160
|
-
alternative.completed_count.
|
157
|
+
expect(alternative.participant_count).to eq(0)
|
158
|
+
expect(alternative.completed_count(goal1)).to eq(0)
|
159
|
+
expect(alternative.completed_count(goal2)).to eq(0)
|
160
|
+
expect(alternative.completed_count).to eq(0)
|
161
161
|
end
|
162
162
|
|
163
163
|
it "should know if it is the control of an experiment" do
|
164
|
-
alternative.control
|
165
|
-
alternative2.control
|
164
|
+
expect(alternative.control?).to be_truthy
|
165
|
+
expect(alternative2.control?).to be_falsey
|
166
166
|
end
|
167
167
|
|
168
168
|
describe 'unfinished_count' do
|
169
169
|
it "should be difference between participant and completed counts" do
|
170
170
|
alternative.increment_participation
|
171
|
-
alternative.unfinished_count.
|
171
|
+
expect(alternative.unfinished_count).to eq(alternative.participant_count)
|
172
172
|
end
|
173
173
|
|
174
174
|
it "should return the correct unfinished_count" do
|
@@ -177,35 +177,35 @@ describe Split::Alternative do
|
|
177
177
|
alternative.set_completed_count(3, goal2)
|
178
178
|
alternative.set_completed_count(2)
|
179
179
|
|
180
|
-
alternative.unfinished_count.
|
180
|
+
expect(alternative.unfinished_count).to eq(1)
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
184
|
describe 'conversion rate' do
|
185
185
|
it "should be 0 if there are no conversions" do
|
186
|
-
alternative.completed_count.
|
187
|
-
alternative.conversion_rate.
|
186
|
+
expect(alternative.completed_count).to eq(0)
|
187
|
+
expect(alternative.conversion_rate).to eq(0)
|
188
188
|
end
|
189
189
|
|
190
190
|
it "calculate conversion rate" do
|
191
|
-
alternative.
|
192
|
-
alternative.
|
193
|
-
alternative.conversion_rate.
|
191
|
+
expect(alternative).to receive(:participant_count).exactly(6).times.and_return(10)
|
192
|
+
expect(alternative).to receive(:completed_count).and_return(4)
|
193
|
+
expect(alternative.conversion_rate).to eq(0.4)
|
194
194
|
|
195
|
-
alternative.
|
196
|
-
alternative.conversion_rate(goal1).
|
195
|
+
expect(alternative).to receive(:completed_count).with(goal1).and_return(5)
|
196
|
+
expect(alternative.conversion_rate(goal1)).to eq(0.5)
|
197
197
|
|
198
|
-
alternative.
|
199
|
-
alternative.conversion_rate(goal2).
|
198
|
+
expect(alternative).to receive(:completed_count).with(goal2).and_return(6)
|
199
|
+
expect(alternative.conversion_rate(goal2)).to eq(0.6)
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
203
|
describe 'z score' do
|
204
204
|
|
205
205
|
it "should return an error string when the control has 0 people" do
|
206
|
-
alternative2.z_score.
|
207
|
-
alternative2.z_score(goal1).
|
208
|
-
alternative2.z_score(goal2).
|
206
|
+
expect(alternative2.z_score).to eq("Needs 30+ participants.")
|
207
|
+
expect(alternative2.z_score(goal1)).to eq("Needs 30+ participants.")
|
208
|
+
expect(alternative2.z_score(goal2)).to eq("Needs 30+ participants.")
|
209
209
|
end
|
210
210
|
|
211
211
|
it "should return an error string when the data is skewed or incomplete as per the np > 5 test" do
|
@@ -216,7 +216,7 @@ describe Split::Alternative do
|
|
216
216
|
alternative2.participant_count = 50
|
217
217
|
alternative2.set_completed_count(1)
|
218
218
|
|
219
|
-
alternative2.z_score.
|
219
|
+
expect(alternative2.z_score).to eq("Needs 5+ conversions.")
|
220
220
|
end
|
221
221
|
|
222
222
|
it "should return a float for a z_score given proper data" do
|
@@ -227,8 +227,8 @@ describe Split::Alternative do
|
|
227
227
|
alternative2.participant_count = 100
|
228
228
|
alternative2.set_completed_count(25)
|
229
229
|
|
230
|
-
alternative2.z_score.
|
231
|
-
alternative2.z_score.
|
230
|
+
expect(alternative2.z_score).to be_kind_of(Float)
|
231
|
+
expect(alternative2.z_score).to_not eq(0)
|
232
232
|
end
|
233
233
|
|
234
234
|
it "should correctly calculate a z_score given proper data" do
|
@@ -239,14 +239,14 @@ describe Split::Alternative do
|
|
239
239
|
alternative2.participant_count = 142
|
240
240
|
alternative2.set_completed_count(119)
|
241
241
|
|
242
|
-
alternative2.z_score.round(2).
|
242
|
+
expect(alternative2.z_score.round(2)).to eq(2.58)
|
243
243
|
end
|
244
244
|
|
245
245
|
it "should be N/A for the control" do
|
246
246
|
control = experiment.control
|
247
|
-
control.z_score.
|
248
|
-
control.z_score(goal1).
|
249
|
-
control.z_score(goal2).
|
247
|
+
expect(control.z_score).to eq('N/A')
|
248
|
+
expect(control.z_score(goal1)).to eq('N/A')
|
249
|
+
expect(control.z_score(goal2)).to eq('N/A')
|
250
250
|
end
|
251
251
|
end
|
252
252
|
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -5,69 +5,69 @@ describe Split::Configuration do
|
|
5
5
|
before(:each) { @config = Split::Configuration.new }
|
6
6
|
|
7
7
|
it "should provide a default value for ignore_ip_addresses" do
|
8
|
-
@config.ignore_ip_addresses.
|
8
|
+
expect(@config.ignore_ip_addresses).to eq([])
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should provide default values for db failover" do
|
12
|
-
@config.db_failover.
|
13
|
-
@config.db_failover_on_db_error.
|
12
|
+
expect(@config.db_failover).to be_falsey
|
13
|
+
expect(@config.db_failover_on_db_error).to be_a Proc
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should not allow multiple experiments by default" do
|
17
|
-
@config.allow_multiple_experiments.
|
17
|
+
expect(@config.allow_multiple_experiments).to be_falsey
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should be enabled by default" do
|
21
|
-
@config.enabled.
|
21
|
+
expect(@config.enabled).to be_truthy
|
22
22
|
end
|
23
23
|
|
24
24
|
it "disabled is the opposite of enabled" do
|
25
25
|
@config.enabled = false
|
26
|
-
@config.disabled
|
26
|
+
expect(@config.disabled?).to be_truthy
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should not store the overridden test group per default" do
|
30
|
-
@config.store_override.
|
30
|
+
expect(@config.store_override).to be_falsey
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should provide a default pattern for robots" do
|
34
34
|
%w[Baidu Gigabot Googlebot libwww-perl lwp-trivial msnbot SiteUptime Slurp WordPress ZIBB ZyBorg YandexBot AdsBot-Google Wget curl bitlybot facebookexternalhit spider].each do |robot|
|
35
|
-
@config.robot_regex.
|
35
|
+
expect(@config.robot_regex).to match(robot)
|
36
36
|
end
|
37
37
|
|
38
|
-
@config.robot_regex.
|
39
|
-
@config.robot_regex.
|
40
|
-
@config.robot_regex.
|
38
|
+
expect(@config.robot_regex).to match("EventMachine HttpClient")
|
39
|
+
expect(@config.robot_regex).to match("libwww-perl/5.836")
|
40
|
+
expect(@config.robot_regex).to match("Pingdom.com_bot_version_1.4_(http://www.pingdom.com)")
|
41
41
|
|
42
|
-
@config.robot_regex.
|
42
|
+
expect(@config.robot_regex).to match(" - ")
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should accept real UAs with the robot regexp" do
|
46
|
-
@config.robot_regex.
|
47
|
-
@config.robot_regex.
|
46
|
+
expect(@config.robot_regex).not_to match("Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.4) Gecko/20091017 SeaMonkey/2.0")
|
47
|
+
expect(@config.robot_regex).not_to match("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; F-6.0SP2-20041109; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 1.1.4322; InfoPath.3)")
|
48
48
|
end
|
49
49
|
|
50
50
|
it "should allow adding a bot to the bot list" do
|
51
51
|
@config.bots["newbot"] = "An amazing test bot"
|
52
|
-
@config.robot_regex.
|
52
|
+
expect(@config.robot_regex).to match("newbot")
|
53
53
|
end
|
54
54
|
|
55
55
|
it "should use the session adapter for persistence by default" do
|
56
|
-
@config.persistence.
|
56
|
+
expect(@config.persistence).to eq(Split::Persistence::SessionAdapter)
|
57
57
|
end
|
58
58
|
|
59
59
|
it "should load a metric" do
|
60
60
|
@config.experiments = {:my_experiment=>
|
61
61
|
{:alternatives=>["control_opt", "other_opt"], :metric=>:my_metric}}
|
62
62
|
|
63
|
-
@config.metrics.
|
64
|
-
@config.metrics.keys.
|
63
|
+
expect(@config.metrics).not_to be_nil
|
64
|
+
expect(@config.metrics.keys).to eq([:my_metric])
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should allow loading of experiment using experment_for" do
|
68
68
|
@config.experiments = {:my_experiment=>
|
69
69
|
{:alternatives=>["control_opt", "other_opt"], :metric=>:my_metric}}
|
70
|
-
@config.experiment_for(:my_experiment).
|
70
|
+
expect(@config.experiment_for(:my_experiment)).to eq({:alternatives=>["control_opt", ["other_opt"]]})
|
71
71
|
end
|
72
72
|
|
73
73
|
context "when experiments are defined via YAML" do
|
@@ -86,7 +86,7 @@ describe Split::Configuration do
|
|
86
86
|
end
|
87
87
|
|
88
88
|
it 'should normalize experiments' do
|
89
|
-
@config.normalized_experiments.
|
89
|
+
expect(@config.normalized_experiments).to eq({:my_experiment=>{:resettable=>false,:alternatives=>["Control Opt", ["Alt One", "Alt Two"]]}})
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -112,13 +112,13 @@ describe Split::Configuration do
|
|
112
112
|
end
|
113
113
|
|
114
114
|
it "should normalize experiments" do
|
115
|
-
@config.normalized_experiments.
|
116
|
-
[{"Alt One"=>0.1}, {"Alt Two"=>0.23}]]}, :another_experiment=>{:alternatives=>["a", ["b"]]}}
|
115
|
+
expect(@config.normalized_experiments).to eq({:my_experiment=>{:resettable=>false,:alternatives=>[{"Control Opt"=>0.67},
|
116
|
+
[{"Alt One"=>0.1}, {"Alt Two"=>0.23}]]}, :another_experiment=>{:alternatives=>["a", ["b"]]}})
|
117
117
|
end
|
118
118
|
|
119
119
|
it "should recognize metrics" do
|
120
|
-
@config.metrics.
|
121
|
-
@config.metrics.keys.
|
120
|
+
expect(@config.metrics).not_to be_nil
|
121
|
+
expect(@config.metrics.keys).to eq([:my_metric])
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
@@ -139,7 +139,7 @@ describe Split::Configuration do
|
|
139
139
|
end
|
140
140
|
|
141
141
|
it "should normalize experiments" do
|
142
|
-
@config.normalized_experiments.
|
142
|
+
expect(@config.normalized_experiments).to eq({:my_experiment=>{:resettable=>false,:alternatives=>["Control Opt", ["Alt One", "Alt Two"]]}})
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
@@ -177,6 +177,6 @@ describe Split::Configuration do
|
|
177
177
|
}
|
178
178
|
}
|
179
179
|
|
180
|
-
@config.normalized_experiments.
|
180
|
+
expect(@config.normalized_experiments).to eq({:my_experiment=>{:alternatives=>[{"control_opt"=>0.67}, [{"second_opt"=>0.1}, {"third_opt"=>0.23}]]}})
|
181
181
|
end
|
182
182
|
end
|