split 4.0.1 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +8 -3
  3. data/.rubocop.yml +2 -5
  4. data/CHANGELOG.md +38 -0
  5. data/CONTRIBUTING.md +1 -1
  6. data/Gemfile +1 -1
  7. data/README.md +11 -3
  8. data/Rakefile +4 -5
  9. data/gemfiles/5.2.gemfile +1 -3
  10. data/gemfiles/6.0.gemfile +1 -3
  11. data/gemfiles/6.1.gemfile +1 -3
  12. data/gemfiles/7.0.gemfile +1 -3
  13. data/lib/split/algorithms/block_randomization.rb +5 -6
  14. data/lib/split/algorithms/whiplash.rb +16 -18
  15. data/lib/split/algorithms.rb +14 -0
  16. data/lib/split/alternative.rb +21 -22
  17. data/lib/split/cache.rb +0 -1
  18. data/lib/split/combined_experiments_helper.rb +4 -4
  19. data/lib/split/configuration.rb +83 -84
  20. data/lib/split/dashboard/helpers.rb +6 -7
  21. data/lib/split/dashboard/pagination_helpers.rb +53 -54
  22. data/lib/split/dashboard/public/style.css +5 -2
  23. data/lib/split/dashboard/views/_experiment.erb +2 -1
  24. data/lib/split/dashboard/views/index.erb +19 -4
  25. data/lib/split/dashboard.rb +29 -23
  26. data/lib/split/encapsulated_helper.rb +4 -6
  27. data/lib/split/experiment.rb +93 -88
  28. data/lib/split/experiment_catalog.rb +6 -5
  29. data/lib/split/extensions/string.rb +1 -1
  30. data/lib/split/goals_collection.rb +8 -10
  31. data/lib/split/helper.rb +20 -20
  32. data/lib/split/metric.rb +4 -5
  33. data/lib/split/persistence/cookie_adapter.rb +44 -47
  34. data/lib/split/persistence/dual_adapter.rb +7 -8
  35. data/lib/split/persistence/redis_adapter.rb +3 -4
  36. data/lib/split/persistence/session_adapter.rb +0 -2
  37. data/lib/split/persistence.rb +4 -4
  38. data/lib/split/redis_interface.rb +7 -1
  39. data/lib/split/trial.rb +23 -24
  40. data/lib/split/user.rb +12 -13
  41. data/lib/split/version.rb +1 -1
  42. data/lib/split/zscore.rb +1 -3
  43. data/lib/split.rb +26 -25
  44. data/spec/algorithms/block_randomization_spec.rb +6 -5
  45. data/spec/algorithms/weighted_sample_spec.rb +6 -5
  46. data/spec/algorithms/whiplash_spec.rb +4 -5
  47. data/spec/alternative_spec.rb +35 -36
  48. data/spec/cache_spec.rb +15 -19
  49. data/spec/combined_experiments_helper_spec.rb +18 -17
  50. data/spec/configuration_spec.rb +32 -38
  51. data/spec/dashboard/pagination_helpers_spec.rb +69 -67
  52. data/spec/dashboard/paginator_spec.rb +10 -9
  53. data/spec/dashboard_helpers_spec.rb +19 -18
  54. data/spec/dashboard_spec.rb +79 -35
  55. data/spec/encapsulated_helper_spec.rb +12 -14
  56. data/spec/experiment_catalog_spec.rb +14 -13
  57. data/spec/experiment_spec.rb +132 -123
  58. data/spec/goals_collection_spec.rb +17 -15
  59. data/spec/helper_spec.rb +415 -382
  60. data/spec/metric_spec.rb +14 -14
  61. data/spec/persistence/cookie_adapter_spec.rb +23 -8
  62. data/spec/persistence/dual_adapter_spec.rb +71 -71
  63. data/spec/persistence/redis_adapter_spec.rb +28 -29
  64. data/spec/persistence/session_adapter_spec.rb +2 -3
  65. data/spec/persistence_spec.rb +1 -2
  66. data/spec/redis_interface_spec.rb +26 -14
  67. data/spec/spec_helper.rb +16 -13
  68. data/spec/split_spec.rb +11 -11
  69. data/spec/support/cookies_mock.rb +1 -2
  70. data/spec/trial_spec.rb +61 -60
  71. data/spec/user_spec.rb +36 -36
  72. data/split.gemspec +21 -20
  73. metadata +25 -14
  74. data/.rubocop_todo.yml +0 -226
  75. data/Appraisals +0 -19
  76. data/gemfiles/5.0.gemfile +0 -9
  77. data/gemfiles/5.1.gemfile +0 -9
