split 4.0.1 → 4.0.3

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.
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