split 3.3.2 → 4.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc +1 -1
  3. data/.github/FUNDING.yml +1 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +24 -0
  5. data/.github/dependabot.yml +7 -0
  6. data/.github/workflows/ci.yml +63 -0
  7. data/.rspec +1 -0
  8. data/.rubocop.yml +67 -1043
  9. data/CHANGELOG.md +121 -0
  10. data/CODE_OF_CONDUCT.md +3 -3
  11. data/CONTRIBUTING.md +1 -1
  12. data/Gemfile +6 -1
  13. data/README.md +51 -21
  14. data/Rakefile +6 -5
  15. data/lib/split/algorithms/block_randomization.rb +7 -6
  16. data/lib/split/algorithms/weighted_sample.rb +2 -1
  17. data/lib/split/algorithms/whiplash.rb +17 -18
  18. data/lib/split/algorithms.rb +14 -0
  19. data/lib/split/alternative.rb +25 -25
  20. data/lib/split/cache.rb +27 -0
  21. data/lib/split/combined_experiments_helper.rb +5 -4
  22. data/lib/split/configuration.rb +94 -96
  23. data/lib/split/dashboard/helpers.rb +7 -7
  24. data/lib/split/dashboard/pagination_helpers.rb +56 -57
  25. data/lib/split/dashboard/paginator.rb +1 -0
  26. data/lib/split/dashboard/public/dashboard.js +10 -0
  27. data/lib/split/dashboard/public/style.css +10 -2
  28. data/lib/split/dashboard/views/_controls.erb +13 -0
  29. data/lib/split/dashboard/views/_experiment.erb +2 -1
  30. data/lib/split/dashboard/views/index.erb +19 -4
  31. data/lib/split/dashboard/views/layout.erb +1 -1
  32. data/lib/split/dashboard.rb +46 -21
  33. data/lib/split/encapsulated_helper.rb +15 -8
  34. data/lib/split/engine.rb +7 -4
  35. data/lib/split/exceptions.rb +1 -0
  36. data/lib/split/experiment.rb +160 -122
  37. data/lib/split/experiment_catalog.rb +7 -8
  38. data/lib/split/extensions/string.rb +2 -1
  39. data/lib/split/goals_collection.rb +10 -10
  40. data/lib/split/helper.rb +52 -24
  41. data/lib/split/metric.rb +6 -6
  42. data/lib/split/persistence/cookie_adapter.rb +47 -44
  43. data/lib/split/persistence/dual_adapter.rb +53 -12
  44. data/lib/split/persistence/redis_adapter.rb +8 -4
  45. data/lib/split/persistence/session_adapter.rb +1 -2
  46. data/lib/split/persistence.rb +8 -6
  47. data/lib/split/redis_interface.rb +16 -29
  48. data/lib/split/trial.rb +44 -35
  49. data/lib/split/user.rb +30 -15
  50. data/lib/split/version.rb +2 -4
  51. data/lib/split/zscore.rb +2 -3
  52. data/lib/split.rb +35 -28
  53. data/spec/algorithms/block_randomization_spec.rb +6 -5
  54. data/spec/algorithms/weighted_sample_spec.rb +6 -5
  55. data/spec/algorithms/whiplash_spec.rb +4 -5
  56. data/spec/alternative_spec.rb +35 -36
  57. data/spec/cache_spec.rb +84 -0
  58. data/spec/combined_experiments_helper_spec.rb +18 -17
  59. data/spec/configuration_spec.rb +41 -45
  60. data/spec/dashboard/pagination_helpers_spec.rb +71 -67
  61. data/spec/dashboard/paginator_spec.rb +10 -9
  62. data/spec/dashboard_helpers_spec.rb +19 -18
  63. data/spec/dashboard_spec.rb +153 -48
  64. data/spec/encapsulated_helper_spec.rb +47 -23
  65. data/spec/experiment_catalog_spec.rb +14 -13
  66. data/spec/experiment_spec.rb +224 -111
  67. data/spec/goals_collection_spec.rb +18 -16
  68. data/spec/helper_spec.rb +531 -424
  69. data/spec/metric_spec.rb +14 -14
  70. data/spec/persistence/cookie_adapter_spec.rb +26 -11
  71. data/spec/persistence/dual_adapter_spec.rb +158 -66
  72. data/spec/persistence/redis_adapter_spec.rb +35 -27
  73. data/spec/persistence/session_adapter_spec.rb +2 -3
  74. data/spec/persistence_spec.rb +1 -2
  75. data/spec/redis_interface_spec.rb +25 -82
  76. data/spec/spec_helper.rb +38 -24
  77. data/spec/split_spec.rb +11 -11
  78. data/spec/support/cookies_mock.rb +1 -2
  79. data/spec/trial_spec.rb +102 -75
  80. data/spec/user_spec.rb +69 -27
  81. data/split.gemspec +26 -23
  82. metadata +68 -42
  83. data/.travis.yml +0 -66
  84. data/Appraisals +0 -19
  85. data/gemfiles/4.2.gemfile +0 -9
  86. data/gemfiles/5.0.gemfile +0 -9
  87. data/gemfiles/5.1.gemfile +0 -9
  88. data/gemfiles/5.2.gemfile +0 -9
  89. data/gemfiles/6.0.gemfile +0 -9
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Split::Cache do
6
+ let(:namespace) { :test_namespace }
7
+ let(:key) { :test_key }
8
+ let(:now) { 1606189017 }
9
+
10
+ before { allow(Time).to receive(:now).and_return(now) }
11
+
12
+ describe "clear" do
13
+ before { Split.configuration.cache = true }
14
+
15
+ it "clears the cache" do
16
+ expect(Time).to receive(:now).and_return(now).exactly(2).times
17
+ Split::Cache.fetch(namespace, key) { Time.now }
18
+ Split::Cache.clear
19
+ Split::Cache.fetch(namespace, key) { Time.now }
20
+ end
21
+ end
22
+
23
+ describe "clear_key" do
24
+ before { Split.configuration.cache = true }
25
+
26
+ it "clears the cache" do
27
+ expect(Time).to receive(:now).and_return(now).exactly(3).times
28
+ Split::Cache.fetch(namespace, :key1) { Time.now }
29
+ Split::Cache.fetch(namespace, :key2) { Time.now }
30
+ Split::Cache.clear_key(:key1)
31
+
32
+ Split::Cache.fetch(namespace, :key1) { Time.now }
33
+ Split::Cache.fetch(namespace, :key2) { Time.now }
34
+ end
35
+ end
36
+
37
+ describe "fetch" do
38
+ subject { Split::Cache.fetch(namespace, key) { Time.now } }
39
+
40
+ context "when cache disabled" do
41
+ before { Split.configuration.cache = false }
42
+
43
+ it "returns the yield" do
44
+ expect(subject).to eql(now)
45
+ end
46
+
47
+ it "yields every time" do
48
+ expect(Time).to receive(:now).and_return(now).exactly(2).times
49
+ Split::Cache.fetch(namespace, key) { Time.now }
50
+ Split::Cache.fetch(namespace, key) { Time.now }
51
+ end
52
+ end
53
+
54
+ context "when cache enabled" do
55
+ before { Split.configuration.cache = true }
56
+
57
+ it "returns the yield" do
58
+ expect(subject).to eql(now)
59
+ end
60
+
61
+ it "yields once" do
62
+ expect(Time).to receive(:now).and_return(now).once
63
+ Split::Cache.fetch(namespace, key) { Time.now }
64
+ Split::Cache.fetch(namespace, key) { Time.now }
65
+ end
66
+
67
+ it "honors namespace" do
68
+ expect(Split::Cache.fetch(:a, key) { :a }).to eql(:a)
69
+ expect(Split::Cache.fetch(:b, key) { :b }).to eql(:b)
70
+
71
+ expect(Split::Cache.fetch(:a, key) { :a }).to eql(:a)
72
+ expect(Split::Cache.fetch(:b, key) { :b }).to eql(:b)
73
+ end
74
+
75
+ it "honors key" do
76
+ expect(Split::Cache.fetch(namespace, :a) { :a }).to eql(:a)
77
+ expect(Split::Cache.fetch(namespace, :b) { :b }).to eql(:b)
78
+
79
+ expect(Split::Cache.fetch(namespace, :a) { :a }).to eql(:a)
80
+ expect(Split::Cache.fetch(namespace, :b) { :b }).to eql(:b)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,57 +1,58 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
- require 'split/combined_experiments_helper'
2
+
3
+ require "spec_helper"
4
+ require "split/combined_experiments_helper"
4
5
 
