split 3.0.0 → 3.3.0

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.
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+ require 'split/dashboard/paginator'
3
+
4
+ module Split
5
+ module DashboardPaginationHelpers
6
+ DEFAULT_PER = 10
7
+
8
+ def pagination_per
9
+ @pagination_per ||= (params[:per] || DEFAULT_PER).to_i
10
+ end
11
+
12
+ def page_number
13
+ @page_number ||= (params[:page] || 1).to_i
14
+ end
15
+
16
+ def paginated(collection)
17
+ Split::DashboardPaginator.new(collection, page_number, pagination_per).paginate
18
+ end
19
+
20
+ def pagination(collection)
21
+ html = []
22
+ html << first_page_tag if show_first_page_tag?
23
+ html << ellipsis_tag if show_first_ellipsis_tag?
24
+ html << prev_page_tag if show_prev_page_tag?
25
+ html << current_page_tag
26
+ html << next_page_tag if show_next_page_tag?(collection)
27
+ html << ellipsis_tag if show_last_ellipsis_tag?(collection)
28
+ html << last_page_tagcollection if show_last_page_tag?(collection)
29
+ html.join
30
+ end
31
+
32
+ private
33
+
34
+ def show_first_page_tag?
35
+ page_number > 2
36
+ end
37
+
38
+ def first_page_tag
39
+ %Q(<a href="#{url.chop}?page=1&per=#{pagination_per}">1</a>)
40
+ end
41
+
42
+ def show_first_ellipsis_tag?
43
+ page_number >= 4
44
+ end
45
+
46
+ def ellipsis_tag
47
+ '<span>...</span>'
48
+ end
49
+
50
+ def show_prev_page_tag?
51
+ page_number > 1
52
+ end
53
+
54
+ def prev_page_tag
55
+ %Q(<a href="#{url.chop}?page=#{page_number - 1}&per=#{pagination_per}">#{page_number - 1}</a>)
56
+ end
57
+
58
+ def current_page_tag
59
+ "<span><b>#{page_number}</b></span>"
60
+ end
61
+
62
+ def show_next_page_tag?(collection)
63
+ (page_number * pagination_per) < collection.count
64
+ end
65
+
66
+ def next_page_tag
67
+ %Q(<a href="#{url.chop}?page=#{page_number + 1}&per=#{pagination_per}">#{page_number + 1}</a>)
68
+ end
69
+
70
+ def show_last_ellipsis_tag?(collection)
71
+ (total_pages(collection) - page_number) >= 3
72
+ end
73
+
74
+ def total_pages(collection)
75
+ collection.count / pagination_per + ((collection.count % pagination_per).zero? ? 0 : 1)
76
+ end
77
+
78
+ def show_last_page_tag?(collection)
79
+ page_number < (total_pages(collection) - 1)
80
+ end
81
+
82
+ def last_page_tag(collection)
83
+ total = total_pages(collection)
84
+ %Q(<a href="#{url.chop}?page=#{total}&per=#{pagination_per}">#{total}</a>)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Split
3
+ class DashboardPaginator
4
+ def initialize(collection, page_number, per)
5
+ @collection = collection
6
+ @page_number = page_number
7
+ @per = per
8
+ end
9
+
10
+ def paginate
11
+ to = @page_number * @per
12
+ from = to - @per
13
+ @collection[from...to]
14
+ end
15
+ end
16
+ end
@@ -317,3 +317,12 @@ a.button.green:focus, button.green:focus, input[type="submit"].green:focus {
317
317
  }
318
318
 
319
319
 
320
+ .pagination {
321
+ text-align: center;
322
+ font-size: 15px;
323
+ }
324
+
325
+ .pagination a, .paginaton span {
326
+ display: inline-block;
327
+ padding: 5px;
328
+ }
@@ -6,7 +6,7 @@
6
6
  <input type="button" id="toggle-active" value="Hide active" />
7
7
  <input type="button" id="clear-filter" value="Clear filters" />
8
8
 
9
- <% @experiments.each do |experiment| %>
9
+ <% paginated(@experiments).each do |experiment| %>
10
10
  <% if experiment.goals.empty? %>
11
11
  <%= erb :_experiment, :locals => {:goal => nil, :experiment => experiment} %>
12
12
  <% else %>
@@ -16,6 +16,10 @@
16
16
  <% end %>
17
17
  <% end %>
18
18
  <% end %>
19
+
20
+ <div class="pagination">
21
+ <%= pagination(@experiments) %>
22
+ </div>
19
23
  <% else %>
20
24
  <p class="intro">No experiments have started yet, you need to define them in your code and introduce them to your users.</p>
21
25
  <p class="intro">Check out the <a href='https://github.com/splitrb/split#readme'>Readme</a> for more help getting started.</p>
@@ -3,6 +3,7 @@ require 'sinatra/base'
3
3
  require 'split'
4
4
  require 'bigdecimal'
5
5
  require 'split/dashboard/helpers'
6
+ require 'split/dashboard/pagination_helpers'
6
7
 
7
8
  module Split
8
9
  class Dashboard < Sinatra::Base
@@ -14,6 +15,7 @@ module Split
14
15
  set :method_override, true
15
16
 
16
17
  helpers Split::DashboardHelpers
18
+ helpers Split::DashboardPaginationHelpers
17
19
 
18
20
  get '/' do
19
21
  # Display experiments without a winner at the top of the dashboard
data/lib/split/engine.rb CHANGED
@@ -5,6 +5,8 @@ module Split
5
5
  if Split.configuration.include_rails_helper
6
6
  ActionController::Base.send :include, Split::Helper
7
7
  ActionController::Base.helper Split::Helper
8
+ ActionController::Base.send :include, Split::CombinedExperimentsHelper
9
+ ActionController::Base.helper Split::CombinedExperimentsHelper
8
10
  end
9
11
  end
10
12
  end
@@ -262,10 +262,11 @@ module Split
262
262
  end
263
263
 
264
264
  def calc_winning_alternatives
265
- # Super simple cache so that we only recalculate winning alternatives once per day
266
- days_since_epoch = Time.now.utc.to_i / 86400
265
+ # Cache the winning alternatives so we recalculate them once per the specified interval.
266
+ intervals_since_epoch =
267
+ Time.now.utc.to_i / Split.configuration.winning_alternative_recalculation_interval
267
268
 
268
- if self.calc_time != days_since_epoch
269
+ if self.calc_time != intervals_since_epoch
269
270
  if goals.empty?
270
271
  self.estimate_winning_alternative
271
272
  else
@@ -274,7 +275,7 @@ module Split
274
275
  end
275
276
  end
276
277
 
277
- self.calc_time = days_since_epoch
278
+ self.calc_time = intervals_since_epoch
278
279
 
279
280
  self.save
280
281
  end
data/lib/split/helper.rb CHANGED
@@ -10,6 +10,7 @@ module Split
10
10
  experiment = ExperimentCatalog.find_or_initialize(metric_descriptor, control, *alternatives)
11
11
  alternative = if Split.configuration.enabled
12
12
  experiment.save
13
+ raise(Split::InvalidExperimentsFormatError) unless (Split.configuration.experiments || {}).fetch(experiment.name.to_sym, {})[:combined_experiments].nil?
13
14
  trial = Trial.new(:user => ab_user, :experiment => experiment,
14
15
  :override => override_alternative(experiment.name), :exclude => exclude_visitor?,
15
16
  :disabled => split_generically_disabled?)
@@ -96,6 +97,14 @@ module Split
96
97
  Split.configuration.db_failover_on_db_error.call(e)
97
98
  end
98
99
 
100
+ def ab_active_experiments()
101
+ ab_user.active_experiments
102
+ rescue => e
103
+ raise unless Split.configuration.db_failover
104
+ Split.configuration.db_failover_on_db_error.call(e)
105
+ end
106
+
107
+
99
108
  def override_present?(experiment_name)
100
109
  override_alternative(experiment_name)
101
110
  end
@@ -113,13 +122,17 @@ module Split
113
122
  end
114
123
 
115
124
  def exclude_visitor?
116
- instance_eval(&Split.configuration.ignore_filter) || is_ignored_ip_address? || is_robot?
125
+ instance_exec(request, &Split.configuration.ignore_filter) || is_ignored_ip_address? || is_robot? || is_preview?
117
126
  end
118
127
 
119
128
  def is_robot?
120
129
  defined?(request) && request.user_agent =~ Split.configuration.robot_regex
121
130
  end
122
131
 
132
+ def is_preview?
133
+ defined?(request) && defined?(request.headers) && request.headers['x-purpose'] == 'preview'
134
+ end
135
+
123
136
  def is_ignored_ip_address?
124
137
  return false if Split.configuration.ignore_ip_addresses.empty?
125
138
 
@@ -6,20 +6,22 @@ module Split
6
6
  class CookieAdapter
7
7
 
8
8
  def initialize(context)
9
- @cookies = context.send(:cookies)
9
+ @context = context
10
+ @request, @response = context.request, context.response
11
+ @cookies = @request.cookies
10
12
  @expires = Time.now + cookie_length_config
11
13
  end
12
14
 
13
15
  def [](key)
14
- hash[key]
16
+ hash[key.to_s]
15
17
  end
16
18
 
17
19
  def []=(key, value)
18
- set_cookie(hash.merge(key => value))
20
+ set_cookie(hash.merge!(key.to_s => value))
19
21
  end
20
22
 
21
23
  def delete(key)
22
- set_cookie(hash.tap { |h| h.delete(key) })
24
+ set_cookie(hash.tap { |h| h.delete(key.to_s) })
23
25
  end
24
26
 
25
27
  def keys
@@ -28,22 +30,55 @@ module Split
28
30
 
29
31
  private
30
32
 
31
- def set_cookie(value)
32
- @cookies[:split] = {
33
- :value => JSON.generate(value),
34
- :expires => @expires
35
- }
33
+ def set_cookie(value = {})
34
+ cookie_key = :split.to_s
35
+ cookie_value = default_options.merge(value: JSON.generate(value))
36
+ if action_dispatch?
37
+ # The "send" is necessary when we call ab_test from the controller
38
+ # and thus @context is a rails controller, because then "cookies" is
39
+ # a private method.
40
+ @context.send(:cookies)[cookie_key] = cookie_value
41
+ else
42
+ set_cookie_via_rack(cookie_key, cookie_value)
43
+ end
44
+ end
45
+
46
+ def default_options
47
+ { expires: @expires, path: '/' }
48
+ end
49
+
50
+ def set_cookie_via_rack(key, value)
51
+ delete_cookie_header!(@response.header, key, value)
52
+ Rack::Utils.set_cookie_header!(@response.header, key, value)
53
+ end
54
+
55
+ # Use Rack::Utils#make_delete_cookie_header after Rack 2.0.0
56
+ def delete_cookie_header!(header, key, value)
57
+ cookie_header = header['Set-Cookie']
58
+ case cookie_header
59
+ when nil, ''
60
+ cookies = []
61
+ when String
62
+ cookies = cookie_header.split("\n")
63
+ when Array
64
+ cookies = cookie_header
65
+ end
66
+
67
+ cookies.reject! { |cookie| cookie =~ /\A#{Rack::Utils.escape(key)}=/ }
68
+ header['Set-Cookie'] = cookies.join("\n")
36
69
  end
37
70
 
38
71
  def hash
39
- if @cookies[:split]
40
- begin
41
- JSON.parse(@cookies[:split])
42
- rescue JSON::ParserError
72
+ @hash ||= begin
73
+ if cookies = @cookies[:split.to_s]
74
+ begin
75
+ JSON.parse(cookies)
76
+ rescue JSON::ParserError
77
+ {}
78
+ end
79
+ else
43
80
  {}
44
81
  end
45
- else
46
- {}
47
82
  end
48
83
  end
49
84
 
@@ -51,6 +86,9 @@ module Split
51
86
  Split.configuration.persistence_cookie_length
52
87
  end
53
88
 
89
+ def action_dispatch?
90
+ defined?(Rails) && @response.is_a?(ActionDispatch::Response)
91
+ end
54
92
  end
55
93
  end
56
94
  end
@@ -35,9 +35,7 @@ module Split
35
35
  end
36
36
 
37
37
  def make_list_length(list_name, new_length)
38
- while list_length(list_name) > new_length
39
- remove_last_item_from_list(list_name)
40
- end
38
+ redis.ltrim(list_name, 0, new_length - 1)
41
39
  end
42
40
 
43
41
  def add_to_set(set_name, value)
data/lib/split/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Split
3
3
  MAJOR = 3
4
- MINOR = 0
4
+ MINOR = 3
5
5
  PATCH = 0
6
6
  VERSION = [MAJOR, MINOR, PATCH].join('.')
7
7
  end
data/lib/split.rb CHANGED
@@ -13,6 +13,7 @@ require 'split/experiment_catalog'
13
13
  require 'split/extensions/string'
14
14
  require 'split/goals_collection'
15
15
  require 'split/helper'
16
+ require 'split/combined_experiments_helper'
16
17
  require 'split/metric'
17
18
  require 'split/persistence'
18
19
  require 'split/redis_interface'
@@ -273,6 +273,18 @@ describe Split::Alternative do
273
273
  expect(control.z_score(goal1)).to eq('N/A')
274
274
  expect(control.z_score(goal2)).to eq('N/A')
275
275
  end
276
+
277
+ it "should not blow up for Conversion Rates > 1" do
278
+ control = experiment.control
279
+ control.participant_count = 3474
280
+ control.set_completed_count(4244)
281
+
282
+ alternative2.participant_count = 3434
283
+ alternative2.set_completed_count(4358)
284
+
285
+ expect { control.z_score }.not_to raise_error
286
+ expect { alternative2.z_score }.not_to raise_error
287
+ end
276
288
  end
277
289
 
278
290
  describe "extra_info" do
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+ require 'split/combined_experiments_helper'
4
+
5
+ describe Split::CombinedExperimentsHelper do
6
+ include Split::CombinedExperimentsHelper
7
+
8
+ describe 'ab_combined_test' do
9
+ let!(:config_enabled) { true }
10
+ let!(:combined_experiments) { [:exp_1_click, :exp_1_scroll ]}
11
+ let!(:allow_multiple_experiments) { true }
12
+
13
+ before do
14
+ Split.configuration.experiments = {
15
+ :combined_exp_1 => {
16
+ :alternatives => [ {"control"=> 0.5}, {"test-alt"=> 0.5} ],
17
+ :metric => :my_metric,
18
+ :combined_experiments => combined_experiments
19
+ }
20
+ }
21
+ Split.configuration.enabled = config_enabled
22
+ Split.configuration.allow_multiple_experiments = allow_multiple_experiments
23
+ end
24
+
25
+ context 'without config enabled' do
26
+ let!(:config_enabled) { false }
27
+
28
+ it "raises an error" do
29
+ expect(lambda { ab_combined_test :combined_exp_1 }).to raise_error(Split::InvalidExperimentsFormatError )
30
+ end
31
+ end
32
+
33
+ context 'multiple experiments disabled' do
34
+ let!(:allow_multiple_experiments) { false }
35
+
36
+ it "raises an error if multiple experiments is disabled" do
37
+ expect(lambda { ab_combined_test :combined_exp_1 }).to raise_error(Split::InvalidExperimentsFormatError)
38
+ end
39
+ end
40
+
41
+ context 'without combined experiments' do
42
+ let!(:combined_experiments) { nil }
43
+
44
+ it "raises an error" do
45
+ expect(lambda { ab_combined_test :combined_exp_1 }).to raise_error(Split::InvalidExperimentsFormatError )
46
+ end
47
+ end
48
+
49
+ it "uses same alternative for all sub experiments and returns the alternative" do
50
+ allow(self).to receive(:get_alternative) { "test-alt" }
51
+ expect(self).to receive(:ab_test).with(:exp_1_click, {"control"=>0.5}, {"test-alt"=>0.5}) { "test-alt" }
52
+ expect(self).to receive(:ab_test).with(:exp_1_scroll, [{"control" => 0, "test-alt" => 1}])
53
+
54
+ expect(ab_combined_test('combined_exp_1')).to eq('test-alt')
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+ require 'split/dashboard/pagination_helpers'
3
+
4
+ describe Split::DashboardPaginationHelpers do
5
+ include Split::DashboardPaginationHelpers
6
+
7
+ let(:url) { '/split/' }
8
+
9
+ describe '#pagination_per' do
10
+ context 'when params empty' do
11
+ let(:params) { Hash[] }
12
+
13
+ it 'returns 10' do
14
+ expect(pagination_per).to eql 10
15
+ end
16
+ end
17
+
18
+ context 'when params[:per] is 5' do
19
+ let(:params) { Hash[per: 5] }
20
+
21
+ it 'returns 5' do
22
+ expect(pagination_per).to eql 5
23
+ end
24
+ end
25
+ end
26
+
27
+ describe '#page_number' do
28
+ context 'when params empty' do
29
+ let(:params) { Hash[] }
30
+
31
+ it 'returns 1' do
32
+ expect(page_number).to eql 1
33
+ end
34
+ end
35
+
36
+ context 'when params[:page] is "2"' do
37
+ let(:params) { Hash[page: '2'] }
38
+
39
+ it 'returns 2' do
40
+ expect(page_number).to eql 2
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#paginated' do
46
+ let(:collection) { (1..20).to_a }
47
+ let(:params) { Hash[per: '5', page: '3'] }
48
+
49
+ it { expect(paginated(collection)).to eql [11, 12, 13, 14, 15] }
50
+ end
51
+
52
+ describe '#show_first_page_tag?' do
53
+ context 'when page is 1' do
54
+ it { expect(show_first_page_tag?).to be false }
55
+ end
56
+
57
+ context 'when page is 3' do
58
+ let(:params) { Hash[page: '3'] }
59
+ it { expect(show_first_page_tag?).to be true }
60
+ end
61
+ end
62
+
63
+ describe '#first_page_tag' do
64
+ it { expect(first_page_tag).to eql '<a href="/split?page=1&per=10">1</a>' }
65
+ end
66
+
67
+ describe '#show_first_ellipsis_tag?' do
68
+ context 'when page is 1' do
69
+ it { expect(show_first_ellipsis_tag?).to be false }
70
+ end
71
+
72
+ context 'when page is 4' do
73
+ let(:params) { Hash[page: '4'] }
74
+ it { expect(show_first_ellipsis_tag?).to be true }
75
+ end
76
+ end
77
+
78
+ describe '#ellipsis_tag' do
79
+ it { expect(ellipsis_tag).to eql '<span>...</span>' }
80
+ end
81
+
82
+ describe '#show_prev_page_tag?' do
83
+ context 'when page is 1' do
84
+ it { expect(show_prev_page_tag?).to be false }
85
+ end
86
+
87
+ context 'when page is 2' do
88
+ let(:params) { Hash[page: '2'] }
89
+ it { expect(show_prev_page_tag?).to be true }
90
+ end
91
+ end
92
+
93
+ describe '#prev_page_tag' do
94
+ context 'when page is 2' do
95
+ let(:params) { Hash[page: '2'] }
96
+
97
+ it do
98
+ expect(prev_page_tag).to eql '<a href="/split?page=1&per=10">1</a>'
99
+ end
100
+ end
101
+
102
+ context 'when page is 3' do
103
+ let(:params) { Hash[page: '3'] }
104
+
105
+ it do
106
+ expect(prev_page_tag).to eql '<a href="/split?page=2&per=10">2</a>'
107
+ end
108
+ end
109
+ end
110
+
111
+ describe '#show_prev_page_tag?' do
112
+ context 'when page is 1' do
113
+ it { expect(show_prev_page_tag?).to be false }
114
+ end
115
+
116
+ context 'when page is 2' do
117
+ let(:params) { Hash[page: '2'] }
118
+ it { expect(show_prev_page_tag?).to be true }
119
+ end
120
+ end
121
+
122
+ describe '#current_page_tag' do
123
+ context 'when page is 1' do
124
+ let(:params) { Hash[page: '1'] }
125
+ it { expect(current_page_tag).to eql '<span><b>1</b></span>' }
126
+ end
127
+
128
+ context 'when page is 2' do
129
+ let(:params) { Hash[page: '2'] }
130
+ it { expect(current_page_tag).to eql '<span><b>2</b></span>' }
131
+ end
132
+ end
133
+
134
+ describe '#show_next_page_tag?' do
135
+ context 'when page is 2' do
136
+ let(:params) { Hash[page: '2'] }
137
+
138
+ context 'when collection length is 20' do
139
+ let(:collection) { (1..20).to_a }
140
+ it { expect(show_next_page_tag?(collection)).to be false }
141
+ end
142
+
143
+ context 'when collection length is 25' do
144
+ let(:collection) { (1..25).to_a }
145
+ it { expect(show_next_page_tag?(collection)).to be true }
146
+ end
147
+ end
148
+ end
149
+
150
+ describe '#next_page_tag' do
151
+ context 'when page is 1' do
152
+ let(:params) { Hash[page: '1'] }
153
+ it { expect(next_page_tag).to eql '<a href="/split?page=2&per=10">2</a>' }
154
+ end
155
+
156
+ context 'when page is 2' do
157
+ let(:params) { Hash[page: '2'] }
158
+ it { expect(next_page_tag).to eql '<a href="/split?page=3&per=10">3</a>' }
159
+ end
160
+ end
161
+
162
+ describe '#total_pages' do
163
+ context 'when collection length is 30' do
164
+ let(:collection) { (1..30).to_a }
165
+ it { expect(total_pages(collection)).to eql 3 }
166
+ end
167
+
168
+ context 'when collection length is 35' do
169
+ let(:collection) { (1..35).to_a }
170
+ it { expect(total_pages(collection)).to eql 4 }
171
+ end
172
+ end
173
+
174
+ describe '#show_last_ellipsis_tag?' do
175
+ let(:collection) { (1..30).to_a }
176
+ let(:params) { Hash[per: '5', page: '2'] }
177
+ it { expect(show_last_ellipsis_tag?(collection)).to be true }
178
+ end
179
+
180
+ describe '#show_last_page_tag?' do
181
+ let(:collection) { (1..30).to_a }
182
+
183
+ context 'when page is 5/6' do
184
+ let(:params) { Hash[per: '5', page: '5'] }
185
+ it { expect(show_last_page_tag?(collection)).to be false }
186
+ end
187
+
188
+ context 'when page is 4/6' do
189
+ let(:params) { Hash[per: '5', page: '4'] }
190
+ it { expect(show_last_page_tag?(collection)).to be true }
191
+ end
192
+ end
193
+
194
+ describe '#last_page_tag' do
195
+ let(:collection) { (1..30).to_a }
196
+ it { expect(last_page_tag(collection)).to eql '<a href="/split?page=3&per=10">3</a>' }
197
+ end
198
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+ require 'split/dashboard/paginator'
4
+
5
+ describe Split::DashboardPaginator do
6
+ context 'when collection is 1..20' do
7
+ let(:collection) { (1..20).to_a }
8
+
9
+ context 'when per 5 for page' do
10
+ let(:per) { 5 }
11
+
12
+ it 'when page number is 1 result is [1, 2, 3, 4, 5]' do
13
+ result = Split::DashboardPaginator.new(collection, 1, per).paginate
14
+ expect(result).to eql [1, 2, 3, 4, 5]
15
+ end
16
+
17
+ it 'when page number is 2 result is [6, 7, 8, 9, 10]' do
18
+ result = Split::DashboardPaginator.new(collection, 2, per).paginate
19
+ expect(result).to eql [6, 7, 8, 9, 10]
20
+ end
21
+ end
22
+
23
+ context 'when per 10 for page' do
24
+ let(:per) { 10 }
25
+
26
+ it 'when page number is 1 result is [1..10]' do
27
+ result = Split::DashboardPaginator.new(collection, 1, per).paginate
28
+ expect(result).to eql [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
29
+ end
30
+
31
+ it 'when page number is 2 result is [10..20]' do
32
+ result = Split::DashboardPaginator.new(collection, 2, per).paginate
33
+ expect(result).to eql [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -458,7 +458,7 @@ describe Split::Experiment do
458
458
  expect(experiment.alternatives[0].p_winner).to be_within(0.04).of(0.50)
459
459
  end
460
460
 
461
- it "should calculate the probability of being the winning alternative separately for each goal" do
461
+ it "should calculate the probability of being the winning alternative separately for each goal", :skip => true do
462
462
  experiment = Split::ExperimentCatalog.find_or_create({'link_color3' => ["purchase", "refund"]}, 'blue', 'red', 'green')
463
463
  goal1 = experiment.goals[0]
464
464
  goal2 = experiment.goals[1]