split 0.3.1 → 0.3.2
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.
- data/CHANGELOG.mdown +6 -0
- data/LICENSE +1 -1
- data/README.mdown +3 -3
- data/lib/split/configuration.rb +4 -0
- data/lib/split/helper.rb +9 -0
- data/lib/split/version.rb +1 -1
- data/spec/configuration_spec.rb +3 -1
- data/spec/helper_spec.rb +85 -1
- metadata +18 -24
data/CHANGELOG.mdown
CHANGED
data/LICENSE
CHANGED
data/README.mdown
CHANGED
@@ -81,14 +81,14 @@ Example: Controller
|
|
81
81
|
|
82
82
|
def register_new_user
|
83
83
|
# See what level of free points maximizes users' decision to buy replacement points.
|
84
|
-
@starter_points = ab_test("new_user_free_points", 100, 200, 300)
|
84
|
+
@starter_points = ab_test("new_user_free_points", '100', '200', '300')
|
85
85
|
end
|
86
86
|
|
87
87
|
Example: Conversion tracking (in a controller!)
|
88
88
|
|
89
89
|
def buy_new_points
|
90
90
|
# some business logic
|
91
|
-
finished("
|
91
|
+
finished("new_user_free_points")
|
92
92
|
end
|
93
93
|
|
94
94
|
Example: Conversion tracking (in a view)
|
@@ -251,4 +251,4 @@ Tests can be ran with `rake spec`
|
|
251
251
|
|
252
252
|
## Copyright
|
253
253
|
|
254
|
-
Copyright (c)
|
254
|
+
Copyright (c) 2012 Andrew Nesbitt. See [LICENSE](https://github.com/andrew/split/blob/master/LICENSE) for details.
|
data/lib/split/configuration.rb
CHANGED
@@ -2,10 +2,14 @@ module Split
|
|
2
2
|
class Configuration
|
3
3
|
attr_accessor :robot_regex
|
4
4
|
attr_accessor :ignore_ip_addresses
|
5
|
+
attr_accessor :db_failover
|
6
|
+
attr_accessor :db_failover_on_db_error
|
5
7
|
|
6
8
|
def initialize
|
7
9
|
@robot_regex = /\b(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg)\b/i
|
8
10
|
@ignore_ip_addresses = []
|
11
|
+
@db_failover = false
|
12
|
+
@db_failover_on_db_error = proc{|error|} # e.g. use Rails logger here
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
data/lib/split/helper.rb
CHANGED
@@ -32,6 +32,12 @@ module Split
|
|
32
32
|
else
|
33
33
|
ret
|
34
34
|
end
|
35
|
+
rescue Errno::ECONNREFUSED => e
|
36
|
+
raise unless Split.configuration.db_failover
|
37
|
+
Split.configuration.db_failover_on_db_error.call(e)
|
38
|
+
ret = Hash === (a0 = alternatives.first) ? a0.keys.first : a0
|
39
|
+
yield(ret) if block_given?
|
40
|
+
ret
|
35
41
|
end
|
36
42
|
|
37
43
|
def finished(experiment_name, options = {:reset => true})
|
@@ -42,6 +48,9 @@ module Split
|
|
42
48
|
alternative.increment_completion
|
43
49
|
session[:split].delete(experiment_name) if options[:reset]
|
44
50
|
end
|
51
|
+
rescue Errno::ECONNREFUSED => e
|
52
|
+
raise unless Split.configuration.db_failover
|
53
|
+
Split.configuration.db_failover_on_db_error.call(e)
|
45
54
|
end
|
46
55
|
|
47
56
|
def override(experiment_name, alternatives)
|
data/lib/split/version.rb
CHANGED
data/spec/configuration_spec.rb
CHANGED
@@ -6,5 +6,7 @@ describe Split::Configuration do
|
|
6
6
|
|
7
7
|
config.ignore_ip_addresses.should eql([])
|
8
8
|
config.robot_regex.should eql(/\b(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg)\b/i)
|
9
|
+
config.db_failover.should be_false
|
10
|
+
config.db_failover_on_db_error.should be_a Proc
|
9
11
|
end
|
10
|
-
end
|
12
|
+
end
|
data/spec/helper_spec.rb
CHANGED
@@ -68,6 +68,7 @@ describe Split::Helper do
|
|
68
68
|
experiment = Split::Experiment.find('link_color')
|
69
69
|
experiment.alternative_names.should eql(['blue', 'red'])
|
70
70
|
end
|
71
|
+
|
71
72
|
end
|
72
73
|
|
73
74
|
describe 'finished' do
|
@@ -271,4 +272,87 @@ describe Split::Helper do
|
|
271
272
|
alternative.completed_count.should eql(0)
|
272
273
|
end
|
273
274
|
end
|
274
|
-
|
275
|
+
|
276
|
+
context 'when redis is not available' do
|
277
|
+
|
278
|
+
before(:each) do
|
279
|
+
Split.stub(:redis).and_raise(Errno::ECONNREFUSED)
|
280
|
+
end
|
281
|
+
|
282
|
+
context 'and db_failover config option is turned off' do
|
283
|
+
|
284
|
+
describe 'ab_test' do
|
285
|
+
it 'should raise an exception' do
|
286
|
+
lambda {
|
287
|
+
ab_test('link_color', 'blue', 'red')
|
288
|
+
}.should raise_error(Errno::ECONNREFUSED)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
describe 'finished' do
|
293
|
+
it 'should raise an exception' do
|
294
|
+
lambda {
|
295
|
+
finished('link_color')
|
296
|
+
}.should raise_error(Errno::ECONNREFUSED)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'and db_failover config option is turned on' do
|
303
|
+
|
304
|
+
before(:each) do
|
305
|
+
Split.configure do |config|
|
306
|
+
config.db_failover = true
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe 'ab_test' do
|
311
|
+
it 'should not raise an exception' do
|
312
|
+
lambda {
|
313
|
+
ab_test('link_color', 'blue', 'red')
|
314
|
+
}.should_not raise_error(Errno::ECONNREFUSED)
|
315
|
+
end
|
316
|
+
it 'should call db_failover_on_db_error proc with error as parameter' do
|
317
|
+
Split.configure do |config|
|
318
|
+
config.db_failover_on_db_error = proc do |error|
|
319
|
+
error.should be_a(Errno::ECONNREFUSED)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
Split.configuration.db_failover_on_db_error.should_receive(:call)
|
323
|
+
ab_test('link_color', 'blue', 'red')
|
324
|
+
end
|
325
|
+
it 'should always use first alternative' do
|
326
|
+
10.times do
|
327
|
+
ab_test('link_color', 'blue', 'red').should eq('blue')
|
328
|
+
ab_test('link_color', 'blue' => 0.01, 'red' => 0.2).should eq('blue')
|
329
|
+
ab_test('link_color', {'blue' => 0.8}, {'red' => 20}).should eq('blue')
|
330
|
+
ab_test('link_color', 'blue', 'red') do |link_color|
|
331
|
+
link_color.should eq('blue')
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe 'finished' do
|
338
|
+
it 'should not raise an exception' do
|
339
|
+
lambda {
|
340
|
+
finished('link_color')
|
341
|
+
}.should_not raise_error(Errno::ECONNREFUSED)
|
342
|
+
end
|
343
|
+
it 'should call db_failover_on_db_error proc with error as parameter' do
|
344
|
+
Split.configure do |config|
|
345
|
+
config.db_failover_on_db_error = proc do |error|
|
346
|
+
error.should be_a(Errno::ECONNREFUSED)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
Split.configuration.db_failover_on_db_error.should_receive(:call)
|
350
|
+
finished('link_color')
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
|
356
|
+
end
|
357
|
+
|
358
|
+
end
|
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.3.
|
4
|
+
version: 0.3.2
|
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:
|
12
|
+
date: 2012-02-12 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement: &
|
16
|
+
requirement: &70251262594940 !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: *70251262594940
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redis-namespace
|
27
|
-
requirement: &
|
27
|
+
requirement: &70251262594280 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.0.3
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70251262594280
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sinatra
|
38
|
-
requirement: &
|
38
|
+
requirement: &70251262592740 !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: *70251262592740
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &70251262591720 !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: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70251262591720
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: bundler
|
60
|
-
requirement: &
|
60
|
+
requirement: &70251262589960 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '1.0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70251262589960
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
|
-
requirement: &
|
71
|
+
requirement: &70251262588940 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '2.6'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70251262588940
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rack-test
|
82
|
-
requirement: &
|
82
|
+
requirement: &70251262585780 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0.6'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70251262585780
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: guard-rspec
|
93
|
-
requirement: &
|
93
|
+
requirement: &70251262579760 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: '0.4'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70251262579760
|
102
102
|
description:
|
103
103
|
email:
|
104
104
|
- andrewnez@gmail.com
|
@@ -145,18 +145,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
145
145
|
- - ! '>='
|
146
146
|
- !ruby/object:Gem::Version
|
147
147
|
version: '0'
|
148
|
-
segments:
|
149
|
-
- 0
|
150
|
-
hash: -3943651241702022185
|
151
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
149
|
none: false
|
153
150
|
requirements:
|
154
151
|
- - ! '>='
|
155
152
|
- !ruby/object:Gem::Version
|
156
153
|
version: '0'
|
157
|
-
segments:
|
158
|
-
- 0
|
159
|
-
hash: -3943651241702022185
|
160
154
|
requirements: []
|
161
155
|
rubyforge_project: split
|
162
156
|
rubygems_version: 1.8.6
|