5
6
  describe Split::CombinedExperimentsHelper do
6
7
  include Split::CombinedExperimentsHelper
7
8
 
8
- describe 'ab_combined_test' do
9
+ describe "ab_combined_test" do
9
10
  let!(:config_enabled) { true }
10
- let!(:combined_experiments) { [:exp_1_click, :exp_1_scroll ]}
11
+ let!(:combined_experiments) { [:exp_1_click, :exp_1_scroll ] }
11
12
  let!(:allow_multiple_experiments) { true }
12
13
 
13
14
  before do
14
15
  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
16
+ combined_exp_1: {
17
+ alternatives: [ { "control"=> 0.5 }, { "test-alt"=> 0.5 } ],
18
+ metric: :my_metric,
19
+ combined_experiments: combined_experiments
19
20
  }
20
21
  }
21
22
  Split.configuration.enabled = config_enabled
22
23
  Split.configuration.allow_multiple_experiments = allow_multiple_experiments
23
24
  end
24
25
 
25
- context 'without config enabled' do
26
+ context "without config enabled" do
26
27
  let!(:config_enabled) { false }
27
28
 
28
29
  it "raises an error" do
29
- expect(lambda { ab_combined_test :combined_exp_1 }).to raise_error(Split::InvalidExperimentsFormatError )
30
+ expect { ab_combined_test :combined_exp_1 }.to raise_error(Split::InvalidExperimentsFormatError)
30
31
  end
