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
data/spec/metric_spec.rb CHANGED
@@ -1,31 +1,31 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
3
- require 'split/metric'
2
+
3
+ require "spec_helper"
4
+ require "split/metric"
4
5
 
5
6
  describe Split::Metric do
6
- describe 'possible experiments' do
7
+ describe "possible experiments" do
7
8
  it "should load the experiment if there is one, but no metric" do
8
- experiment = Split::ExperimentCatalog.find_or_create('color', 'red', 'blue')
9
- expect(Split::Metric.possible_experiments('color')).to eq([experiment])
9
+ experiment = Split::ExperimentCatalog.find_or_create("color", "red", "blue")
10
+ expect(Split::Metric.possible_experiments("color")).to eq([experiment])
10
11
  end
11
12
 
12
13
  it "should load the experiments in a metric" do
13
- experiment1 = Split::ExperimentCatalog.find_or_create('color', 'red', 'blue')
14
- experiment2 = Split::ExperimentCatalog.find_or_create('size', 'big', 'small')
14
+ experiment1 = Split::ExperimentCatalog.find_or_create("color", "red", "blue")
15
+ experiment2 = Split::ExperimentCatalog.find_or_create("size", "big", "small")
15
16
 
16
- metric = Split::Metric.new(:name => 'purchase', :experiments => [experiment1, experiment2])
17
+ metric = Split::Metric.new(name: "purchase", experiments: [experiment1, experiment2])
17
18
  metric.save
18
- expect(Split::Metric.possible_experiments('purchase')).to include(experiment1, experiment2)
19
+ expect(Split::Metric.possible_experiments("purchase")).to include(experiment1, experiment2)
19
20
  end
20
21
 
21
22
  it "should load both the metric experiments and an experiment with the same name" do
22
- experiment1 = Split::ExperimentCatalog.find_or_create('purchase', 'red', 'blue')
23
- experiment2 = Split::ExperimentCatalog.find_or_create('size', 'big', 'small')
23
+ experiment1 = Split::ExperimentCatalog.find_or_create("purchase", "red", "blue")
24
+ experiment2 = Split::ExperimentCatalog.find_or_create("size", "big", "small")
24
25
 
25
- metric = Split::Metric.new(:name => 'purchase', :experiments => [experiment2])
26
+ metric = Split::Metric.new(name: "purchase", experiments: [experiment2])
26
27
  metric.save
27
- expect(Split::Metric.possible_experiments('purchase')).to include(experiment1, experiment2)
28
+ expect(Split::Metric.possible_experiments("purchase")).to include(experiment1, experiment2)
28
29
  end
29
30
  end
30
-
31
31
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "spec_helper"
3
- require 'rack/test'
4
+ require "rack/test"
4
5
 
5
6
  describe Split::Persistence::CookieAdapter do
6
7
  subject { described_class.new(context) }
@@ -13,10 +14,24 @@ describe Split::Persistence::CookieAdapter do
13
14
  end
14
15
 
15
16
  it "handles invalid JSON" do
16
- context.request.cookies[:split] = {
17
- :value => '{"foo":2,',
18
- :expires => Time.now
19
- }
17
+ context.request.cookies["split"] = "{\"foo\":2,"
18
+
19
+ expect(subject["my_key"]).to be_nil
20
+ subject["my_key"] = "my_value"
21
+ expect(subject["my_key"]).to eq("my_value")
22
+ end
23
+
24
+ it "ignores valid JSON of invalid type (integer)" do
25
+ context.request.cookies["split"] = "2"
26
+
27
+ expect(subject["my_key"]).to be_nil
28
+ subject["my_key"] = "my_value"
29
+ expect(subject["my_key"]).to eq("my_value")
30
+ end
31
+
32
+ it "ignores valid JSON of invalid type (array)" do
33
+ context.request.cookies["split"] = "[\"foo\", \"bar\"]"
34
+
20
35
  expect(subject["my_key"]).to be_nil
21
36
  subject["my_key"] = "my_value"
22
37
  expect(subject["my_key"]).to eq("my_value")
