ruby_optimize 2.3 → 2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 06219338afa9e9b6a5feb8b10e5accb8728a82c3
4
- data.tar.gz: 35fc66284257c5c4327dc42dccfcec447352977c
3
+ metadata.gz: 3a1365d9b9f6abb4a8c2a9bdd7bbf1e2f372c579
4
+ data.tar.gz: ffe1f085d2b3816ad11cb6b52f5b2903284af23f
5
5
  SHA512:
6
- metadata.gz: 99088d7643a95a1c1e6ca9907f38a2909b056dac8ec7ec9a2d3857d0ad8f2c7676d84ee48d8299ebe6581fb68a85c48dd5cf8b3cdc031fc19f8cffd6e7f76b9e
7
- data.tar.gz: 1ecff56be0b92756e88dafe26c52ed9ae22a3fd4cd810c17f1d2d15d13bce43f42bbdf92ff5d6f21913368b3229dfbaa30fa76820afc169ee6d13aa83436c409
6
+ metadata.gz: d6bc2bd20e428a39823aa2d6e27d43db7ead576ceaad15facfbcf7d7fa53524a17542490abaf391b19e7a4a73ec30e2100bfbd306b31a04b7f62fbd42af14bba
7
+ data.tar.gz: b0889d323703e63c3ef303df9b3c1f700c780415db3df2e30157b433368281bada8c0eb4b60d2652310dde5cc305886adc9bb34405c98214d9739639033951a1
data/README.md CHANGED
@@ -1,13 +1,10 @@
1
- To know more about RubyOptimize look at the [full documentation](https://github.com/adrdilauro/ruby_optimize/wiki/Full-documentation).
2
-
3
1
  # Features
4
2
 
5
- 1. Set up an A/B test with a very **simple** and **descriptive code** (the gem consists of just three methods)
3
+ 1. Set up an A/B test with a very **simple** and **descriptive code** (the gem consists of just two methods)
6
4
  2. A/B tests are valid across different pages, using cookies
7
5
  3. You can test **multiple versions** with changes as complicated as you need, while still keeping the code clean and understandable
8
6
  4. Effortlessly set up **multiple A/B tests** that don't clash with each other (remembering of course to ensure that results of the tests are kept separated)
9
7
  5. Very easy to select a special version for crawlers, so you don't affect your SEO while you are running the test
10
- 6. The gem is safe and super tested (https://github.com/adrdilauro/ruby_optimize/blob/master/spec/ruby_optimize_spec.rb)
11
8
 
12
9
  # Usage
13
10
 
@@ -24,17 +21,14 @@ def initialize_ab_test
24
21
  ruby_optimize [ :v1, :v2, :v3 ] # Declare the names of all the versions you are going to test
25
22
  end
26
23
  ```
24
+ ..or in the specific `.erb` file where you need to set up the test, if the test is localized in only one place
27
25
 
28
- #### (2) - Render the script that reads / writes the cookie
29
- ```html
30
- <head>
31
- <%= ruby_optimize_init %>
32
- ...
33
- </head>
26
+ ```HTML+ERB
27
+ <% ruby_optimize [ :v1, :v2, :v3 ] %>
34
28
  ```
35
29
 
36
- #### (3) - Wrap blocks of HTML that will be rendered depending on the version
37
- ```html
30
+ #### (2) - Wrap blocks of HTML that will be rendered depending on the version
31
+ ```HTML+ERB
38
32
  <%= ruby_optimize_wrap(:v1) do %>
39
33
  <div class="for-version-1">
40
34
  ...
@@ -48,26 +42,6 @@ end
48
42
  <% end %>
49
43
  ```
50
44
 
51
- # How it works
52
-
53
- When you call `ruby_optimize_init` in your `.erb` files, you will render a simple synchronous script that
54
-
55
- - tries to read the cookie relative to your A/B test
56
- - if the cookie is not present, extract a random version among the ones you defined, and store it in a cookie
57
- - save the version in an internal javascript object that will be used across the page
58
-
59
- When you wrap a block of HTML inside `ruby_optimize_wrap`, passing a specific version, the block will be wrapped inside a `<div>` with a generated random id, and after the block it will be appended a synchronous `<script>` tag that looks like this:
60
-
61
- ```html
62
- <script>
63
- window.rubyOptimizerObject.keepOrRemoveHtmlBlock('[random id]', '[version]');
64
- </script>
65
- ```
66
-
67
- If the version passed doesn't match with the version that has been stored on the top of the page, then the block is removed. This happens before the page is fully rendered, so there isn't any chance to get page flickering.
68
-
69
- The synchronous scripts are really simple and don't slow down page rendering time.
70
-
71
45
 
72
46
  # Why RubyOptimize is good for complex A/B tests
73
47
 
@@ -77,6 +51,7 @@ You can easily span your tests across different pages reading the same cookie, w
77
51
 
78
52
  You can maintain as many different A/B tests you want without risking them to clash.
79
53
 
54
+
80
55
  # Why RubyOptimize is good for small A/B tests as well
81
56
 
82
57
  Usually, to set up a small A/B test (changing a color, removing or adding a div, etc) people use client side tools like Google Optimize.
@@ -88,3 +63,136 @@ Now, usually Google Optimize tag loads fast, but you cannot always rely on exter
88
63
  This means that, even if your server has responded in 150 milliseconds, your user won't be able to see anything in the page until the 4 seconds have expired.
89
64
 
90
65
  Are you sure you want to risk this? With RubyOptimize you can set up a simple A/B test easily and cleanly directly in the code, this means that you can get rid of the hide-page tag, and let Google Optimize focus only on data collection.
66
+
67
+
68
+ # How it works
69
+
70
+ ### Initialization of a test
71
+
72
+ When you call `ruby_optimize` in your controller or `.erb` file, RubyOptimize instantiates a new `AbTestHandler` object scoped for that test, and appends it to a global variable that collects all the tests; this way there is a specific object that handles each separate test, and your tests won't clash.
73
+
74
+ Each `AbTestHandler` object saves data to its own cookie: the first thing it does when it gets initialised is verifying if the cookie is already present: if it's not present, it extracts a random version among the ones you defined.
75
+
76
+ ### Wrapping a block of HTML
77
+
78
+ When you wrap a block of HTML inside `ruby_optimize_wrap`, the helper method finds the corresponding `AbTestHandler` object and asks it whether the block has to be rendered. The `AbTestHandler` object takes it decision based on which version has stored internally, and on whether the request comes from a crawler.
79
+
80
+
81
+ # Examples of configuration
82
+
83
+
84
+ ### 1 - Simplest configuration
85
+
86
+ ```ruby
87
+ ruby_optimize([ :v1, :v2, :v3 ]
88
+ ```
89
+
90
+ A test is initialized containing three different versions, each having one third of probability to be extracted.
91
+
92
+
93
+ ### 2 - Initialize more than one test
94
+
95
+ ```ruby
96
+ ruby_optimize([ :small, :large ]
97
+ ruby_optimize([ :old, :new ], scope: :first_test
98
+ ruby_optimize([ :v1, :v2, :v3 ], scope: :second_test
99
+ ```
100
+
101
+ To set up more than one test, you have to specify a `:scope`, which has to be an alphanumeric symbol. You can't define more than one test associated to the same scope.
102
+
103
+ When you don't specify the `:scope` option, it automatically gets the value of `:default`.
104
+
105
+
106
+ ### 3 - Initialization options
107
+
108
+ ```ruby
109
+ # If not specified, domain defaults to :all
110
+ ruby_optimize [ :v1, :v2 ], domain: 'www.example.com'
111
+ ```
112
+ ```ruby
113
+ # Cookie expiration can be either an integer or a Time instance
114
+ # If not specified, it defaults to 180 days
115
+ ruby_optimize [ :v1, :v2 ], cookie_expiration: 1.month
116
+ ```
117
+ ```ruby
118
+ # Version :old will always be the one shown to crawlers, without need to specify it case per case
119
+ ruby_optimize [ :old, :new ], version_for_crawler: :old
120
+ ```
121
+ ```ruby
122
+ # The cookie is stored in Rails session
123
+ ruby_optimize [ :old, :new ], session_cookie: true
124
+ ```
125
+ ```ruby
126
+ # If you use :session_cookie together with :cookie_expiration, the cookie is stored in session and :cookie_expiration is ignored
127
+ # Another option that is ignored if you use :session_cookie is :domain
128
+ ruby_optimize [ :old, :new ], session_cookie: true, cookie_expiration: 1.month
129
+ ```
130
+
131
+ ### 4 - Weighted versions
132
+
133
+ You can add a hash of custom weights, associate to some of the versions an integer or a float included between 0 and 100. This number will be used to do a weighted extraction.
134
+
135
+ To calculate all the weights, RubyOptimize sums the weights you explicitly specified, and divides equally the remaining versions. If the sum of the weights you specified is over 100, you'll get an error.
136
+
137
+ ```ruby
138
+ ruby_optimize [ :v1, :v2, :v3 ], weights: { v1: 40 } # 40% - 30% - 30%
139
+ ruby_optimize [ :v1, :v2, :v3 ], weights: { v1: 90, v2: 9 } # 90% - 9% - 1%
140
+ ruby_optimize [ :v1, :v2, :v3 ], weights: { v1: 50, v2: 55 } # Exception raised
141
+ ruby_optimize [ :v1, :v2, :v3 ], weights: { v1: 40, v2: 30, v3: 35 } # Exception raised
142
+ ruby_optimize [ :v1, :v2, :v3 ], weights: { v1: 40, v6: 45 } # Exception raised because v6 has not been declared
143
+ ```
144
+
145
+ An example that combines more options
146
+
147
+ ```ruby
148
+ ruby_optimize [ :v1, :v2, :v3 ], scope: :navbar_test, session_cookie: true, domain: 'test.example.com', weights: { v3: 40 }
149
+ ```
150
+
151
+ ### 5 - Wrap options
152
+
153
+ ```HTML+ERB
154
+ <%= ruby_optimize_wrap(:v1) do %>
155
+ <!-- Rendered if visit doesn't come from a crawler and the version extracted is :v1 -->
156
+ <!-- Rendered if visit comes from a crawler and you have previously set up :v1 as global version for crawlers -->
157
+ <div>Hello World</div>
158
+ <% end %>
159
+ ```
160
+
161
+ Scope is `:default`. The version passed needs to be present and be one of the ones defined on `:default` scope
162
+
163
+ ```HTML+ERB
164
+ <%= ruby_optimize_wrap(:v1, :some_scope) do %>
165
+ <!-- Rendered if visit doesn't come from a crawler and the version extracted is :v1 -->
166
+ <!-- Rendered if visit comes from a crawler and you have previously set up :v1 as global version for crawlers under scope :some_scope -->
167
+ <div>Hello World</div>
168
+ <% end %>
169
+ ```
170
+
171
+ The only difference is that we explicitly selected scope `:some_scope`, so `:v1` must match one version defined in that scope rather than in `:default`
172
+
173
+ An exception is raised if the selected scope doesn't correspond to any `AbTestHandler` previously initialized.
174
+
175
+ ```HTML+ERB
176
+ <%= ruby_optimize_wrap(:v1, :some_scope, version_for_crawler: true) do %>
177
+ <!-- Rendered if visit doesn't come from a crawler and the version extracted is :v1 -->
178
+ <!-- Rendered if visit comes from a crawler, regardless of how you configured the test -->
179
+ <div>Hello World</div>
180
+ <% end %>
181
+
182
+ <%= ruby_optimize_wrap(:v1, version_for_crawler: true) do %>
183
+ <!-- Rendered if visit doesn't come from a crawler and the version extracted is :v1 -->
184
+ <!-- Rendered if visit comes from a crawler, regardless of how you configured the test -->
185
+ <div>Hello World</div>
186
+ <% end %>
187
+ ```
188
+
189
+ The final example covers the case when you want to prepare a special version that is ONLY shown to crawlers
190
+
191
+ ```HTML+ERB
192
+ <%= ruby_optimize_wrap(version_for_crawler: true) do %>
193
+ <!-- Rendered only if visit comes from a crawler -->
194
+ <div>Hello Crawler</div>
195
+ <% end %>
196
+ ```
197
+
198
+ This is the only case in which it's acceptable not to set a version. Scope is not necessary because this HTML doesn't affect any of our tests
@@ -4,7 +4,7 @@ module RubyOptimize
4
4
  @ruby_optimize = {} if @ruby_optimize.nil?
5
5
  scope = params[:scope] || :default
6
6
  raise "RubyOptimize - scope already defined: #{scope.inspect}" if @ruby_optimize.has_key?(scope)
7
- @ruby_optimize[scope] = AbTestHandler.new(cookies, versions, scope, request.user_agent, params[:domain], params[:cookie_expiration], params[:version_for_crawler])
7
+ @ruby_optimize[scope] = AbTestHandler.new(cookies, versions, scope, request.user_agent, params[:domain], params[:cookie_expiration], params[:version_for_crawler], !!params[:session_cookie], params[:weights])
8
8
  end
9
9
  end
10
10
  end
@@ -12,7 +12,7 @@ module RubyOptimize
12
12
  'y!j-asr', 'AddThis'
13
13
  ].join('|')}/i
14
14
 
15
- def initialize(cookies, some_versions, scope, agent, domain=nil, a_cookie_expiration=nil, a_version_for_crawler=nil)
15
+ def initialize(cookies, some_versions, scope, agent, domain=nil, a_cookie_expiration=nil, a_version_for_crawler=nil, use_session_cookies=false, custom_weights=nil)
16
16
  @versions = some_versions
17
17
  validate_versions
18
18
  validate_scope(scope)
@@ -26,19 +26,20 @@ module RubyOptimize
26
26
  if cookies.has_key?(cookie_name)
27
27
  @version = cookies[cookie_name].to_sym
28
28
  else
29
- @version = versions.sample
30
- cookies[cookie_name] = {
29
+ @version = extract_random_version(custom_weights || {})
30
+ cookie_hash = {
31
31
  value: version,
32
- expires: cookie_expiration.from_now,
33
32
  domain: domain || :all,
34
33
  }
34
+ cookie_hash[:expires] = cookie_expiration.from_now if !use_session_cookies
35
+ cookies[cookie_name] = cookie_hash
35
36
  end
36
37
  end
37
38
 
38
39
  def show?(a_version, for_crawler)
39
40
  raise "RubyOptimize - for_crawler must be a boolean: #{for_crawler.inspect}" if for_crawler != !!for_crawler
40
41
  return for_crawler || (!version_for_crawler.nil? && a_version == version_for_crawler) if is_crawler
41
- raise "RubyOptimize - version must be one of the available versions: #{a_version.inspect}" if !a_version.nil? && !versions.include?(a_version)
42
+ raise "RubyOptimize - version must be one of the available versions: #{a_version.inspect}" if !versions.include?(a_version)
42
43
  a_version == version
43
44
  end
44
45
 
@@ -63,6 +64,38 @@ module RubyOptimize
63
64
  raise "RubyOptimize - version_for_crawler must be one of the available versions: #{version_for_crawler.inspect}" if !version_for_crawler.nil? && !versions.include?(version_for_crawler)
64
65
  end
65
66
 
67
+ def validate_weight_against_versions(weight_version)
68
+ raise "RubyOptimize - weight associated to a non declared version: #{weight_version.inspect}" if !versions.include?(weight_version)
69
+ end
70
+
71
+ def validate_total_declared_weight(total_weight)
72
+ raise "RubyOptimize - sum of declared weights is greater than 100: #{total_weight.inspect}" if total_weight >= 100
73
+ end
74
+
75
+ def extract_random_version(weights)
76
+ processed_weights = []
77
+ total_weight = 0
78
+ temp_versions = versions.clone
79
+ index = 0
80
+ weights.each do |key, value|
81
+ validate_weight_against_versions(key)
82
+ temp_versions.delete(key)
83
+ total_weight += value.to_f.round(2)
84
+ processed_weights << [ total_weight, key ]
85
+ end
86
+ validate_total_declared_weight(total_weight)
87
+ remaining_weight = ((100 - total_weight).to_f / temp_versions.length).round(2)
88
+ temp_versions.each do |a_version|
89
+ total_weight += remaining_weight
90
+ processed_weights << [ total_weight, a_version ]
91
+ end
92
+ processed_weights[processed_weights.length - 1] = [ 100, processed_weights[processed_weights.length - 1][1] ]
93
+ extracted_number = rand() * 100
94
+ processed_weights.each do |weight_and_version|
95
+ return weight_and_version[1] if extracted_number <= weight_and_version[0]
96
+ end
97
+ end
98
+
66
99
  attr_reader :cookie_expiration, :cookie_name, :version_for_crawler, :is_crawler, :version, :versions
67
100
  end
68
101
  end
@@ -1,3 +1,3 @@
1
1
  module RubyOptimize
2
- VERSION = '2.3'
2
+ VERSION = '2.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_optimize
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.3'
4
+ version: '2.5'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adriano di Lauro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-26 00:00:00.000000000 Z
11
+ date: 2017-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -87,7 +87,6 @@ files:
87
87
  - lib/ruby_optimize/railtie.rb
88
88
  - lib/ruby_optimize/version.rb
89
89
  - ruby_optimize.gemspec
90
- - spec/ruby_optimize_spec.rb
91
90
  homepage: https://github.com/adrdilauro/ruby_optimize
92
91
  licenses:
93
92
  - MIT
@@ -1,546 +0,0 @@
1
- require 'rails_helper'
2
-
3
- RSpec.describe AbTestHandler, type: :model do
4
- def ruby_optimize(versions, **params)
5
- @ruby_optimize = {} if @ruby_optimize.nil?
6
- scope = params[:scope] || :default
7
- raise "RubyOptimize - scope already defined: #{scope.inspect}" if @ruby_optimize.has_key?(scope)
8
- @ruby_optimize[scope] = AbTestHandler.new({}, versions, scope, request.user_agent, params[:domain], params[:cookie_expiration], params[:version_for_crawler])
9
- end
10
-
11
- def ruby_optimize_wrap(*version_and_scope, **params, &block)
12
- scope = version_and_scope[1] || :default
13
- raise "RubyOptimize - A/B test not initialized" if @ruby_optimize.nil?
14
- raise "RubyOptimize - scope not found: #{scope.inspect}" if !@ruby_optimize.has_key?(scope)
15
- @ruby_optimize[scope].wrap(yield, version_and_scope[0], !!params[:version_for_crawler])
16
- end
17
-
18
- def fake_wrapped(version, random_div_id, js_object_id)
19
- " <div id=\"#{random_div_id}\">\n hello\n </div>\n <script>\n window['#{js_object_id}'].handle('#{version}', '#{random_div_id}');\n </script>\n"
20
- end
21
-
22
- describe 'create' do
23
- context 'not crawler' do
24
- let(:request) do
25
- OpenStruct.new(user_agent: 'safari')
26
- end
27
-
28
- it 'raises an error if "versions" is not an array' do
29
- expect do
30
- ruby_optimize 'hello'
31
- end.to raise_error('RubyOptimize - you need to pass an array of at least two versions: "hello"')
32
- end
33
-
34
- it 'raises an error if there are less than two versions, 1' do
35
- expect do
36
- ruby_optimize [ 'helllo' ]
37
- end.to raise_error('RubyOptimize - you need to pass an array of at least two versions: ["helllo"]')
38
- end
39
-
40
- it 'raises an error if there are less than two versions, 2' do
41
- expect do
42
- ruby_optimize []
43
- end.to raise_error('RubyOptimize - you need to pass an array of at least two versions: []')
44
- end
45
-
46
- it 'raises an error if there versions are not alphanumeric, 1' do
47
- expect do
48
- ruby_optimize [ 'v1', :v2 ]
49
- end.to raise_error('RubyOptimize - versions need to be alphanumeric symbols: ["v1", :v2]')
50
- end
51
-
52
- it 'raises an error if there versions are not alphanumeric, 2' do
53
- expect do
54
- ruby_optimize [ :v1, :v2, 3 ]
55
- end.to raise_error('RubyOptimize - versions need to be alphanumeric symbols: [:v1, :v2, 3]')
56
- end
57
-
58
- it 'raises an error if there versions are not alphanumeric, 3' do
59
- expect do
60
- ruby_optimize [ :'v-1', :v2, :v3 ]
61
- end.to raise_error('RubyOptimize - versions need to be alphanumeric symbols: [:"v-1", :v2, :v3]')
62
- end
63
-
64
- it 'raises an error if there versions are not alphanumeric, 4' do
65
- expect do
66
- ruby_optimize [ :'v1-', :v2, :v3 ]
67
- end.to raise_error('RubyOptimize - versions need to be alphanumeric symbols: [:"v1-", :v2, :v3]')
68
- end
69
-
70
- it 'raises an error if scope is not alphanumeric, 1' do
71
- expect do
72
- ruby_optimize [ :v1, :v2, :v3 ], scope: 23
73
- end.to raise_error('RubyOptimize - scope needs to be an alphanumeric symbol: 23')
74
- end
75
-
76
- it 'raises an error if scope is not alphanumeric, 2' do
77
- expect do
78
- ruby_optimize [ :v1, :v2, :v3 ], scope: 'ehi23'
79
- end.to raise_error('RubyOptimize - scope needs to be an alphanumeric symbol: "ehi23"')
80
- end
81
-
82
- it 'raises an error if scope is not alphanumeric, 3' do
83
- expect do
84
- ruby_optimize [ :v1, :v2, :v3 ], scope: :'ehi-'
85
- end.to raise_error('RubyOptimize - scope needs to be an alphanumeric symbol: :"ehi-"')
86
- end
87
-
88
- it 'raises an error if cookie_expiration is not a positive integer, 1' do
89
- expect do
90
- ruby_optimize [ :v1, :v2, :v3 ], cookie_expiration: 'ahi'
91
- end.to raise_error('RubyOptimize - cookie_expiration needs to be an integer greater than zero: 0')
92
- end
93
-
94
- it 'raises an error if cookie_expiration is not a positive integer, 2' do
95
- expect do
96
- ruby_optimize [ :v1, :v2, :v3 ], cookie_expiration: -1
97
- end.to raise_error('RubyOptimize - cookie_expiration needs to be an integer greater than zero: -1')
98
- end
99
-
100
- it 'raises an error if version_for_crawler is not one of the whitelisted versions' do
101
- expect do
102
- ruby_optimize [ :v1, :v2, :v3 ], version_for_crawler: 'ehi'
103
- end.to raise_error('RubyOptimize - version_for_crawler must be one of the available versions: "ehi"')
104
- end
105
-
106
- it 'raises an error if version_for_crawler is not one of the whitelisted versions' do
107
- expect do
108
- ruby_optimize [ :v1, :v2, :v3 ], version_for_crawler: :v4
109
- end.to raise_error('RubyOptimize - version_for_crawler must be one of the available versions: :v4')
110
- end
111
-
112
- it 'does not raise any error if cookie_expiration is explicitly nil' do
113
- expect do
114
- ruby_optimize [ :v1, :v2, :v3 ], cookie_expiration: nil
115
- end.not_to raise_error
116
- end
117
-
118
- it 'does not raise any error if version_for_crawler is explicitly nil' do
119
- expect do
120
- ruby_optimize [ :v1, :v2, :v3 ], version_for_crawler: nil
121
- end.not_to raise_error
122
- end
123
-
124
- it 'raises an error if you try to access the same scope twice' do
125
- expect do
126
- ruby_optimize [ :v1, :v2, :v3 ], scope: :myscope
127
- ruby_optimize [ :v4, :v5 ], scope: :myscope
128
- end.to raise_error('RubyOptimize - scope already defined: :myscope')
129
- end
130
-
131
- it 'raises an error if you try to access the same scope twice (default)' do
132
- expect do
133
- ruby_optimize [ :v1, :v2, :v3 ]
134
- ruby_optimize [ :v4, :v5 ]
135
- end.to raise_error('RubyOptimize - scope already defined: :default')
136
- end
137
-
138
- it 'raises an error if you try to access the same scope twice (default set explicitly 1)' do
139
- expect do
140
- ruby_optimize [ :v1, :v2, :v3 ], scope: :default
141
- ruby_optimize [ :v4, :v5 ]
142
- end.to raise_error('RubyOptimize - scope already defined: :default')
143
- end
144
-
145
- it 'raises an error if you try to access the same scope twice (default set explicitly 2)' do
146
- expect do
147
- ruby_optimize [ :v1, :v2, :v3 ]
148
- ruby_optimize [ :v4, :v5 ], scope: :default
149
- end.to raise_error('RubyOptimize - scope already defined: :default')
150
- end
151
-
152
- it 'raises an error if you try using the object without having initialized it previously' do
153
- expect do
154
- ruby_optimize_wrap(:v1) do
155
- 'hello'
156
- end
157
- end.to raise_error('RubyOptimize - A/B test not initialized')
158
- expect do
159
- ruby_optimize_wrap(:v1, :somescope) do
160
- 'hello'
161
- end
162
- end.to raise_error('RubyOptimize - A/B test not initialized')
163
- end
164
-
165
- it 'correctly sets up the object, init scripts, wrap' do
166
- ruby_optimize [ :v1, :v2, :v3 ]
167
- ruby_optimize [ :old, :new ], scope: :test
168
- ruby_optimize [ :old, :new ], scope: :test2, cookie_expiration: nil, version_for_crawler: nil
169
- ruby_optimize [ :v4, :v5 ], scope: :test3, cookie_expiration: 33
170
- ruby_optimize [ :v4, :v5 ], scope: :test4, version_for_crawler: :v5
171
- expect(@ruby_optimize.class.to_s).to eq('Hash')
172
- expect(@ruby_optimize.keys.length).to eq(5)
173
- expect(@ruby_optimize.keys.sort[0]).to eq(:default)
174
- expect(@ruby_optimize.keys.sort[1]).to eq(:test)
175
- expect(@ruby_optimize.keys.sort[2]).to eq(:test2)
176
- expect(@ruby_optimize.keys.sort[3]).to eq(:test3)
177
- expect(@ruby_optimize.keys.sort[4]).to eq(:test4)
178
- # WRAP GENERIC
179
- expect do
180
- ruby_optimize_wrap(:v1, :anotherscope) do
181
- 'hello'
182
- end
183
- end.to raise_error('RubyOptimize - scope not found: :anotherscope')
184
- expect do
185
- @ruby_optimize[:default].wrap('hello', :v1, 'true') do
186
- 'hello'
187
- end
188
- end.to raise_error('RubyOptimize - for_crawler must be a boolean: "true"')
189
- # DEFAULT SET UP
190
- def (@ruby_optimize[:default]).set_version(a_version)
191
- @version = a_version
192
- end
193
- def (@ruby_optimize[:default]).get_cookie_expiration
194
- cookie_expiration
195
- end
196
- def (@ruby_optimize[:default]).get_cookie_name
197
- cookie_name
198
- end
199
- def (@ruby_optimize[:default]).get_version_for_crawler
200
- version_for_crawler
201
- end
202
- def (@ruby_optimize[:default]).get_is_crawler
203
- is_crawler
204
- end
205
- def (@ruby_optimize[:default]).get_versions
206
- versions
207
- end
208
- expect(@ruby_optimize[:default].get_cookie_expiration).to eq(15552000)
209
- expect(@ruby_optimize[:default].get_cookie_name).to eq('ruby-optimize-cookie-default')
210
- expect(@ruby_optimize[:default].get_version_for_crawler).to eq(nil)
211
- expect(@ruby_optimize[:default].get_is_crawler).to eq(false)
212
- expect(@ruby_optimize[:default].get_versions.sort).to eq([:v1, :v2, :v3])
213
- # DEFAULT WRAP
214
- expect do
215
- ruby_optimize_wrap(:new) do
216
- 'hello'
217
- end
218
- end.to raise_error('RubyOptimize - version must be one of the available versions: :new')
219
- expect(ruby_optimize_wrap do
220
- 'hello'
221
- end).to eq('')
222
- @ruby_optimize[:default].set_version(:v1)
223
- expect(ruby_optimize_wrap(:v1) do
224
- 'hello'
225
- end).to eq('hello')
226
- @ruby_optimize[:default].set_version(:other)
227
- expect(ruby_optimize_wrap(:v1) do
228
- 'hello'
229
- end).to eq('')
230
- @ruby_optimize[:default].set_version(:v2)
231
- expect(ruby_optimize_wrap(:v2, :default) do
232
- 'hello'
233
- end).to eq('hello')
234
- @ruby_optimize[:default].set_version(:other)
235
- expect(ruby_optimize_wrap(:v2, :default) do
236
- 'hello'
237
- end).to eq('')
238
- @ruby_optimize[:default].set_version(:v3)
239
- expect(ruby_optimize_wrap(:v3, :default, version_for_crawler: true) do
240
- 'hello'
241
- end).to eq('hello')
242
- @ruby_optimize[:default].set_version(:other)
243
- expect(ruby_optimize_wrap(:v3, :default, version_for_crawler: true) do
244
- 'hello'
245
- end).to eq('')
246
- @ruby_optimize[:default].set_version(:v1)
247
- expect(ruby_optimize_wrap(:v1, version_for_crawler: true) do
248
- 'hello'
249
- end).to eq('hello')
250
- @ruby_optimize[:default].set_version(:other)
251
- expect(ruby_optimize_wrap(:v1, version_for_crawler: true) do
252
- 'hello'
253
- end).to eq('')
254
- expect(ruby_optimize_wrap(version_for_crawler: true) do
255
- 'hello'
256
- end).to eq('')
257
- # TEST SET UP
258
- def (@ruby_optimize[:test]).set_version(a_version)
259
- @version = a_version
260
- end
261
- def (@ruby_optimize[:test]).get_cookie_expiration
262
- cookie_expiration
263
- end
264
- def (@ruby_optimize[:test]).get_cookie_name
265
- cookie_name
266
- end
267
- def (@ruby_optimize[:test]).get_version_for_crawler
268
- version_for_crawler
269
- end
270
- def (@ruby_optimize[:test]).get_is_crawler
271
- is_crawler
272
- end
273
- def (@ruby_optimize[:test]).get_versions
274
- versions
275
- end
276
- expect(@ruby_optimize[:test].get_cookie_expiration).to eq(15552000)
277
- expect(@ruby_optimize[:test].get_cookie_name).to eq('ruby-optimize-cookie-test')
278
- expect(@ruby_optimize[:test].get_version_for_crawler).to eq(nil)
279
- expect(@ruby_optimize[:test].get_is_crawler).to eq(false)
280
- expect(@ruby_optimize[:test].get_versions.sort).to eq([:new, :old])
281
- # TEST WRAP
282
- expect do
283
- ruby_optimize_wrap(:v444, :test) do
284
- 'hello'
285
- end
286
- end.to raise_error('RubyOptimize - version must be one of the available versions: :v444')
287
- @ruby_optimize[:test].set_version(:old)
288
- expect(ruby_optimize_wrap(:old, :test) do
289
- 'hello'
290
- end).to eq('hello')
291
- @ruby_optimize[:test].set_version(:other)
292
- expect(ruby_optimize_wrap(:old, :test) do
293
- 'hello'
294
- end).to eq('')
295
- @ruby_optimize[:test].set_version(:new)
296
- expect(ruby_optimize_wrap(:new, :test, version_for_crawler: true) do
297
- 'hello'
298
- end).to eq('hello')
299
- @ruby_optimize[:test].set_version(:other)
300
- expect(ruby_optimize_wrap(:new, :test, version_for_crawler: true) do
301
- 'hello'
302
- end).to eq('')
303
- # TEST2 SET UP
304
- def (@ruby_optimize[:test2]).set_version(a_version)
305
- @version = a_version
306
- end
307
- def (@ruby_optimize[:test2]).get_cookie_expiration
308
- cookie_expiration
309
- end
310
- def (@ruby_optimize[:test2]).get_cookie_name
311
- cookie_name
312
- end
313
- def (@ruby_optimize[:test2]).get_version_for_crawler
314
- version_for_crawler
315
- end
316
- def (@ruby_optimize[:test2]).get_is_crawler
317
- is_crawler
318
- end
319
- def (@ruby_optimize[:test2]).get_versions
320
- versions
321
- end
322
- expect(@ruby_optimize[:test2].get_cookie_expiration).to eq(15552000)
323
- expect(@ruby_optimize[:test2].get_cookie_name).to eq('ruby-optimize-cookie-test2')
324
- expect(@ruby_optimize[:test2].get_version_for_crawler).to eq(nil)
325
- expect(@ruby_optimize[:test2].get_is_crawler).to eq(false)
326
- expect(@ruby_optimize[:test2].get_versions.sort).to eq([:new, :old])
327
- # TEST2 WRAP
328
- expect do
329
- ruby_optimize_wrap(:v444, :test2) do
330
- 'hello'
331
- end
332
- end.to raise_error('RubyOptimize - version must be one of the available versions: :v444')
333
- @ruby_optimize[:test2].set_version(:old)
334
- expect(ruby_optimize_wrap(:old, :test2) do
335
- 'hello'
336
- end).to eq('hello')
337
- @ruby_optimize[:test2].set_version(:other)
338
- expect(ruby_optimize_wrap(:old, :test2) do
339
- 'hello'
340
- end).to eq('')
341
- @ruby_optimize[:test2].set_version(:new)
342
- expect(ruby_optimize_wrap(:new, :test2, version_for_crawler: true) do
343
- 'hello'
344
- end).to eq('hello')
345
- @ruby_optimize[:test2].set_version(:other)
346
- expect(ruby_optimize_wrap(:new, :test2, version_for_crawler: true) do
347
- 'hello'
348
- end).to eq('')
349
- # TEST3 SET UP
350
- def (@ruby_optimize[:test3]).set_version(a_version)
351
- @version = a_version
352
- end
353
- def (@ruby_optimize[:test3]).get_cookie_expiration
354
- cookie_expiration
355
- end
356
- def (@ruby_optimize[:test3]).get_cookie_name
357
- cookie_name
358
- end
359
- def (@ruby_optimize[:test3]).get_version_for_crawler
360
- version_for_crawler
361
- end
362
- def (@ruby_optimize[:test3]).get_is_crawler
363
- is_crawler
364
- end
365
- def (@ruby_optimize[:test3]).get_versions
366
- versions
367
- end
368
- expect(@ruby_optimize[:test3].get_cookie_expiration).to eq(33)
369
- expect(@ruby_optimize[:test3].get_cookie_name).to eq('ruby-optimize-cookie-test3')
370
- expect(@ruby_optimize[:test3].get_version_for_crawler).to eq(nil)
371
- expect(@ruby_optimize[:test3].get_is_crawler).to eq(false)
372
- expect(@ruby_optimize[:test3].get_versions.sort).to eq([:v4, :v5])
373
- # TEST3 WRAP
374
- expect do
375
- ruby_optimize_wrap(:v444, :test3) do
376
- 'hello'
377
- end
378
- end.to raise_error('RubyOptimize - version must be one of the available versions: :v444')
379
- @ruby_optimize[:test3].set_version(:v4)
380
- expect(ruby_optimize_wrap(:v4, :test3) do
381
- 'hello'
382
- end).to eq('hello')
383
- @ruby_optimize[:test3].set_version(:other)
384
- expect(ruby_optimize_wrap(:v4, :test3) do
385
- 'hello'
386
- end).to eq('')
387
- @ruby_optimize[:test3].set_version(:v5)
388
- expect(ruby_optimize_wrap(:v5, :test3, version_for_crawler: true) do
389
- 'hello'
390
- end).to eq('hello')
391
- @ruby_optimize[:test3].set_version(:other)
392
- expect(ruby_optimize_wrap(:v5, :test3, version_for_crawler: true) do
393
- 'hello'
394
- end).to eq('')
395
- # TEST4 SET UP
396
- def (@ruby_optimize[:test4]).set_version(a_version)
397
- @version = a_version
398
- end
399
- def (@ruby_optimize[:test4]).get_cookie_expiration
400
- cookie_expiration
401
- end
402
- def (@ruby_optimize[:test4]).get_cookie_name
403
- cookie_name
404
- end
405
- def (@ruby_optimize[:test4]).get_version_for_crawler
406
- version_for_crawler
407
- end
408
- def (@ruby_optimize[:test4]).get_is_crawler
409
- is_crawler
410
- end
411
- def (@ruby_optimize[:test4]).get_versions
412
- versions
413
- end
414
- expect(@ruby_optimize[:test4].get_cookie_expiration).to eq(15552000)
415
- expect(@ruby_optimize[:test4].get_cookie_name).to eq('ruby-optimize-cookie-test4')
416
- expect(@ruby_optimize[:test4].get_version_for_crawler).to eq(:v5)
417
- expect(@ruby_optimize[:test4].get_is_crawler).to eq(false)
418
- expect(@ruby_optimize[:test4].get_versions.sort).to eq([:v4, :v5])
419
- # TEST4 WRAP
420
- expect do
421
- ruby_optimize_wrap(:v444, :test4) do
422
- 'hello'
423
- end
424
- end.to raise_error('RubyOptimize - version must be one of the available versions: :v444')
425
- @ruby_optimize[:test4].set_version(:v5)
426
- expect(ruby_optimize_wrap(:v5, :test4) do
427
- 'hello'
428
- end).to eq('hello')
429
- @ruby_optimize[:test4].set_version(:other)
430
- expect(ruby_optimize_wrap(:v5, :test4) do
431
- 'hello'
432
- end).to eq('')
433
- @ruby_optimize[:test4].set_version(:v4)
434
- expect(ruby_optimize_wrap(:v4, :test4, version_for_crawler: true) do
435
- 'hello'
436
- end).to eq('hello')
437
- @ruby_optimize[:test4].set_version(:other)
438
- expect(ruby_optimize_wrap(:v4, :test4, version_for_crawler: true) do
439
- 'hello'
440
- end).to eq('')
441
- end
442
- end
443
-
444
- context 'crawler' do
445
- let(:request) do
446
- OpenStruct.new(user_agent: 'summify')
447
- end
448
-
449
- it 'correctly sets up the object, empty init scripts, empty wrap' do
450
- ruby_optimize [ :v1, :v2, :v3 ]
451
- ruby_optimize [ :old, :new ], scope: :test, version_for_crawler: :old
452
- # WRAP GENERIC
453
- expect do
454
- ruby_optimize_wrap(:v1, :anotherscope) do
455
- 'hello'
456
- end
457
- end.to raise_error('RubyOptimize - scope not found: :anotherscope')
458
- expect do
459
- @ruby_optimize[:default].wrap('hello', :v1, 'true') do
460
- 'hello'
461
- end
462
- end.to raise_error('RubyOptimize - for_crawler must be a boolean: "true"')
463
- # DEFAULT SET UP
464
- def (@ruby_optimize[:default]).get_cookie_expiration
465
- cookie_expiration
466
- end
467
- def (@ruby_optimize[:default]).get_cookie_name
468
- cookie_name
469
- end
470
- def (@ruby_optimize[:default]).get_version_for_crawler
471
- version_for_crawler
472
- end
473
- def (@ruby_optimize[:default]).get_is_crawler
474
- is_crawler
475
- end
476
- def (@ruby_optimize[:default]).get_versions
477
- versions
478
- end
479
- expect(@ruby_optimize[:default].get_cookie_expiration).to eq(15552000)
480
- expect(@ruby_optimize[:default].get_cookie_name).to eq('ruby-optimize-cookie-default')
481
- expect(@ruby_optimize[:default].get_version_for_crawler).to eq(nil)
482
- expect(@ruby_optimize[:default].get_is_crawler).to eq(true)
483
- expect(@ruby_optimize[:default].get_versions.sort).to eq([:v1, :v2, :v3])
484
- # DEFAULT WRAP
485
- expect(ruby_optimize_wrap(:xxx) do
486
- 'hello'
487
- end).to eq('')
488
- expect(ruby_optimize_wrap do
489
- 'hello'
490
- end).to eq('')
491
- expect(ruby_optimize_wrap(:v1) do
492
- 'hello'
493
- end).to eq('')
494
- expect(ruby_optimize_wrap(:v2, :default) do
495
- 'hello'
496
- end).to eq('')
497
- expect(ruby_optimize_wrap(:v3, :default, version_for_crawler: true) do
498
- 'hello'
499
- end).to eq('hello')
500
- expect(ruby_optimize_wrap(:v1, version_for_crawler: true) do
501
- 'hello'
502
- end).to eq('hello')
503
- expect(ruby_optimize_wrap(version_for_crawler: true) do
504
- 'hello'
505
- end).to eq('hello')
506
- # TEST SET UP
507
- def (@ruby_optimize[:test]).get_cookie_expiration
508
- cookie_expiration
509
- end
510
- def (@ruby_optimize[:test]).get_cookie_name
511
- cookie_name
512
- end
513
- def (@ruby_optimize[:test]).get_version_for_crawler
514
- version_for_crawler
515
- end
516
- def (@ruby_optimize[:test]).get_is_crawler
517
- is_crawler
518
- end
519
- def (@ruby_optimize[:test]).get_versions
520
- versions
521
- end
522
- expect(@ruby_optimize[:test].get_cookie_expiration).to eq(15552000)
523
- expect(@ruby_optimize[:test].get_cookie_name).to eq('ruby-optimize-cookie-test')
524
- expect(@ruby_optimize[:test].get_version_for_crawler).to eq(:old)
525
- expect(@ruby_optimize[:test].get_is_crawler).to eq(true)
526
- expect(@ruby_optimize[:test].get_versions.sort).to eq([:new, :old])
527
- # TEST WRAP
528
- expect(ruby_optimize_wrap(:xxx, :test) do
529
- 'hello'
530
- end).to eq('')
531
- expect(ruby_optimize_wrap(:old, :test) do
532
- 'hello'
533
- end).to eq('hello')
534
- expect(ruby_optimize_wrap(:new, :test) do
535
- 'hello'
536
- end).to eq('')
537
- expect(ruby_optimize_wrap(:old, :test, version_for_crawler: true) do
538
- 'hello'
539
- end).to eq('hello')
540
- expect(ruby_optimize_wrap(:new, :test, version_for_crawler: true) do
541
- 'hello'
542
- end).to eq('hello')
543
- end
544
- end
545
- end
546
- end