31
32
  end
32
33
 
33
- context 'multiple experiments disabled' do
34
+ context "multiple experiments disabled" do
34
35
  let!(:allow_multiple_experiments) { false }
35
36
 
36
37
  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
+ expect { ab_combined_test :combined_exp_1 }.to raise_error(Split::InvalidExperimentsFormatError)
38
39
  end
39
40
  end
40
41
 
41
- context 'without combined experiments' do
42
+ context "without combined experiments" do
42
43
  let!(:combined_experiments) { nil }
43
44
 
44
45
  it "raises an error" do
45
- expect(lambda { ab_combined_test :combined_exp_1 }).to raise_error(Split::InvalidExperimentsFormatError )
46
+ expect { ab_combined_test :combined_exp_1 }.to raise_error(Split::InvalidExperimentsFormatError)
46
47
  end
47
48
  end
48
49
 
49
50
  it "uses same alternative for all sub experiments and returns the alternative" do
50
51
  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}])
52
+ expect(self).to receive(:ab_test).with(:exp_1_click, { "control"=>0.5 }, { "test-alt"=>0.5 }) { "test-alt" }
53
+ expect(self).to receive(:ab_test).with(:exp_1_scroll, [{ "control" => 0, "test-alt" => 1 }])
53
54
 
54
- expect(ab_combined_test('combined_exp_1')).to eq('test-alt')
55
+ expect(ab_combined_test("combined_exp_1")).to eq("test-alt")
55
56
  end
56
57
  end
57
58
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
2
 
4
- describe Split::Configuration do
3
+ require "spec_helper"
5
4
 
5
+ describe Split::Configuration do
6
6
  before(:each) { @config = Split::Configuration.new }
7
7
 
8
8
  it "should provide a default value for ignore_ip_addresses" do
@@ -58,17 +58,15 @@ describe Split::Configuration do
58
58
  end
59
59
 
60
60
  it "should load a metric" do
61
- @config.experiments = {:my_experiment=>
62
- {:alternatives=>["control_opt", "other_opt"], :metric=>:my_metric}}
61
+ @config.experiments = { my_experiment: { alternatives: ["control_opt", "other_opt"], metric: :my_metric } }
63
62
 
64
63
  expect(@config.metrics).not_to be_nil
65
64
  expect(@config.metrics.keys).to eq([:my_metric])
66
65
  end
67
66
 
68
67
  it "should allow loading of experiment using experment_for" do
69
- @config.experiments = {:my_experiment=>
70
- {:alternatives=>["control_opt", "other_opt"], :metric=>:my_metric}}
71
- expect(@config.experiment_for(:my_experiment)).to eq({:alternatives=>["control_opt", ["other_opt"]]})
68
+ @config.experiments = { my_experiment: { alternatives: ["control_opt", "other_opt"], metric: :my_metric } }
69
+ expect(@config.experiment_for(:my_experiment)).to eq({ alternatives: ["control_opt", ["other_opt"]] })
72
70
  end