@@ -1,108 +1,110 @@
1
- require 'spec_helper'
2
- require 'split/dashboard/pagination_helpers'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "split/dashboard/pagination_helpers"
3
5
 
4
6
  describe Split::DashboardPaginationHelpers do
5
7
  include Split::DashboardPaginationHelpers
6
8
 
7
- let(:url) { '/split/' }
9
+ let(:url) { "/split/" }
8
10
 
9
- describe '#pagination_per' do
10
- context 'when params empty' do
11
+ describe "#pagination_per" do
12
+ context "when params empty" do
11
13
  let(:params) { Hash[] }
12
14
 
13
- it 'returns the default (10)' do
15
+ it "returns the default (10)" do
14
16
  default_per_page = Split.configuration.dashboard_pagination_default_per_page
15
17
  expect(pagination_per).to eql default_per_page
16
18
  expect(pagination_per).to eql 10
17
19
  end
18
20
  end
19
21
 
20
- context 'when params[:per] is 5' do
22
+ context "when params[:per] is 5" do
21
23
  let(:params) { Hash[per: 5] }
22
24
 
23
- it 'returns 5' do
25
+ it "returns 5" do
24
26
  expect(pagination_per).to eql 5
25
27
  end
26
28
  end
27
29
  end
28
30
 
29
- describe '#page_number' do
30
- context 'when params empty' do
31
+ describe "#page_number" do
32
+ context "when params empty" do
31
33
  let(:params) { Hash[] }
32
34
 
33
- it 'returns 1' do
35
+ it "returns 1" do
34
36
  expect(page_number).to eql 1
35
37
  end
36
38
  end
37
39
 
38
40
  context 'when params[:page] is "2"' do
39
- let(:params) { Hash[page: '2'] }
41
+ let(:params) { Hash[page: "2"] }
40
42
 
41
- it 'returns 2' do
43
+ it "returns 2" do
42
44
  expect(page_number).to eql 2
43
45
  end
44
46
  end
45
47
  end
46
48
 
47
- describe '#paginated' do
49
+ describe "#paginated" do
48
50
  let(:collection) { (1..20).to_a }
49
- let(:params) { Hash[per: '5', page: '3'] }
51
+ let(:params) { Hash[per: "5", page: "3"] }
50
52
 
51
53
  it { expect(paginated(collection)).to eql [11, 12, 13, 14, 15] }
52
54
  end
53
55
 
54
- describe '#show_first_page_tag?' do
55
- context 'when page is 1' do
56
+ describe "#show_first_page_tag?" do
57
+ context "when page is 1" do
56
58
  it { expect(show_first_page_tag?).to be false }
57
59
  end
58
60
 
59
- context 'when page is 3' do
60
- let(:params) { Hash[page: '3'] }
61
+ context "when page is 3" do
62
+ let(:params) { Hash[page: "3"] }
61
63
  it { expect(show_first_page_tag?).to be true }
62
64
  end
63
65
  end
64
66
 
65
- describe '#first_page_tag' do
67
+ describe "#first_page_tag" do
66
68
  it { expect(first_page_tag).to eql '<a href="/split?page=1&per=10">1</a>' }
67
69
  end
68
70
 
69
- describe '#show_first_ellipsis_tag?' do
70
- context 'when page is 1' do
71
+ describe "#show_first_ellipsis_tag?" do
72
+ context "when page is 1" do
71
73
  it { expect(show_first_ellipsis_tag?).to be false }
72
74
  end
73
75
 
74
- context 'when page is 4' do
75
- let(:params) { Hash[page: '4'] }
76
+ context "when page is 4" do
77
+ let(:params) { Hash[page: "4"] }
76
78
  it { expect(show_first_ellipsis_tag?).to be true }