@@ -56,7 +71,7 @@ describe Split::Persistence::CookieAdapter do
56
71
  end
57
72
 
58
73
  it "ensure other added cookies are not overriden" do
59
- context.response.set_cookie 'dummy', 'wow'
74
+ context.response.set_cookie "dummy", "wow"
60
75
  subject["foo"] = "FOO"
61
76
  expect(context.response.headers["Set-Cookie"]).to include("dummy=wow")
62
77
  expect(context.response.headers["Set-Cookie"]).to include("split=")
@@ -77,7 +92,7 @@ describe Split::Persistence::CookieAdapter do
77
92
  controller.send(:"request=", ActionDispatch::Request.new({}))
78
93
  end
79
94
 
80
- response = ActionDispatch::Response.new(200, {}, '').tap do |res|
95
+ response = ActionDispatch::Response.new(200, {}, "").tap do |res|
81
96
  res.request = controller.request
82
97
  end
83
98
 
@@ -100,7 +115,7 @@ describe Split::Persistence::CookieAdapter do
100
115
  expect(subject["foo"]).to eq("FOO")
101
116
  expect(subject["bar"]).to eq("BAR")
102
117
  cookie_jar = context.request.env["action_dispatch.cookies"]
103
- expect(cookie_jar['split']).to eq("{\"foo\":\"FOO\",\"bar\":\"BAR\"}")
118
+ expect(cookie_jar["split"]).to eq('{"foo":"FOO","bar":"BAR"}')
104
119
  end
105
120
  end
106
121
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe Split::Persistence::DualAdapter do
6
- let(:context) { 'some context' }
6
+ let(:context) { "some context" }
7
7
 
8
8
  let(:logged_in_adapter_instance) { double }
9
9
  let(:logged_in_adapter) do
@@ -14,8 +14,8 @@ describe Split::Persistence::DualAdapter do
14
14
  Class.new.tap { |c| allow(c).to receive(:new) { logged_out_adapter_instance } }
15
15
  end
16
16
 
17
- context 'when fallback_to_logged_out_adapter is false' do
18
- context 'when logged in' do
17
+ context "when fallback_to_logged_out_adapter is false" do
18
+ context "when logged in" do
19
19
  subject do
20
20
  described_class.with_config(
21
21
  logged_in: lambda { |context| true },
@@ -25,32 +25,32 @@ describe Split::Persistence::DualAdapter do
25
25
  ).new(context)
26
26
  end
27
27
 
28
- it '#[]=' do
29
- expect(logged_in_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
28
+ it "#[]=" do
29
+ expect(logged_in_adapter_instance).to receive(:[]=).with("my_key", "my_value")
30
30
  expect_any_instance_of(logged_out_adapter).not_to receive(:[]=)
31
- subject['my_key'] = 'my_value'
31
+ subject["my_key"] = "my_value"
32
32
  end
33
33
 
34
- it '#[]' do
35
- expect(logged_in_adapter_instance).to receive(:[]).with('my_key') { 'my_value' }
34
+ it "#[]" do
35
+ expect(logged_in_adapter_instance).to receive(:[]).with("my_key") { "my_value" }
36
36
  expect_any_instance_of(logged_out_adapter).not_to receive(:[])
37
- expect(subject['my_key']).to eq('my_value')
37
+ expect(subject["my_key"]).to eq("my_value")
38
38
  end
39
39
 
40
- it '#delete' do
41
- expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
40
+ it "#delete" do
41
+ expect(logged_in_adapter_instance).to receive(:delete).with("my_key") { "my_value" }
42
42
  expect_any_instance_of(logged_out_adapter).not_to receive(:delete)
43
- expect(subject.delete('my_key')).to eq('my_value')
43
+ expect(subject.delete("my_key")).to eq("my_value")
44
44
  end
45
45
 
46
- it '#keys' do
47
- expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] }
46
+ it "#keys" do
47
+ expect(logged_in_adapter_instance).to receive(:keys) { ["my_value"] }
48
48
  expect_any_instance_of(logged_out_adapter).not_to receive(:keys)