73
71
 
74
72
  context "when experiments are defined via YAML" do
@@ -82,12 +80,12 @@ describe Split::Configuration do
82
80
  - Alt One
83
81
  - Alt Two
84
82
  resettable: false
85
- eos
83
+ eos
86
84
  @config.experiments = YAML.load(experiments_yaml)
87
85
  end
88
86
 
89
- it 'should normalize experiments' do
90
- expect(@config.normalized_experiments).to eq({:my_experiment=>{:resettable=>false,:alternatives=>["Control Opt", ["Alt One", "Alt Two"]]}})
87
+ it "should normalize experiments" do
88
+ expect(@config.normalized_experiments).to eq({ my_experiment: { resettable: false, alternatives: ["Control Opt", ["Alt One", "Alt Two"]] } })
91
89
  end
92
90
  end
93
91
 
@@ -110,14 +108,14 @@ describe Split::Configuration do
110
108
  Alt Two:
111
109
  text: 'Alternative Two'
112
110
  resettable: false
113
- eos
111
+ eos
114
112
  @config.experiments = YAML.load(experiments_yaml)
115
113
  end
116
114
 
117
- it 'should have metadata on the experiment' do
115
+ it "should have metadata on the experiment" do
118
116
  meta = @config.normalized_experiments[:my_experiment][:metadata]
119
117
  expect(meta).to_not be nil
120
- expect(meta['Control Opt']['text']).to eq('Control Option')
118
+ expect(meta["Control Opt"]["text"]).to eq("Control Option")
121
119
  end
122
120
  end
123
121
 
@@ -138,25 +136,23 @@ describe Split::Configuration do
138
136
  alternatives:
139
137
  - a
140
138
  - b
141
- eos
139
+ eos
142
140
  @config.experiments = YAML.load(experiments_yaml)
143
141
  end
144
142
 
145
143
  it "should normalize experiments" do
146
- expect(@config.normalized_experiments).to eq({:my_experiment=>{:resettable=>false,:alternatives=>[{"Control Opt"=>0.67},
147
- [{"Alt One"=>0.1}, {"Alt Two"=>0.23}]]}, :another_experiment=>{:alternatives=>["a", ["b"]]}})
144
+ expect(@config.normalized_experiments).to eq({ my_experiment: { resettable: false, alternatives: [{ "Control Opt"=>0.67 },
145
+ [{ "Alt One"=>0.1 }, { "Alt Two"=>0.23 }]] }, another_experiment: { alternatives: ["a", ["b"]] } })
148
146
  end
149
147
 
150
148
  it "should recognize metrics" do
151
149
  expect(@config.metrics).not_to be_nil
152
150
  expect(@config.metrics.keys).to eq([:my_metric])
153
151
  end
154
-
155
152
  end
156
153
  end
157
154
 
158
155
  context "as symbols" do
159
-
160
156
  context "with valid YAML" do
161
157
  before do
162
158
  experiments_yaml = <<-eos
@@ -166,21 +162,20 @@ describe Split::Configuration do
166
162
  - Alt One
167
163
  - Alt Two
168
164
  :resettable: false
169
- eos
165
+ eos
170
166
  @config.experiments = YAML.load(experiments_yaml)
171
167
  end
172
168
 
173
169
  it "should normalize experiments" do
174
- expect(@config.normalized_experiments).to eq({:my_experiment=>{:resettable=>false,:alternatives=>["Control Opt", ["Alt One", "Alt Two"]]}})
170
+ expect(@config.normalized_experiments).to eq({ my_experiment: { resettable: false, alternatives: ["Control Opt", ["Alt One", "Alt Two"]] } })
175
171
  end
176
172
  end
177
173
 
178
174
  context "with invalid YAML" do
179
-
180
175
  let(:yaml) { YAML.load(input) }
181
176
 
182
177
  context "with an empty string" do
183
- let(:input) { '' }
178
+ let(:input) { "" }
184
179
 
185
180
  it "should raise an error" do
186
181
  expect { @config.experiments = yaml }.to raise_error(Split::InvalidExperimentsFormatError)