77
79
  end
78
80
  end
79
81
 
80
- describe '#ellipsis_tag' do
81
- it { expect(ellipsis_tag).to eql '<span>...</span>' }
82
+ describe "#ellipsis_tag" do
83
+ it { expect(ellipsis_tag).to eql "<span>...</span>" }
82
84
  end
83
85
 
84
- describe '#show_prev_page_tag?' do
85
- context 'when page is 1' do
86
+ describe "#show_prev_page_tag?" do
87
+ context "when page is 1" do
86
88
  it { expect(show_prev_page_tag?).to be false }
87
89
  end
88
90
 
89
- context 'when page is 2' do
90
- let(:params) { Hash[page: '2'] }
91
+ context "when page is 2" do
92
+ let(:params) { Hash[page: "2"] }
91
93
  it { expect(show_prev_page_tag?).to be true }
92
94
  end
93
95
  end
94
96
 
95
- describe '#prev_page_tag' do
96
- context 'when page is 2' do
97
- let(:params) { Hash[page: '2'] }
97
+ describe "#prev_page_tag" do
98
+ context "when page is 2" do
99
+ let(:params) { Hash[page: "2"] }
98
100
 
99
101
  it do
100
102
  expect(prev_page_tag).to eql '<a href="/split?page=1&per=10">1</a>'
101
103
  end
102
104
  end
103
105
 
104
- context 'when page is 3' do
105
- let(:params) { Hash[page: '3'] }
106
+ context "when page is 3" do
107
+ let(:params) { Hash[page: "3"] }
106
108
 
107
109
  it do
108
110
  expect(prev_page_tag).to eql '<a href="/split?page=2&per=10">2</a>'
@@ -110,90 +112,90 @@ describe Split::DashboardPaginationHelpers do
110
112
  end
111
113
  end
112
114
 
113
- describe '#show_prev_page_tag?' do
114
- context 'when page is 1' do
115
+ describe "#show_prev_page_tag?" do
116
+ context "when page is 1" do
115
117
  it { expect(show_prev_page_tag?).to be false }
116
118
  end
117
119
 
118
- context 'when page is 2' do
119
- let(:params) { Hash[page: '2'] }
120
+ context "when page is 2" do
121
+ let(:params) { Hash[page: "2"] }
120
122
  it { expect(show_prev_page_tag?).to be true }
121
123
  end
122
124
  end
123
125
 
124
- describe '#current_page_tag' do
125
- context 'when page is 1' do
126
- let(:params) { Hash[page: '1'] }
127
- it { expect(current_page_tag).to eql '<span><b>1</b></span>' }
126
+ describe "#current_page_tag" do
127
+ context "when page is 1" do
128
+ let(:params) { Hash[page: "1"] }
129
+ it { expect(current_page_tag).to eql "<span><b>1</b></span>" }
128
130
  end
129
131
 
130
- context 'when page is 2' do
131
- let(:params) { Hash[page: '2'] }
132
- it { expect(current_page_tag).to eql '<span><b>2</b></span>' }
132
+ context "when page is 2" do
133
+ let(:params) { Hash[page: "2"] }
134
+ it { expect(current_page_tag).to eql "<span><b>2</b></span>" }
133
135
  end
134
136
  end
135
137
 
136
- describe '#show_next_page_tag?' do
137
- context 'when page is 2' do
138
- let(:params) { Hash[page: '2'] }
138
+ describe "#show_next_page_tag?" do
139
+ context "when page is 2" do
140
+ let(:params) { Hash[page: "2"] }
139
141
 
140
- context 'when collection length is 20' do
142
+ context "when collection length is 20" do
141
143
  let(:collection) { (1..20).to_a }
142
144
  it { expect(show_next_page_tag?(collection)).to be false }
143
145
  end
144
146
 
145
- context 'when collection length is 25' do
147
+ context "when collection length is 25" do
146
148
  let(:collection) { (1..25).to_a }
147
149
  it { expect(show_next_page_tag?(collection)).to be true }
148
150
  end
149
151
  end
150
152
  end