49
- expect(subject.keys).to eq(['my_value'])
49
+ expect(subject.keys).to eq(["my_value"])
50
50
  end
51
51
  end
52
52
 
53
- context 'when logged out' do
53
+ context "when logged out" do
54
54
  subject do
55
55
  described_class.with_config(
56
56
  logged_in: lambda { |context| false },
@@ -60,34 +60,34 @@ describe Split::Persistence::DualAdapter do
60
60
  ).new(context)
61
61
  end
62
62
 
63
- it '#[]=' do
63
+ it "#[]=" do
64
64
  expect_any_instance_of(logged_in_adapter).not_to receive(:[]=)
65
- expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
66
- subject['my_key'] = 'my_value'
65
+ expect(logged_out_adapter_instance).to receive(:[]=).with("my_key", "my_value")
66
+ subject["my_key"] = "my_value"
67
67
  end
68
68
 
69
- it '#[]' do
69
+ it "#[]" do
70
70
  expect_any_instance_of(logged_in_adapter).not_to receive(:[])
71
- expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { 'my_value' }
72
- expect(subject['my_key']).to eq('my_value')
71
+ expect(logged_out_adapter_instance).to receive(:[]).with("my_key") { "my_value" }
72
+ expect(subject["my_key"]).to eq("my_value")
73
73
  end
74
74
 
75
- it '#delete' do
75
+ it "#delete" do
76
76
  expect_any_instance_of(logged_in_adapter).not_to receive(:delete)
77
- expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
78
- expect(subject.delete('my_key')).to eq('my_value')
77
+ expect(logged_out_adapter_instance).to receive(:delete).with("my_key") { "my_value" }
78
+ expect(subject.delete("my_key")).to eq("my_value")
79
79
  end
80
80
 
81
- it '#keys' do
81
+ it "#keys" do
82
82
  expect_any_instance_of(logged_in_adapter).not_to receive(:keys)
83
- expect(logged_out_adapter_instance).to receive(:keys) { ['my_value', 'my_value2'] }
84
- expect(subject.keys).to eq(['my_value', 'my_value2'])
83
+ expect(logged_out_adapter_instance).to receive(:keys) { ["my_value", "my_value2"] }
84
+ expect(subject.keys).to eq(["my_value", "my_value2"])
85
85
  end
86
86
  end
87
87
  end
88
88
 
89
- context 'when fallback_to_logged_out_adapter is true' do
90
- context 'when logged in' do
89
+ context "when fallback_to_logged_out_adapter is true" do
90
+ context "when logged in" do
91
91
  subject do
92
92
  described_class.with_config(
93
93
  logged_in: lambda { |context| true },
@@ -97,33 +97,33 @@ describe Split::Persistence::DualAdapter do
97
97
  ).new(context)
98
98
  end
99
99
 
100
- it '#[]=' do
101
- expect(logged_in_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
102
- expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
103
- expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { nil }
104
- subject['my_key'] = 'my_value'
100
+ it "#[]=" do
101
+ expect(logged_in_adapter_instance).to receive(:[]=).with("my_key", "my_value")
102
+ expect(logged_out_adapter_instance).to receive(:[]=).with("my_key", "my_value")
103
+ expect(logged_out_adapter_instance).to receive(:[]).with("my_key") { nil }
104
+ subject["my_key"] = "my_value"
105
105
  end
106
106
 
107
- it '#[]' do
108
- expect(logged_in_adapter_instance).to receive(:[]).with('my_key') { 'my_value' }
107
+ it "#[]" do
108
+ expect(logged_in_adapter_instance).to receive(:[]).with("my_key") { "my_value" }
109
109
  expect_any_instance_of(logged_out_adapter).not_to receive(:[])
110
- expect(subject['my_key']).to eq('my_value')
110
+ expect(subject["my_key"]).to eq("my_value")
111
111
  end
112
112
 
113
- it '#delete' do
114
- expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
115
- expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
116
- expect(subject.delete('my_key')).to eq('my_value')
113
+ it "#delete" do
114
+ expect(logged_in_adapter_instance).to receive(:delete).with("my_key") { "my_value" }
115
+ expect(logged_out_adapter_instance).to receive(:delete).with("my_key") { "my_value" }
116
+ expect(subject.delete("my_key")).to eq("my_value")
117
117
  end
118
118
 
119
- it '#keys' do
120
- expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] }
121
- expect(logged_out_adapter_instance).to receive(:keys) { ['my_value', 'my_value2'] }
122
- expect(subject.keys).to eq(['my_value', 'my_value2'])
119
+ it "#keys" do
120
+ expect(logged_in_adapter_instance).to receive(:keys) { ["my_value"] }
121
+ expect(logged_out_adapter_instance).to receive(:keys) { ["my_value", "my_value2"] }
122
+ expect(subject.keys).to eq(["my_value", "my_value2"])
123
123
  end