@@ -188,7 +183,7 @@ describe Split::Configuration do
188
183
  end
189
184
 
190
185
  context "with just the YAML header" do
191
- let(:input) { '---' }
186
+ let(:input) { "---" }
192
187
 
193
188
  it "should raise an error" do
194
189
  expect { @config.experiments = yaml }.to raise_error(Split::InvalidExperimentsFormatError)
@@ -200,35 +195,24 @@ describe Split::Configuration do
200
195
 
201
196
  it "should normalize experiments" do
202
197
  @config.experiments = {
203
- :my_experiment => {
204
- :alternatives => [
205
- { :name => "control_opt", :percent => 67 },
206
- { :name => "second_opt", :percent => 10 },
207
- { :name => "third_opt", :percent => 23 },
198
+ my_experiment: {
199
+ alternatives: [
200
+ { name: "control_opt", percent: 67 },
201
+ { name: "second_opt", percent: 10 },
202
+ { name: "third_opt", percent: 23 },
208
203
  ],
209
204
  }
210
205
  }
211
206
 
212
- expect(@config.normalized_experiments).to eq({:my_experiment=>{:alternatives=>[{"control_opt"=>0.67}, [{"second_opt"=>0.1}, {"third_opt"=>0.23}]]}})
213
- end
214
-
215
- context 'redis_url configuration [DEPRECATED]' do
216
- it 'should warn on set and assign to #redis' do
217
- expect(@config).to receive(:warn).with(/\[DEPRECATED\]/) { nil }
218
- @config.redis_url = 'example_url'
219
- expect(@config.redis).to eq('example_url')
220
- end
221
-
222
- it 'should warn on get and return #redis' do
223
- expect(@config).to receive(:warn).with(/\[DEPRECATED\]/) { nil }
224
- @config.redis = 'example_url'
225
- expect(@config.redis_url).to eq('example_url')
226
- end
207
+ expect(@config.normalized_experiments).to eq({ my_experiment: { alternatives: [{ "control_opt"=>0.67 }, [{ "second_opt"=>0.1 }, { "third_opt"=>0.23 }]] } })
227
208
  end
228
209
 
229
210
  context "redis configuration" do
230
211
  it "should default to local redis server" do
231
- expect(@config.redis).to eq("redis://localhost:6379")
212
+ old_redis_url = ENV["REDIS_URL"]
213
+ ENV.delete("REDIS_URL")
214
+ expect(Split::Configuration.new.redis).to eq("redis://localhost:6379")
215
+ ENV["REDIS_URL"] = old_redis_url
232
216
  end
233
217
 
234
218
  it "should allow for redis url to be configured" do
@@ -238,8 +222,10 @@ describe Split::Configuration do
238
222
 
239
223
  context "provided REDIS_URL environment variable" do
240
224
  it "should use the ENV variable" do
241
- ENV['REDIS_URL'] = "env_redis_url"
225
+ old_redis_url = ENV["REDIS_URL"]
226
+ ENV["REDIS_URL"] = "env_redis_url"
242
227
  expect(Split::Configuration.new.redis).to eq("env_redis_url")
228
+ ENV["REDIS_URL"] = old_redis_url
243
229
  end
244
230
  end
245
231
  end
@@ -255,4 +241,14 @@ describe Split::Configuration do
255
241
  end
256
242
  end
257
243
 
244
+ context "persistence cookie domain" do
245
+ it "should default to nil" do
246
+ expect(@config.persistence_cookie_domain).to eq(nil)
247
+ end
248
+
249
+ it "should allow the persistence cookie domain to be configured" do
250
+ @config.persistence_cookie_domain = ".acme.com"
251
+ expect(@config.persistence_cookie_domain).to eq(".acme.com")
252
+ end
253
+ end
258
254
  end
@@ -1,106 +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 10' do
15
+ it "returns the default (10)" do
16
+ default_per_page = Split.configuration.dashboard_pagination_default_per_page
17
+ expect(pagination_per).to eql default_per_page
14
18
  expect(pagination_per).to eql 10
15
19
  end
16
20
  end
17
21
 
18
- context 'when params[:per] is 5' do
22
+ context "when params[:per] is 5" do
19
23
  let(:params) { Hash[per: 5] }
20
24
 
21
- it 'returns 5' do
25
+ it "returns 5" do
22
26
  expect(pagination_per).to eql 5
23
27
  end
24
28
  end
25
29
  end
26
30
 
27
- describe '#page_number' do
28
- context 'when params empty' do
31
+ describe "#page_number" do
32
+ context "when params empty" do
29
33
  let(:params) { Hash[] }
30
34
 
31
- it 'returns 1' do
35
+ it "returns 1" do
32
36
  expect(page_number).to eql 1
33
37
  end
34
38
  end
35
39
 
36
40
  context 'when params[:page] is "2"' do
37
- let(:params) { Hash[page: '2'] }
41
+ let(:params) { Hash[page: "2"] }
38
42
 
39
- it 'returns 2' do
43
+ it "returns 2" do
40
44
  expect(page_number).to eql 2
41
45
  end
42
46
  end
43
47
  end
44
48
 
45
- describe '#paginated' do
49
+ describe "#paginated" do
46
50
  let(:collection) { (1..20).to_a }
47
- let(:params) { Hash[per: '5', page: '3'] }
51
+ let(:params) { Hash[per: "5", page: "3"] }
48
52
 
49
53
  it { expect(paginated(collection)).to eql [11, 12, 13, 14, 15] }
50
54
  end
51
55
 
52
- describe '#show_first_page_tag?' do
53
- context 'when page is 1' do
56
+ describe "#show_first_page_tag?" do
57
+ context "when page is 1" do
54
58
  it { expect(show_first_page_tag?).to be false }
55
59
  end
56
60
 
57
- context 'when page is 3' do
58
- let(:params) { Hash[page: '3'] }
61
+ context "when page is 3" do
62
+ let(:params) { Hash[page: "3"] }
59
63
  it { expect(show_first_page_tag?).to be true }
60
64
  end
61
65
  end
62
66
 
63
- describe '#first_page_tag' do
67
+ describe "#first_page_tag" do
64
68
  it { expect(first_page_tag).to eql '<a href="/split?page=1&per=10">1</a>' }
65
69
  end
66
70
 
67
- describe '#show_first_ellipsis_tag?' do
68
- context 'when page is 1' do
71
+ describe "#show_first_ellipsis_tag?" do
72
+ context "when page is 1" do
69
73
  it { expect(show_first_ellipsis_tag?).to be false }
70
74
  end
71
75
 
72
- context 'when page is 4' do
73
- let(:params) { Hash[page: '4'] }
76
+ context "when page is 4" do
77
+ let(:params) { Hash[page: "4"] }
74
78
  it { expect(show_first_ellipsis_tag?).to be true }
75
79
  end
76
80
  end
77
81
 
78
- describe '#ellipsis_tag' do
79
- it { expect(ellipsis_tag).to eql '<span>...</span>' }
82
+ describe "#ellipsis_tag" do
83
+ it { expect(ellipsis_tag).to eql "<span>...</span>" }
80
84
  end
81
85
 
82
- describe '#show_prev_page_tag?' do
83
- context 'when page is 1' do
86
+ describe "#show_prev_page_tag?" do
87
+ context "when page is 1" do
84
88
  it { expect(show_prev_page_tag?).to be false }
85
89
  end
86
90
 
87
- context 'when page is 2' do
88
- let(:params) { Hash[page: '2'] }
91
+ context "when page is 2" do
92
+ let(:params) { Hash[page: "2"] }
89
93
  it { expect(show_prev_page_tag?).to be true }
90
94
  end
91
95
  end
92
96
 
93
- describe '#prev_page_tag' do
94
- context 'when page is 2' do
95
- let(:params) { Hash[page: '2'] }
97
+ describe "#prev_page_tag" do
98
+ context "when page is 2" do
99
+ let(:params) { Hash[page: "2"] }
96
100
 
97
101
  it do
98
102
  expect(prev_page_tag).to eql '<a href="/split?page=1&per=10">1</a>'
99
103
  end
100
104
  end
101
105
 
102
- context 'when page is 3' do
103
- let(:params) { Hash[page: '3'] }
106
+ context "when page is 3" do
107
+ let(:params) { Hash[page: "3"] }
104
108
 
105
109
  it do
106
110
  expect(prev_page_tag).to eql '<a href="/split?page=2&per=10">2</a>'
@@ -108,90 +112,90 @@ describe Split::DashboardPaginationHelpers do
108
112
  end
109
113
  end
110
114
 
111
- describe '#show_prev_page_tag?' do
112
- context 'when page is 1' do
115
+ describe "#show_prev_page_tag?" do
116
+ context "when page is 1" do
113
117
  it { expect(show_prev_page_tag?).to be false }
114
118
  end
115
119
 
116
- context 'when page is 2' do
117
- let(:params) { Hash[page: '2'] }
120
+ context "when page is 2" do
121
+ let(:params) { Hash[page: "2"] }
118
122
  it { expect(show_prev_page_tag?).to be true }
119
123
  end
120
124
  end
121
125
 
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
+ 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>" }
126
130
  end
127
131
 
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>' }
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>" }
131
135
  end
132
136
  end
133
137
 
134
- describe '#show_next_page_tag?' do
135
- context 'when page is 2' do
136
- 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"] }
137
141
 
138
- context 'when collection length is 20' do
142
+ context "when collection length is 20" do
139
143
  let(:collection) { (1..20).to_a }
140
144
  it { expect(show_next_page_tag?(collection)).to be false }
141
145
  end
142
146
 
143
- context 'when collection length is 25' do
147
+ context "when collection length is 25" do
144
148
  let(:collection) { (1..25).to_a }
145
149
  it { expect(show_next_page_tag?(collection)).to be true }
146
150
  end
147
151
  end
148
152
  end
149
153
 
150
- describe '#next_page_tag' do
151
- context 'when page is 1' do
152
- let(:params) { Hash[page: '1'] }
154
+ describe "#next_page_tag" do
155
+ context "when page is 1" do
156
+ let(:params) { Hash[page: "1"] }
153
157
  it { expect(next_page_tag).to eql '<a href="/split?page=2&per=10">2</a>' }
154
158
  end
155
159
 
156
- context 'when page is 2' do
157
- let(:params) { Hash[page: '2'] }
160
+ context "when page is 2" do
161
+ let(:params) { Hash[page: "2"] }
158
162
  it { expect(next_page_tag).to eql '<a href="/split?page=3&per=10">3</a>' }
159
163
  end
160
164
  end
161
165
 
162
- describe '#total_pages' do
163
- context 'when collection length is 30' do
166
+ describe "#total_pages" do
167
+ context "when collection length is 30" do
164
168
  let(:collection) { (1..30).to_a }
165
169
  it { expect(total_pages(collection)).to eql 3 }
166
170
  end
167
171
 
168
- context 'when collection length is 35' do
172
+ context "when collection length is 35" do
169
173
  let(:collection) { (1..35).to_a }
170
174
  it { expect(total_pages(collection)).to eql 4 }
171
175
  end
172
176
  end
173
177
 
174
- describe '#show_last_ellipsis_tag?' do
178
+ describe "#show_last_ellipsis_tag?" do
175
179
  let(:collection) { (1..30).to_a }
176
- let(:params) { Hash[per: '5', page: '2'] }
180
+ let(:params) { Hash[per: "5", page: "2"] }
177
181
  it { expect(show_last_ellipsis_tag?(collection)).to be true }
178
182
  end
179
183
 
180
- describe '#show_last_page_tag?' do
184
+ describe "#show_last_page_tag?" do
181
185
  let(:collection) { (1..30).to_a }
182
186
 
183
- context 'when page is 5/6' do
184
- let(:params) { Hash[per: '5', page: '5'] }
187
+ context "when page is 5/6" do
188
+ let(:params) { Hash[per: "5", page: "5"] }
185
189
  it { expect(show_last_page_tag?(collection)).to be false }
186
190
  end
187
191
 
188
- context 'when page is 4/6' do
189
- let(:params) { Hash[per: '5', page: '4'] }
192
+ context "when page is 4/6" do
193
+ let(:params) { Hash[per: "5", page: "4"] }
190
194
  it { expect(show_last_page_tag?(collection)).to be true }
191
195
  end
192
196
  end
193
197
 
194
- describe '#last_page_tag' do
198
+ describe "#last_page_tag" do
195
199
  let(:collection) { (1..30).to_a }
196
200
  it { expect(last_page_tag(collection)).to eql '<a href="/split?page=3&per=10">3</a>' }
197
201
  end