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.
@@ -1,3 +1,9 @@
1
+ ## 0.3.2 (February 12, 2012)
2
+
3
+ Features:
4
+
5
+ - Handle redis errors gracefully (@layflags, #32)
6
+
1
7
  ## 0.3.1 (November 19, 2011)
2
8
 
3
9
  Features:
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Andrew Nesbitt
1
+ Copyright (c) 2012 Andrew Nesbitt
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -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("buy_new_points")
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) 2011 Andrew Nesbitt. See [LICENSE](https://github.com/andrew/split/blob/master/LICENSE) for details.
254
+ Copyright (c) 2012 Andrew Nesbitt. See [LICENSE](https://github.com/andrew/split/blob/master/LICENSE) for details.
@@ -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
@@ -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)
@@ -1,3 +1,3 @@
1
1
  module Split
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -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
@@ -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
- end
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.1
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: 2011-11-19 00:00:00.000000000Z
12
+ date: 2012-02-12 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &70308912822720 !ruby/object:Gem::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: *70308912822720
24
+ version_requirements: *70251262594940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: redis-namespace
27
- requirement: &70308912821980 !ruby/object:Gem::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: *70308912821980
35
+ version_requirements: *70251262594280
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sinatra
38
- requirement: &70308912821300 !ruby/object:Gem::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: *70308912821300
46
+ version_requirements: *70251262592740
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
- requirement: &70308912820460 !ruby/object:Gem::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: *70308912820460
57
+ version_requirements: *70251262591720
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: bundler
60
- requirement: &70308912819780 !ruby/object:Gem::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: *70308912819780
68
+ version_requirements: *70251262589960
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &70308912819060 !ruby/object:Gem::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: *70308912819060
79
+ version_requirements: *70251262588940
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rack-test
82
- requirement: &70308912818400 !ruby/object:Gem::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: *70308912818400
90
+ version_requirements: *70251262585780
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: guard-rspec
93
- requirement: &70308912817760 !ruby/object:Gem::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: *70308912817760
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