151
153
 
152
- describe '#next_page_tag' do
153
- context 'when page is 1' do
154
- let(:params) { Hash[page: '1'] }
154
+ describe "#next_page_tag" do
155
+ context "when page is 1" do
156
+ let(:params) { Hash[page: "1"] }
155
157
  it { expect(next_page_tag).to eql '<a href="/split?page=2&per=10">2</a>' }
156
158
  end
157
159
 
158
- context 'when page is 2' do
159
- let(:params) { Hash[page: '2'] }
160
+ context "when page is 2" do
161
+ let(:params) { Hash[page: "2"] }
160
162
  it { expect(next_page_tag).to eql '<a href="/split?page=3&per=10">3</a>' }
161
163
  end
162
164
  end
163
165
 
164
- describe '#total_pages' do
165
- context 'when collection length is 30' do
166
+ describe "#total_pages" do
167
+ context "when collection length is 30" do
166
168
  let(:collection) { (1..30).to_a }
167
169
  it { expect(total_pages(collection)).to eql 3 }
168
170
  end
169
171
 
170
- context 'when collection length is 35' do
172
+ context "when collection length is 35" do
171
173
  let(:collection) { (1..35).to_a }
172
174
  it { expect(total_pages(collection)).to eql 4 }
173
175
  end
174
176
  end
175
177
 
176
- describe '#show_last_ellipsis_tag?' do
178
+ describe "#show_last_ellipsis_tag?" do
177
179
  let(:collection) { (1..30).to_a }
178
- let(:params) { Hash[per: '5', page: '2'] }
180
+ let(:params) { Hash[per: "5", page: "2"] }
179
181
  it { expect(show_last_ellipsis_tag?(collection)).to be true }
180
182
  end
181
183
 
182
- describe '#show_last_page_tag?' do
184
+ describe "#show_last_page_tag?" do
183
185
  let(:collection) { (1..30).to_a }
184
186
 
185
- context 'when page is 5/6' do
186
- let(:params) { Hash[per: '5', page: '5'] }
187
+ context "when page is 5/6" do
188
+ let(:params) { Hash[per: "5", page: "5"] }
187
189
  it { expect(show_last_page_tag?(collection)).to be false }
188
190
  end
189
191
 
190
- context 'when page is 4/6' do
191
- let(:params) { Hash[per: '5', page: '4'] }
192
+ context "when page is 4/6" do
193
+ let(:params) { Hash[per: "5", page: "4"] }
192
194
  it { expect(show_last_page_tag?(collection)).to be true }
193
195
  end
194
196
  end
195
197
 
196
- describe '#last_page_tag' do
198
+ describe "#last_page_tag" do
197
199
  let(:collection) { (1..30).to_a }
198
200
  it { expect(last_page_tag(collection)).to eql '<a href="/split?page=3&per=10">3</a>' }
199
201
  end
@@ -1,34 +1,35 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
- require 'split/dashboard/paginator'
2
+
3
+ require "spec_helper"
4
+ require "split/dashboard/paginator"
4
5
 
5
6
  describe Split::DashboardPaginator do
6
- context 'when collection is 1..20' do
7
+ context "when collection is 1..20" do
7
8
  let(:collection) { (1..20).to_a }
8
9
 
9
- context 'when per 5 for page' do
10
+ context "when per 5 for page" do
10
11
  let(:per) { 5 }
11
12
 
12
- it 'when page number is 1 result is [1, 2, 3, 4, 5]' do
13
+ it "when page number is 1 result is [1, 2, 3, 4, 5]" do
13
14
  result = Split::DashboardPaginator.new(collection, 1, per).paginate
14
15
  expect(result).to eql [1, 2, 3, 4, 5]
15
16
  end
16
17
 
17
- it 'when page number is 2 result is [6, 7, 8, 9, 10]' do
18
+ it "when page number is 2 result is [6, 7, 8, 9, 10]" do
18
19
  result = Split::DashboardPaginator.new(collection, 2, per).paginate
19
20
  expect(result).to eql [6, 7, 8, 9, 10]
20
21
  end
21
22
  end
22
23
 
