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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +8 -3
- data/.rubocop.yml +2 -5
- data/CHANGELOG.md +38 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -1
- data/README.md +11 -3
- data/Rakefile +4 -5
- data/gemfiles/5.2.gemfile +1 -3
- data/gemfiles/6.0.gemfile +1 -3
- data/gemfiles/6.1.gemfile +1 -3
- data/gemfiles/7.0.gemfile +1 -3
- data/lib/split/algorithms/block_randomization.rb +5 -6
- data/lib/split/algorithms/whiplash.rb +16 -18
- data/lib/split/algorithms.rb +14 -0
- data/lib/split/alternative.rb +21 -22
- data/lib/split/cache.rb +0 -1
- data/lib/split/combined_experiments_helper.rb +4 -4
- data/lib/split/configuration.rb +83 -84
- data/lib/split/dashboard/helpers.rb +6 -7
- data/lib/split/dashboard/pagination_helpers.rb +53 -54
- data/lib/split/dashboard/public/style.css +5 -2
- data/lib/split/dashboard/views/_experiment.erb +2 -1
- data/lib/split/dashboard/views/index.erb +19 -4
- data/lib/split/dashboard.rb +29 -23
- data/lib/split/encapsulated_helper.rb +4 -6
- data/lib/split/experiment.rb +93 -88
- data/lib/split/experiment_catalog.rb +6 -5
- data/lib/split/extensions/string.rb +1 -1
- data/lib/split/goals_collection.rb +8 -10
- data/lib/split/helper.rb +20 -20
- data/lib/split/metric.rb +4 -5
- data/lib/split/persistence/cookie_adapter.rb +44 -47
- data/lib/split/persistence/dual_adapter.rb +7 -8
- data/lib/split/persistence/redis_adapter.rb +3 -4
- data/lib/split/persistence/session_adapter.rb +0 -2
- data/lib/split/persistence.rb +4 -4
- data/lib/split/redis_interface.rb +7 -1
- data/lib/split/trial.rb +23 -24
- data/lib/split/user.rb +12 -13
- data/lib/split/version.rb +1 -1
- data/lib/split/zscore.rb +1 -3
- data/lib/split.rb +26 -25
- data/spec/algorithms/block_randomization_spec.rb +6 -5
- data/spec/algorithms/weighted_sample_spec.rb +6 -5
- data/spec/algorithms/whiplash_spec.rb +4 -5
- data/spec/alternative_spec.rb +35 -36
- data/spec/cache_spec.rb +15 -19
- data/spec/combined_experiments_helper_spec.rb +18 -17
- data/spec/configuration_spec.rb +32 -38
- data/spec/dashboard/pagination_helpers_spec.rb +69 -67
- data/spec/dashboard/paginator_spec.rb +10 -9
- data/spec/dashboard_helpers_spec.rb +19 -18
- data/spec/dashboard_spec.rb +79 -35
- data/spec/encapsulated_helper_spec.rb +12 -14
- data/spec/experiment_catalog_spec.rb +14 -13
- data/spec/experiment_spec.rb +132 -123
- data/spec/goals_collection_spec.rb +17 -15
- data/spec/helper_spec.rb +415 -382
- data/spec/metric_spec.rb +14 -14
- data/spec/persistence/cookie_adapter_spec.rb +23 -8
- data/spec/persistence/dual_adapter_spec.rb +71 -71
- data/spec/persistence/redis_adapter_spec.rb +28 -29
- data/spec/persistence/session_adapter_spec.rb +2 -3
- data/spec/persistence_spec.rb +1 -2
- data/spec/redis_interface_spec.rb +26 -14
- data/spec/spec_helper.rb +16 -13
- data/spec/split_spec.rb +11 -11
- data/spec/support/cookies_mock.rb +1 -2
- data/spec/trial_spec.rb +61 -60
- data/spec/user_spec.rb +36 -36
- data/split.gemspec +21 -20
- metadata +25 -14
- data/.rubocop_todo.yml +0 -226
- data/Appraisals +0 -19
- data/gemfiles/5.0.gemfile +0 -9
- data/gemfiles/5.1.gemfile +0 -9
@@ -1,108 +1,110 @@
|
|
1
|
-
|
2
|
-
|
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) {
|
9
|
+
let(:url) { "/split/" }
|
8
10
|
|
9
|
-
describe
|
10
|
-
context
|
11
|
+
describe "#pagination_per" do
|
12
|
+
context "when params empty" do
|
11
13
|
let(:params) { Hash[] }
|
12
14
|
|
13
|
-
it
|
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
|
22
|
+
context "when params[:per] is 5" do
|
21
23
|
let(:params) { Hash[per: 5] }
|
22
24
|
|
23
|
-
it
|
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
|
30
|
-
context
|
31
|
+
describe "#page_number" do
|
32
|
+
context "when params empty" do
|
31
33
|
let(:params) { Hash[] }
|
32
34
|
|
33
|
-
it
|
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:
|
41
|
+
let(:params) { Hash[page: "2"] }
|
40
42
|
|
41
|
-
it
|
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
|
49
|
+
describe "#paginated" do
|
48
50
|
let(:collection) { (1..20).to_a }
|
49
|
-
let(:params) { Hash[per:
|
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
|
55
|
-
context
|
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
|
60
|
-
let(:params) { Hash[page:
|
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
|
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
|
70
|
-
context
|
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
|
75
|
-
let(:params) { Hash[page:
|
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
|
81
|
-
it { expect(ellipsis_tag).to eql
|
82
|
+
describe "#ellipsis_tag" do
|
83
|
+
it { expect(ellipsis_tag).to eql "<span>...</span>" }
|
82
84
|
end
|
83
85
|
|
84
|
-
describe
|
85
|
-
context
|
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
|
90
|
-
let(:params) { Hash[page:
|
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
|
96
|
-
context
|
97
|
-
let(:params) { Hash[page:
|
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
|
105
|
-
let(:params) { Hash[page:
|
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
|
114
|
-
context
|
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
|
119
|
-
let(:params) { Hash[page:
|
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
|
125
|
-
context
|
126
|
-
let(:params) { Hash[page:
|
127
|
-
it { expect(current_page_tag).to eql
|
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
|
131
|
-
let(:params) { Hash[page:
|
132
|
-
it { expect(current_page_tag).to eql
|
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
|
137
|
-
context
|
138
|
-
let(:params) { Hash[page:
|
138
|
+
describe "#show_next_page_tag?" do
|
139
|
+
context "when page is 2" do
|
140
|
+
let(:params) { Hash[page: "2"] }
|
139
141
|
|
140
|
-
context
|
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
|
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
|
153
|
-
context
|
154
|
-
let(:params) { Hash[page:
|
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
|
159
|
-
let(:params) { Hash[page:
|
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
|
165
|
-
context
|
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
|
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
|
178
|
+
describe "#show_last_ellipsis_tag?" do
|
177
179
|
let(:collection) { (1..30).to_a }
|
178
|
-
let(:params) { Hash[per:
|
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
|
184
|
+
describe "#show_last_page_tag?" do
|
183
185
|
let(:collection) { (1..30).to_a }
|
184
186
|
|
185
|
-
context
|
186
|
-
let(:params) { Hash[per:
|
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
|
191
|
-
let(:params) { Hash[per:
|
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
|
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
|
-
|
3
|
-
require
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "split/dashboard/paginator"
|
4
5
|
|
5
6
|
describe Split::DashboardPaginator do
|
6
|
-
context
|
7
|
+
context "when collection is 1..20" do
|
7
8
|
let(:collection) { (1..20).to_a }
|
8
9
|
|
9
|
-
context
|
10
|
+
context "when per 5 for page" do
|
10
11
|
let(:per) { 5 }
|
11
12
|
|
12
|
-
it
|
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
|
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
|
24
|
+
context "when per 10 for page" do
|
24
25
|
let(:per) { 10 }
|
25
26
|
|
26
|
-
it
|
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
|
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
|
-
|
3
|
-
require
|
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
|
9
|
-
it
|
10
|
-
expect(confidence_level(Complex(2e-18, -0.03))).to eq(
|
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(
|
15
|
-
expect(confidence_level(1.80)).to eq(
|
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(
|
20
|
-
expect(confidence_level(2.00)).to eq(
|
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(
|
25
|
-
expect(confidence_level(3.00)).to eq(
|
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
|
29
|
-
it
|
30
|
-
expect(round(
|
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
|
34
|
-
expect(round(
|
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
|
38
|
-
expect(round(
|
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
|
data/spec/dashboard_spec.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
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
|
13
|
-
ab_test(params[:experiment],
|
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:
|
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(
|
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(
|
63
|
-
expect(last_response.body).not_to include(
|
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(
|
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(
|
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(
|
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 =>
|
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}" =>
|
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 =
|
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(
|
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(
|
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 =
|
157
|
+
before { experiment.winner = "red" }
|
157
158
|
|
158
|
-
it
|
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 =
|
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 =
|
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}", :
|
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(
|
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
|
-
|
290
|
+
get "/"
|
291
|
+
|
292
|
+
expect(last_response).to be_ok
|
249
293
|
end
|
250
294
|
end
|