124
124
  end
125
125
 
126
- context 'when logged out' do
126
+ context "when logged out" do
127
127
  subject do
128
128
  described_class.with_config(
129
129
  logged_in: lambda { |context| false },
@@ -133,39 +133,39 @@ describe Split::Persistence::DualAdapter do
133
133
  ).new(context)
134
134
  end
135
135
 
136
- it '#[]=' do
136
+ it "#[]=" do
137
137
  expect_any_instance_of(logged_in_adapter).not_to receive(:[]=)
138
- expect(logged_out_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
139
- expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { nil }
140
- subject['my_key'] = 'my_value'
138
+ expect(logged_out_adapter_instance).to receive(:[]=).with("my_key", "my_value")
139
+ expect(logged_out_adapter_instance).to receive(:[]).with("my_key") { nil }
140
+ subject["my_key"] = "my_value"
141
141
  end
142
142
 
143
- it '#[]' do
143
+ it "#[]" do
144
144
  expect_any_instance_of(logged_in_adapter).not_to receive(:[])
145
- expect(logged_out_adapter_instance).to receive(:[]).with('my_key') { 'my_value' }
146
- expect(subject['my_key']).to eq('my_value')
145
+ expect(logged_out_adapter_instance).to receive(:[]).with("my_key") { "my_value" }
146
+ expect(subject["my_key"]).to eq("my_value")
147
147
  end
148
148
 
149
- it '#delete' do
150
- expect(logged_in_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
151
- expect(logged_out_adapter_instance).to receive(:delete).with('my_key') { 'my_value' }
152
- expect(subject.delete('my_key')).to eq('my_value')
149
+ it "#delete" do
150
+ expect(logged_in_adapter_instance).to receive(:delete).with("my_key") { "my_value" }
151
+ expect(logged_out_adapter_instance).to receive(:delete).with("my_key") { "my_value" }
152
+ expect(subject.delete("my_key")).to eq("my_value")
153
153
  end
154
154
 
155
- it '#keys' do
156
- expect(logged_in_adapter_instance).to receive(:keys) { ['my_value'] }
157
- expect(logged_out_adapter_instance).to receive(:keys) { ['my_value', 'my_value2'] }
158
- expect(subject.keys).to eq(['my_value', 'my_value2'])
155
+ it "#keys" do
156
+ expect(logged_in_adapter_instance).to receive(:keys) { ["my_value"] }
157
+ expect(logged_out_adapter_instance).to receive(:keys) { ["my_value", "my_value2"] }
158
+ expect(subject.keys).to eq(["my_value", "my_value2"])
159
159
  end
160
160
  end
161
161
  end
162
162
 
163
- describe 'when errors in config' do
163
+ describe "when errors in config" do
164
164
  before { described_class.config.clear }
165
- let(:some_proc) { ->{} }
165
+ let(:some_proc) { -> { } }
166
166
 
167
- it 'when no logged in adapter' do
168
- expect{
167
+ it "when no logged in adapter" do
168
+ expect {
169
169
  described_class.with_config(
170
170
  logged_in: some_proc,
171
171
  logged_out_adapter: logged_out_adapter
@@ -173,8 +173,8 @@ describe Split::Persistence::DualAdapter do
173
173
  }.to raise_error(StandardError, /:logged_in_adapter/)
174
174
  end
175
175
 
176
- it 'when no logged out adapter' do
177
- expect{
176
+ it "when no logged out adapter" do
177
+ expect {
178
178
  described_class.with_config(
179
179
  logged_in: some_proc,
180
180
  logged_in_adapter: logged_in_adapter
@@ -182,8 +182,8 @@ describe Split::Persistence::DualAdapter do
182
182
  }.to raise_error(StandardError, /:logged_out_adapter/)
183
183
  end
184
184
 
185
- it 'when no logged in detector' do
186
- expect{
185
+ it "when no logged in detector" do
186
+ expect {
187
187
  described_class.with_config(
188
188
  logged_in_adapter: logged_in_adapter,
189
189
  logged_out_adapter: logged_out_adapter
@@ -1,67 +1,67 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "spec_helper"
3
4
 
4
5
  describe Split::Persistence::RedisAdapter do
5
-
6
- let(:context) { double(:lookup => 'blah') }
6
+ let(:context) { double(lookup: "blah") }
7
7
 
8
8
  subject { Split::Persistence::RedisAdapter.new(context) }
9
9
 
10
- describe '#redis_key' do
10
+ describe "#redis_key" do
11
11
  before { Split::Persistence::RedisAdapter.reset_config! }
12
12
 
13
- context 'default' do
14
- it 'should raise error with prompt to set lookup_by' do
15
- expect{Split::Persistence::RedisAdapter.new(context)}.to raise_error(RuntimeError)
13
+ context "default" do
14
+ it "should raise error with prompt to set lookup_by" do
15
+ expect { Split::Persistence::RedisAdapter.new(context) }.to raise_error(RuntimeError)
16
16
  end
17
17
  end
18
18
 
19
- context 'config with key' do
19
+ context "config with key" do
20
20
  before { Split::Persistence::RedisAdapter.reset_config! }
21
- subject { Split::Persistence::RedisAdapter.new(context, 'manual') }
21
+ subject { Split::Persistence::RedisAdapter.new(context, "manual") }
22
22
 
23
23
  it 'should be "persistence:manual"' do
24
- expect(subject.redis_key).to eq('persistence:manual')
24
+ expect(subject.redis_key).to eq("persistence:manual")
25
25
  end
26
26
  end
27
27
 
28
28
  context 'config with lookup_by = proc { "block" }' do
29
- before { Split::Persistence::RedisAdapter.with_config(:lookup_by => proc{'block'}) }
29
+ before { Split::Persistence::RedisAdapter.with_config(lookup_by: proc { "block" }) }
30
30
 
31
31
  it 'should be "persistence:block"' do
32
- expect(subject.redis_key).to eq('persistence:block')
32
+ expect(subject.redis_key).to eq("persistence:block")
33
33
  end
34
34
  end
35
35
 
36
- context 'config with lookup_by = proc { |context| context.test }' do
37
- before { Split::Persistence::RedisAdapter.with_config(:lookup_by => proc{'block'}) }
38
- let(:context) { double(:test => 'block') }
36
+ context "config with lookup_by = proc { |context| context.test }" do
37
+ before { Split::Persistence::RedisAdapter.with_config(lookup_by: proc { "block" }) }
38
+ let(:context) { double(test: "block") }
39
39
 
40
40
  it 'should be "persistence:block"' do
41
- expect(subject.redis_key).to eq('persistence:block')
41
+ expect(subject.redis_key).to eq("persistence:block")
42
42
  end
43
43
  end
44
44
 
45
45
  context 'config with lookup_by = "method_name"' do
46
- before { Split::Persistence::RedisAdapter.with_config(:lookup_by => 'method_name') }
47
- let(:context) { double(:method_name => 'val') }
46
+ before { Split::Persistence::RedisAdapter.with_config(lookup_by: "method_name") }
47
+ let(:context) { double(method_name: "val") }
48
48
 
49
49
  it 'should be "persistence:bar"' do
50
- expect(subject.redis_key).to eq('persistence:val')
50
+ expect(subject.redis_key).to eq("persistence:val")
51
51
  end
52
52
  end
53
53
 
54
- context 'config with namespace and lookup_by' do
55
- before { Split::Persistence::RedisAdapter.with_config(:lookup_by => proc{'frag'}, :namespace => 'namer') }
54
+ context "config with namespace and lookup_by" do
55
+ before { Split::Persistence::RedisAdapter.with_config(lookup_by: proc { "frag" }, namespace: "namer") }
56
56
 
57
57
  it 'should be "namer"' do
58
- expect(subject.redis_key).to eq('namer:frag')
58
+ expect(subject.redis_key).to eq("namer:frag")
59
59
  end
60
60
  end
61
61
  end
62
62
 
63
- describe '#find' do
64
- before { Split::Persistence::RedisAdapter.with_config(:lookup_by => proc{'frag'}, :namespace => 'a_namespace') }
63
+ describe "#find" do
64
+ before { Split::Persistence::RedisAdapter.with_config(lookup_by: proc { "frag" }, namespace: "a_namespace") }
65
65
 
66
66
  it "should create and user from a given key" do
67
67
  adapter = Split::Persistence::RedisAdapter.find(2)
@@ -69,13 +69,13 @@ describe Split::Persistence::RedisAdapter do
69
69
  end
70
70
  end
71
71
 
72
- context 'functional tests' do
73
- before { Split::Persistence::RedisAdapter.with_config(:lookup_by => 'lookup') }
72
+ context "functional tests" do
73
+ before { Split::Persistence::RedisAdapter.with_config(lookup_by: "lookup") }
74
74
 
75
75
  describe "#[] and #[]=" do
76
- it "should set and return the value for given key" do
77
- subject["my_key"] = "my_value"
78
- expect(subject["my_key"]).to eq("my_value")
76
+ it "should convert to string, set and return the value for given key" do
77
+ subject["my_key"] = true
78
+ expect(subject["my_key"]).to eq("true")
79
79
  end
80
80
  end
81
81
 
@@ -94,6 +94,5 @@ describe Split::Persistence::RedisAdapter do
94
94
  expect(subject.keys).to match(["my_key", "my_second_key"])
95
95
  end
96
96
  end
97
-
98
97
  end
99
98
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "spec_helper"
3
4
 
4
5
  describe Split::Persistence::SessionAdapter do
5
-
6
- let(:context) { double(:session => {}) }
6
+ let(:context) { double(session: {}) }
7
7
  subject { Split::Persistence::SessionAdapter.new(context) }
8
8
 
9
9
  describe "#[] and #[]=" do
@@ -28,5 +28,4 @@ describe Split::Persistence::SessionAdapter do
28
28
  expect(subject.keys).to match(["my_key", "my_second_key"])
29
29
  end
30
30
  end
31
-
32
31
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "spec_helper"
3
4
 
4
5
  describe Split::Persistence do
5
-
6
6
  subject { Split::Persistence }
7
7
 
8
8
  describe ".adapter" do
@@ -30,5 +30,4 @@ describe Split::Persistence do
30
30
  end
31
31
  end
32
32
  end
33
-
34
33
  end
@@ -1,42 +1,54 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe Split::RedisInterface do
4
- let(:list_name) { 'list_name' }
5
- let(:set_name) { 'set_name' }
6
+ let(:list_name) { "list_name" }
7
+ let(:set_name) { "set_name" }
6
8
  let(:interface) { described_class.new }
7
9
 
8
- describe '#persist_list' do
10
+ describe "#persist_list" do
9
11
  subject(:persist_list) do
10
12
  interface.persist_list(list_name, %w(a b c d))
11
13
  end
12
14
 
13
15
  specify do
14
16
  expect(persist_list).to eq %w(a b c d)
15
- expect(Split.redis.lindex(list_name, 0)).to eq 'a'
16
- expect(Split.redis.lindex(list_name, 1)).to eq 'b'
17
- expect(Split.redis.lindex(list_name, 2)).to eq 'c'
18
- expect(Split.redis.lindex(list_name, 3)).to eq 'd'
17
+ expect(Split.redis.lindex(list_name, 0)).to eq "a"
18
+ expect(Split.redis.lindex(list_name, 1)).to eq "b"
19
+ expect(Split.redis.lindex(list_name, 2)).to eq "c"
20
+ expect(Split.redis.lindex(list_name, 3)).to eq "d"
19
21
  expect(Split.redis.llen(list_name)).to eq 4
20
22
  end
21
23
 
22
- context 'list is overwritten but not deleted' do
24
+ context "list is overwritten but not deleted" do
23
25
  specify do
24
26
  expect(persist_list).to eq %w(a b c d)
25
- interface.persist_list(list_name, ['z'])
26
- expect(Split.redis.lindex(list_name, 0)).to eq 'z'
27
+ interface.persist_list(list_name, ["z"])
28
+ expect(Split.redis.lindex(list_name, 0)).to eq "z"
27
29
  expect(Split.redis.llen(list_name)).to eq 1
28
30
  end
29
31
  end
30
32
  end
31
33
 
32
- describe '#add_to_set' do
34
+ describe "#add_to_set" do
33
35
  subject(:add_to_set) do
34
- interface.add_to_set(set_name, 'something')
36
+ interface.add_to_set(set_name, "something")
35
37
  end
36
38
 
37
39
  specify do
38
40
  add_to_set
39
- expect(Split.redis.sismember(set_name, 'something')).to be true
41
+ expect(Split.redis.sismember(set_name, "something")).to be true
42
+ end
43
+
44
+ context "when a Redis version is used that supports the 'sadd?' method" do
45
+ before { expect(Split.redis).to receive(:respond_to?).with(:sadd?).and_return(true) }
46
+
47
+ it "will use this method instead of 'sadd'" do
48
+ expect(Split.redis).to receive(:sadd?).with(set_name, "something")
49
+ expect(Split.redis).not_to receive(:sadd).with(set_name, "something")
50
+ add_to_set
51
+ end
40
52
  end
41
53
  end
42
54
  end
data/spec/spec_helper.rb CHANGED
@@ -1,21 +1,23 @@
1
1
  # frozen_string_literal: true
2
- ENV['RACK_ENV'] = "test"
3
2
 
4
- require 'rubygems'
5
- require 'bundler/setup'
3
+ ENV["RACK_ENV"] = "test"
6
4
 
7
- require 'simplecov'
5
+ require "rubygems"
6
+ require "bundler/setup"
7
+
8
+ require "simplecov"
8
9
  SimpleCov.start
9
10
 
10
- require 'split'
11
- require 'ostruct'
12
- require 'yaml'
11
+ require "split"
12
+ require "ostruct"
13
+ require "yaml"
14
+ require "pry"
13
15
 
14
- Dir['./spec/support/*.rb'].each { |f| require f }
16
+ Dir["./spec/support/*.rb"].each { |f| require f }
15
17
 
16
18
  module GlobalSharedContext
17
19
  extend RSpec::SharedContext
18
- let(:mock_user){ Split::User.new(double(session: {})) }
20
+ let(:mock_user) { Split::User.new(double(session: {})) }
19
21
 
20
22
  before(:each) do
21
23
  Split.configuration = Split::Configuration.new
@@ -24,13 +26,14 @@ module GlobalSharedContext
24
26
  Split.redis.flushdb
25
27
  Split::Cache.clear
26
28
  @ab_user = mock_user
27
- params = nil
29
+ @params = nil
28
30
  end
29
31
  end
30
32
 
31
33
  RSpec.configure do |config|
32
- config.order = 'random'
34
+ config.order = "random"
33
35
  config.include GlobalSharedContext
36
+ config.raise_errors_for_deprecations!
34
37
  end
35
38
 
36
39
  def session
@@ -41,11 +44,11 @@ def params
41
44
  @params ||= {}
42
45
  end
43
46
 
44
- def request(ua = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; de-de) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27')
47
+ def request(ua = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; de-de) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27")
45
48
  @request ||= begin
46
49
  r = OpenStruct.new
47
50
  r.user_agent = ua
48
- r.ip = '192.168.1.1'
51
+ r.ip = "192.168.1.1"
49
52
  r
50
53
  end
51
54
  end