23
- context 'when per 10 for page' do
24
+ context "when per 10 for page" do
24
25
  let(:per) { 10 }
25
26
 
26
- it 'when page number is 1 result is [1..10]' do
27
+ it "when page number is 1 result is [1..10]" do
27
28
  result = Split::DashboardPaginator.new(collection, 1, per).paginate
28
29
  expect(result).to eql [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
29
30
  end
30
31
 
31
- it 'when page number is 2 result is [10..20]' do
32
+ it "when page number is 2 result is [10..20]" do
32
33
  result = Split::DashboardPaginator.new(collection, 2, per).paginate
33
34
  expect(result).to eql [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
34
35
  end
@@ -1,41 +1,42 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
- require 'split/dashboard/helpers'
2
+
3
+ require "spec_helper"
4
+ require "split/dashboard/helpers"
4
5
 
5
6
  include Split::DashboardHelpers
6
7
 
7
8
  describe Split::DashboardHelpers do
8
- describe 'confidence_level' do
9
- it 'should handle very small numbers' do
10
- expect(confidence_level(Complex(2e-18, -0.03))).to eq('Insufficient confidence')
9
+ describe "confidence_level" do
10
+ it "should handle very small numbers" do
11
+ expect(confidence_level(Complex(2e-18, -0.03))).to eq("Insufficient confidence")
11
12
  end
12
13
 
13
14
  it "should consider a z-score of 1.65 <= z < 1.96 as 90% confident" do
14
- expect(confidence_level(1.65)).to eq('90% confidence')
15
- expect(confidence_level(1.80)).to eq('90% confidence')
15
+ expect(confidence_level(1.65)).to eq("90% confidence")
16
+ expect(confidence_level(1.80)).to eq("90% confidence")
16
17
  end
17
18
 
18
19
  it "should consider a z-score of 1.96 <= z < 2.58 as 95% confident" do
19
- expect(confidence_level(1.96)).to eq('95% confidence')
20
- expect(confidence_level(2.00)).to eq('95% confidence')
20
+ expect(confidence_level(1.96)).to eq("95% confidence")
21
+ expect(confidence_level(2.00)).to eq("95% confidence")
21
22
  end
22
23
 
23
24
  it "should consider a z-score of z >= 2.58 as 99% confident" do
24
- expect(confidence_level(2.58)).to eq('99% confidence')
25
- expect(confidence_level(3.00)).to eq('99% confidence')
25
+ expect(confidence_level(2.58)).to eq("99% confidence")
26
+ expect(confidence_level(3.00)).to eq("99% confidence")
26
27
  end
27
28
 
28
- describe '#round' do
29
- it 'can round number strings' do
30
- expect(round('3.1415')).to eq BigDecimal('3.14')
29
+ describe "#round" do
30
+ it "can round number strings" do
31
+ expect(round("3.1415")).to eq BigDecimal("3.14")
31
32
  end
32
33
 
33
- it 'can round number strings for precsion' do
34
- expect(round('3.1415', 1)).to eq BigDecimal('3.1')
34
+ it "can round number strings for precsion" do
35
+ expect(round("3.1415", 1)).to eq BigDecimal("3.1")
35
36
  end
36
37
 
37
- it 'can handle invalid number strings' do
38
- expect(round('N/A')).to be_zero
38
+ it "can handle invalid number strings" do
39
+ expect(round("N/A")).to be_zero
39
40
  end
40
41
  end
41
42
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
- require 'rack/test'
4
- require 'split/dashboard'
2
+
3
+ require "spec_helper"
4
+ require "rack/test"
5
+ require "split/dashboard"
5
6
 
6
7
  describe Split::Dashboard do
7
8
  include Rack::Test::Methods
@@ -9,8 +10,8 @@ describe Split::Dashboard do
9
10
  class TestDashboard < Split::Dashboard
10
11
  include Split::Helper
11
12
 
12
- get '/my_experiment' do
13
- ab_test(params[:experiment], 'blue', 'red')
13
+ get "/my_experiment" do
14
+ ab_test(params[:experiment], "blue", "red")
14
15
  end
15
16
  end
16
17
 
@@ -27,11 +28,11 @@ describe Split::Dashboard do
27
28
  }
28
29
 
29
30
  let(:experiment_with_goals) {
30
- Split::ExperimentCatalog.find_or_create({"link_color" => ["goal_1", "goal_2"]}, "blue", "red")
31
+ Split::ExperimentCatalog.find_or_create({ "link_color" => ["goal_1", "goal_2"] }, "blue", "red")
31
32
  }
32
33
 
33
34
  let(:metric) {
34
- Split::Metric.find_or_create(name: 'testmetric', experiments: [experiment, experiment_with_goals])
35
+ Split::Metric.find_or_create(name: "testmetric", experiments: [experiment, experiment_with_goals])
35
36
  }
36
37
 
37
38
  let(:red_link) { link("red") }
@@ -42,7 +43,7 @@ describe Split::Dashboard do
42
43
  end
43
44
 
44
45
  it "should respond to /" do
45
- get '/'
46
+ get "/"
46
47
  expect(last_response).to be_ok
47
48
  end
48
49
 
@@ -54,33 +55,33 @@ describe Split::Dashboard do
54
55
  context "experiment without goals" do
55
56
  it "should display a Start button" do
56
57
  experiment
57
- get '/'
58
- expect(last_response.body).to include('Start')
58
+ get "/"
59
+ expect(last_response.body).to include("Start")
59
60
 
60
61
  post "/start?experiment=#{experiment.name}"
61
- get '/'
62
- expect(last_response.body).to include('Reset Data')
63
- expect(last_response.body).not_to include('Metrics:')
62
+ get "/"
63
+ expect(last_response.body).to include("Reset Data")
64
+ expect(last_response.body).not_to include("Metrics:")
64
65
  end
65
66
  end
66
67
 
67
68
  context "experiment with metrics" do
68
69
  it "should display the names of associated metrics" do
69
70
  metric
70
- get '/'
71
- expect(last_response.body).to include('Metrics:testmetric')
71
+ get "/"
72
+ expect(last_response.body).to include("Metrics:testmetric")
72
73
  end
73
74
  end
74
75
 
75
76
  context "with goals" do
76
77
  it "should display a Start button" do
77
78
  experiment_with_goals
78
- get '/'
79
- expect(last_response.body).to include('Start')
79
+ get "/"
80
+ expect(last_response.body).to include("Start")
80
81
 
81
82
  post "/start?experiment=#{experiment.name}"
82
- get '/'
83
- expect(last_response.body).to include('Reset Data')
83
+ get "/"
84
+ expect(last_response.body).to include("Reset Data")
84
85
  end
85
86
  end
86
87
  end
@@ -88,7 +89,7 @@ describe Split::Dashboard do
88
89
  describe "force alternative" do
89
90
  context "initial version" do
90
91
  let!(:user) do
91
- Split::User.new(@app, { experiment.name => 'red' })
92
+ Split::User.new(@app, { experiment.name => "red" })
92
93
  end
93
94
 
94
95
  before do
@@ -115,7 +116,7 @@ describe Split::Dashboard do
115
116
  context "incremented version" do
116
117
  let!(:user) do
117
118
  experiment.increment_version
118
- Split::User.new(@app, { "#{experiment.name}:#{experiment.version}" => 'red' })
119
+ Split::User.new(@app, { "#{experiment.name}:#{experiment.version}" => "red" })
119
120
  end
120
121
 
121
122
  before do
@@ -134,28 +135,28 @@ describe Split::Dashboard do
134
135
 
135
136
  describe "index page" do
136
137
  context "with winner" do
137
- before { experiment.winner = 'red' }
138
+ before { experiment.winner = "red" }
138
139
 
139
140
  it "displays `Reopen Experiment` button" do
140
- get '/'
141
+ get "/"
141
142
 
142
- expect(last_response.body).to include('Reopen Experiment')
143
+ expect(last_response.body).to include("Reopen Experiment")
143
144
  end
144
145
  end
145
146
 
146
147
  context "without winner" do
147
148
  it "should not display `Reopen Experiment` button" do
148
- get '/'
149
+ get "/"
149
150
 
150
- expect(last_response.body).to_not include('Reopen Experiment')
151
+ expect(last_response.body).to_not include("Reopen Experiment")
151
152
  end
152
153
  end
153
154
  end
154
155
 
155
156
  describe "reopen experiment" do
156
- before { experiment.winner = 'red' }
157
+ before { experiment.winner = "red" }
157
158
 
158
- it 'redirects' do
159
+ it "redirects" do
159
160
  post "/reopen?experiment=#{experiment.name}"
160
161
 
161
162
  expect(last_response).to be_redirect
@@ -170,7 +171,7 @@ describe Split::Dashboard do
170
171
  it "keeps existing stats" do
171
172
  red_link.participant_count = 5
172
173
  blue_link.participant_count = 7
173
- experiment.winner = 'blue'
174
+ experiment.winner = "blue"
174
175
 
175
176
  post "/reopen?experiment=#{experiment.name}"
176
177
 
@@ -201,10 +202,41 @@ describe Split::Dashboard do
201
202
  end
202
203
  end
203
204
 
205
+ describe "initialize experiment" do
206
+ before do
207
+ Split.configuration.experiments = {
208
+ my_experiment: {
209
+ alternatives: [ "control", "alternative" ],
210
+ }
211
+ }
212
+ end
213
+
214
+ it "initializes the experiment when the experiment is given" do
215
+ expect(Split::ExperimentCatalog.find("my_experiment")).to be nil
216
+
217
+ post "/initialize_experiment", { experiment: "my_experiment" }
218
+
219
+ experiment = Split::ExperimentCatalog.find("my_experiment")
220
+ expect(experiment).to be_a(Split::Experiment)
221
+ end
222
+
223
+ it "does not attempt to intialize the experiment when empty experiment is given" do
224
+ post "/initialize_experiment", { experiment: "" }
225
+
226
+ expect(Split::ExperimentCatalog).to_not receive(:find_or_create)
227
+ end
228
+
229
+ it "does not attempt to intialize the experiment when no experiment is given" do
230
+ post "/initialize_experiment"
231
+
232
+ expect(Split::ExperimentCatalog).to_not receive(:find_or_create)
233
+ end
234
+ end
235
+
204
236
  it "should reset an experiment" do
205
237
  red_link.participant_count = 5
206
238
  blue_link.participant_count = 7
207
- experiment.winner = 'blue'
239
+ experiment.winner = "blue"
208
240
 
209
241
  post "/reset?experiment=#{experiment.name}"
210
242
 
@@ -226,16 +258,16 @@ describe Split::Dashboard do
226
258
 
227
259
  it "should mark an alternative as the winner" do
228
260
  expect(experiment.winner).to be_nil
229
- post "/experiment?experiment=#{experiment.name}", :alternative => 'red'
261
+ post "/experiment?experiment=#{experiment.name}", alternative: "red"
230
262
 
231
263
  expect(last_response).to be_redirect
232
- expect(experiment.winner.name).to eq('red')
264
+ expect(experiment.winner.name).to eq("red")
233
265
  end
234
266
 
235
267
  it "should display the start date" do
236
268
  experiment.start
237
269
 
238
- get '/'
270
+ get "/"
239
271
 
240
272
  expect(last_response.body).to include("<small>#{experiment.start_time.strftime('%Y-%m-%d')}</small>")
241
273
  end
@@ -243,8 +275,20 @@ describe Split::Dashboard do
243
275
  it "should handle experiments without a start date" do
244
276
  Split.redis.hdel(:experiment_start_times, experiment.name)
245
277
 
246
- get '/'
278
+ get "/"
279
+
280
+ expect(last_response.body).to include("<small>Unknown</small>")
281
+ end
282
+
283
+ it "should be explode with experiments with invalid data" do
284
+ red_link.participant_count = 1
285
+ red_link.set_completed_count(10)
286
+
287
+ blue_link.participant_count = 3
288
+ blue_link.set_completed_count(2)
247
289
 
248
- expect(last_response.body).to include('<small>Unknown</small>')
290
+ get "/"
291
+
292
+ expect(last_response).to be_ok
249
293
  end
250
294
  end