split 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.mdown +12 -1
- data/lib/split.rb +1 -1
- data/lib/split/configuration.rb +7 -1
- data/lib/split/exceptions.rb +2 -1
- data/lib/split/experiment.rb +1 -1
- data/lib/split/helper.rb +5 -0
- data/lib/split/trial.rb +1 -1
- data/lib/split/version.rb +1 -1
- data/spec/configuration_spec.rb +36 -12
- data/spec/experiment_spec.rb +11 -1
- data/spec/helper_spec.rb +5 -2
- data/spec/trial_spec.rb +1 -0
- metadata +18 -18
data/CHANGELOG.mdown
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 0.6.1 (May 4, 2013)
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- Use the specified algorithm for the experiment instead of the default (@woodhull, #165)
|
6
|
+
|
7
|
+
Misc:
|
8
|
+
|
9
|
+
- Ensure experiements are valid when configuring (@ashmckenzie, #159)
|
10
|
+
- Allow arrays to be passed to ab_test (@fenelon, #156)
|
11
|
+
|
1
12
|
## 0.6.0 (April 4, 2013)
|
2
13
|
|
3
14
|
Features:
|
@@ -19,7 +30,7 @@ Misc:
|
|
19
30
|
- updated minimum json version requirement
|
20
31
|
- Refactor Yaml Configuration (@rtwomey, #124)
|
21
32
|
- Refactoring of Experiments (@iangreenleaf @tamird, #117 #118)
|
22
|
-
- Added more known Bots, including Pingdom, Bing, YandexBot (@julesie, @zinkkrysty)
|
33
|
+
- Added more known Bots, including Pingdom, Bing, YandexBot (@julesie, @zinkkrysty, @dimko)
|
23
34
|
- Improved Readme (@iangreenleaf @phoet)
|
24
35
|
|
25
36
|
## 0.5.0 (January 28, 2013)
|
data/lib/split.rb
CHANGED
data/lib/split/configuration.rb
CHANGED
@@ -9,10 +9,11 @@ module Split
|
|
9
9
|
attr_accessor :db_failover_allow_parameter_override
|
10
10
|
attr_accessor :allow_multiple_experiments
|
11
11
|
attr_accessor :enabled
|
12
|
-
attr_accessor :experiments
|
13
12
|
attr_accessor :persistence
|
14
13
|
attr_accessor :algorithm
|
15
14
|
|
15
|
+
attr_reader :experiments
|
16
|
+
|
16
17
|
def bots
|
17
18
|
@bots ||= {
|
18
19
|
# Indexers
|
@@ -63,6 +64,11 @@ module Split
|
|
63
64
|
}
|
64
65
|
end
|
65
66
|
|
67
|
+
def experiments= experiments
|
68
|
+
raise InvalidExperimentsFormatError.new('Experiments must be a Hash') unless experiments.respond_to?(:keys)
|
69
|
+
@experiments = experiments
|
70
|
+
end
|
71
|
+
|
66
72
|
def disabled?
|
67
73
|
!enabled
|
68
74
|
end
|
data/lib/split/exceptions.rb
CHANGED
data/lib/split/experiment.rb
CHANGED
data/lib/split/helper.rb
CHANGED
@@ -6,6 +6,11 @@ module Split
|
|
6
6
|
puts 'WARNING: You should always pass the control alternative through as the second argument with any other alternatives as the third because the order of the hash is not preserved in ruby 1.8'
|
7
7
|
end
|
8
8
|
|
9
|
+
# Check if array is passed to ab_test: ab_test('name', ['Alt 1', 'Alt 2', 'Alt 3'])
|
10
|
+
if control.is_a? Array and alternatives.length.zero?
|
11
|
+
control, alternatives = control.first, control[1..-1]
|
12
|
+
end
|
13
|
+
|
9
14
|
begin
|
10
15
|
experiment_name_with_version, goals = normalize_experiment(metric_descriptor)
|
11
16
|
experiment_name = experiment_name_with_version.to_s.split(':')[0]
|
data/lib/split/trial.rb
CHANGED
@@ -6,7 +6,7 @@ module Split
|
|
6
6
|
def initialize(attrs = {})
|
7
7
|
self.experiment = attrs[:experiment] if !attrs[:experiment].nil?
|
8
8
|
self.alternative = attrs[:alternative] if !attrs[:alternative].nil?
|
9
|
-
self.goals = attrs[:goals]
|
9
|
+
self.goals = attrs[:goals].nil? ? [] : attrs[:goals]
|
10
10
|
end
|
11
11
|
|
12
12
|
def alternative
|
data/lib/split/version.rb
CHANGED
data/spec/configuration_spec.rb
CHANGED
@@ -120,20 +120,44 @@ describe Split::Configuration do
|
|
120
120
|
end
|
121
121
|
|
122
122
|
context "as symbols" do
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
123
|
+
|
124
|
+
context "with valid YAML" do
|
125
|
+
before do
|
126
|
+
experiments_yaml = <<-eos
|
127
|
+
:my_experiment:
|
128
|
+
:alternatives:
|
129
|
+
- Control Opt
|
130
|
+
- Alt One
|
131
|
+
- Alt Two
|
132
|
+
:resettable: false
|
133
|
+
eos
|
134
|
+
@config.experiments = YAML.load(experiments_yaml)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should normalize experiments" do
|
138
|
+
@config.normalized_experiments.should == {:my_experiment=>{:alternatives=>["Control Opt", ["Alt One", "Alt Two"]]}}
|
139
|
+
end
|
133
140
|
end
|
134
141
|
|
135
|
-
|
136
|
-
|
142
|
+
context "with invalid YAML" do
|
143
|
+
|
144
|
+
let(:yaml) { YAML.load(input) }
|
145
|
+
|
146
|
+
context "with an empty string" do
|
147
|
+
let(:input) { '' }
|
148
|
+
|
149
|
+
it "should raise an error" do
|
150
|
+
expect { @config.experiments = yaml }.to raise_error(/Experiments must be a Hash/)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "with just the YAML header" do
|
155
|
+
let(:input) { '---' }
|
156
|
+
|
157
|
+
it "should raise an error" do
|
158
|
+
expect { @config.experiments = yaml }.to raise_error(/Experiments must be a Hash/)
|
159
|
+
end
|
160
|
+
end
|
137
161
|
end
|
138
162
|
end
|
139
163
|
end
|
data/spec/experiment_spec.rb
CHANGED
@@ -139,6 +139,15 @@ describe Split::Experiment do
|
|
139
139
|
e.should == experiment
|
140
140
|
e.algorithm.should == Split::Algorithms::Whiplash
|
141
141
|
end
|
142
|
+
|
143
|
+
it "should persist a new experiment in redis, that does not exist in the configuration file" do
|
144
|
+
experiment = Split::Experiment.new('foobar', :alternatives => ['tra', 'la'], :algorithm => Split::Algorithms::Whiplash)
|
145
|
+
experiment.save
|
146
|
+
|
147
|
+
e = Split::Experiment.find('foobar')
|
148
|
+
e.should == experiment
|
149
|
+
e.alternatives.collect{|a| a.name}.should == ['tra', 'la']
|
150
|
+
end
|
142
151
|
end
|
143
152
|
|
144
153
|
describe 'deleting' do
|
@@ -230,7 +239,8 @@ describe Split::Experiment do
|
|
230
239
|
end
|
231
240
|
|
232
241
|
it "should use the specified algorithm if a winner does not exist" do
|
233
|
-
|
242
|
+
experiment.algorithm = Split::Algorithms::Whiplash
|
243
|
+
experiment.algorithm.should_receive(:choose_alternative).and_return(Split::Alternative.new('green', 'link_color'))
|
234
244
|
experiment.next_alternative.name.should eql('green')
|
235
245
|
end
|
236
246
|
end
|
data/spec/helper_spec.rb
CHANGED
@@ -15,6 +15,10 @@ describe Split::Helper do
|
|
15
15
|
lambda { ab_test('xyz', '1', '2', '3') }.should_not raise_error
|
16
16
|
end
|
17
17
|
|
18
|
+
it "should not raise an error when passed an array for alternatives" do
|
19
|
+
lambda { ab_test('xyz', ['1', '2', '3']) }.should_not raise_error
|
20
|
+
end
|
21
|
+
|
18
22
|
it "should raise the appropriate error when passed integers for alternatives" do
|
19
23
|
lambda { ab_test('xyz', 1, 2, 3) }.should raise_error(ArgumentError)
|
20
24
|
end
|
@@ -801,8 +805,7 @@ describe Split::Helper do
|
|
801
805
|
end
|
802
806
|
|
803
807
|
it "fails gracefully if config is missing" do
|
804
|
-
Split.configuration.experiments = nil
|
805
|
-
lambda { ab_test :my_experiment }.should raise_error(/not found/i)
|
808
|
+
lambda { Split.configuration.experiments = nil }.should raise_error(/Experiments must be a Hash/)
|
806
809
|
end
|
807
810
|
|
808
811
|
it "fails gracefully if config is missing alternatives" do
|
data/spec/trial_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: split
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement: &
|
16
|
+
requirement: &70334741839320 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '2.1'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70334741839320
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redis-namespace
|
27
|
-
requirement: &
|
27
|
+
requirement: &70334741851360 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.1.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70334741851360
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sinatra
|
38
|
-
requirement: &
|
38
|
+
requirement: &70334741849020 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.2.6
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70334741849020
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: simple-random
|
49
|
-
requirement: &
|
49
|
+
requirement: &70334741846920 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70334741846920
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
requirement: &
|
60
|
+
requirement: &70334741860380 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70334741860380
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
|
-
requirement: &
|
71
|
+
requirement: &70334741859480 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '1.0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70334741859480
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rspec
|
82
|
-
requirement: &
|
82
|
+
requirement: &70334741857740 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '2.12'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70334741857740
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: rack-test
|
93
|
-
requirement: &
|
93
|
+
requirement: &70334741856560 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: '0.6'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70334741856560
|
102
102
|
description:
|
103
103
|
email:
|
104
104
|
- andrewnez@gmail.com
|