split 2.0.0 → 3.0.0

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +30 -0
  3. data/.csslintrc +2 -0
  4. data/.eslintignore +1 -0
  5. data/.eslintrc +213 -0
  6. data/.rubocop.yml +1156 -0
  7. data/.travis.yml +5 -2
  8. data/Appraisals +5 -4
  9. data/CHANGELOG.md +46 -0
  10. data/Gemfile +1 -0
  11. data/README.md +123 -20
  12. data/gemfiles/4.2.gemfile +1 -0
  13. data/gemfiles/5.0.gemfile +10 -0
  14. data/lib/split/algorithms/block_randomization.rb +22 -0
  15. data/lib/split/alternative.rb +29 -8
  16. data/lib/split/configuration.rb +13 -2
  17. data/lib/split/dashboard/helpers.rb +5 -1
  18. data/lib/split/dashboard/public/dashboard-filtering.js +3 -3
  19. data/lib/split/dashboard/views/_experiment.erb +35 -1
  20. data/lib/split/dashboard.rb +5 -0
  21. data/lib/split/encapsulated_helper.rb +4 -15
  22. data/lib/split/experiment.rb +63 -54
  23. data/lib/split/goals_collection.rb +1 -1
  24. data/lib/split/helper.rb +20 -0
  25. data/lib/split/persistence/dual_adapter.rb +3 -0
  26. data/lib/split/persistence.rb +5 -3
  27. data/lib/split/redis_interface.rb +51 -0
  28. data/lib/split/user.rb +3 -1
  29. data/lib/split/version.rb +1 -1
  30. data/lib/split/zscore.rb +1 -1
  31. data/lib/split.rb +34 -41
  32. data/spec/algorithms/block_randomization_spec.rb +32 -0
  33. data/spec/alternative_spec.rb +31 -0
  34. data/spec/configuration_spec.rb +19 -5
  35. data/spec/dashboard_helpers_spec.rb +14 -0
  36. data/spec/dashboard_spec.rb +15 -0
  37. data/spec/encapsulated_helper_spec.rb +35 -4
  38. data/spec/experiment_spec.rb +38 -7
  39. data/spec/helper_spec.rb +59 -16
  40. data/spec/persistence/dual_adapter_spec.rb +102 -0
  41. data/spec/redis_interface_spec.rb +111 -0
  42. data/spec/spec_helper.rb +11 -10
  43. data/spec/split_spec.rb +43 -0
  44. data/split.gemspec +2 -3
  45. metadata +23 -26
  46. data/gemfiles/4.1.gemfile +0 -8
  47. data/lib/split/algorithms.rb +0 -4
  48. data/lib/split/extensions/array.rb +0 -5
  49. data/lib/split/extensions.rb +0 -4
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  require 'spec_helper'
3
- require 'split/experiment'
4
- require 'split/algorithms'
5
3
  require 'time'
6
4
 
7
5
  describe Split::Experiment do
@@ -13,9 +11,7 @@ describe Split::Experiment do
13
11
  Split::Alternative.new(color, 'link_color')
14
12
  end
15
13
 
16
- let(:experiment) {
17
- new_experiment
18
- }
14
+ let(:experiment) { new_experiment }
19
15
 
20
16
  let(:blue) { alternative("blue") }
21
17
  let(:green) { alternative("green") }
@@ -242,7 +238,15 @@ describe Split::Experiment do
242
238
  end
243
239
 
244
240
  describe 'reset' do
245
- before { experiment.save }
241
+ let(:reset_manually) { false }
242
+
243
+ before do
244
+ allow(Split.configuration).to receive(:reset_manually).and_return(reset_manually)
245
+ experiment.save
246
+ green.increment_participation
247
+ green.increment_participation
248
+ end
249
+
246
250
  it 'should reset all alternatives' do
247
251
  experiment.winner = 'green'
248
252
 
@@ -352,6 +356,34 @@ describe Split::Experiment do
352
356
  same_experiment_again = same_but_different_alternative
353
357
  expect(same_experiment_again.version).to eq(1)
354
358
  end
359
+
360
+ context 'when experiment configuration is changed' do
361
+ let(:reset_manually) { false }
362
+
363
+ before do
364
+ experiment.save
365
+ allow(Split.configuration).to receive(:reset_manually).and_return(reset_manually)
366
+ green.increment_participation
367
+ green.increment_participation
368
+ experiment.set_alternatives_and_options(alternatives: %w(blue red green zip),
369
+ goals: %w(purchase))
370
+ experiment.save
371
+ end
372
+
373
+ it 'resets all alternatives' do
374
+ expect(green.participant_count).to eq(0)
375
+ expect(green.completed_count).to eq(0)
376
+ end
377
+
378
+ context 'when reset_manually is set' do
379
+ let(:reset_manually) { true }
380
+
381
+ it 'does not reset alternatives' do
382
+ expect(green.participant_count).to eq(2)
383
+ expect(green.completed_count).to eq(0)
384
+ end
385
+ end
386
+ end
355
387
  end
356
388
 
357
389
  describe 'alternatives passed as non-strings' do
@@ -448,5 +480,4 @@ describe Split::Experiment do
448
480
  expect(experiment.calc_winning_alternatives).to be nil
449
481
  end
450
482
  end
451
-
452
483
  end
data/spec/helper_spec.rb CHANGED
@@ -197,24 +197,51 @@ describe Split::Helper do
197
197
  expect(button_size_alt.participant_count).to eq(1)
198
198
  end
199
199
 
200
- it "should let a user participate in many experiment with one non-'control' alternative with allow_multiple_experiments = 'control'" do
201
- Split.configure do |config|
202
- config.allow_multiple_experiments = 'control'
203
- end
204
- groups = []
205
- (0..100).each do |n|
206
- alt = ab_test("test#{n}".to_sym, {'control' => (100 - n)}, {'test#{n}-alt' => n})
207
- groups << alt
200
+ context "with allow_multiple_experiments = 'control'" do
201
+ it "should let a user participate in many experiment with one non-'control' alternative" do
202
+ Split.configure do |config|
203
+ config.allow_multiple_experiments = 'control'
204
+ end
205
+ groups = 100.times.map do |n|
206
+ ab_test("test#{n}".to_sym, {'control' => (100 - n)}, {"test#{n}-alt" => n})
207
+ end
208
+
209
+ experiments = ab_user.active_experiments
210
+ expect(experiments.size).to be > 1
211
+
212
+ count_control = experiments.values.count { |g| g == 'control' }
213
+ expect(count_control).to eq(experiments.size - 1)
214
+
215
+ count_alts = groups.count { |g| g != 'control' }
216
+ expect(count_alts).to eq(1)
208
217
  end
209
218
 
210
- experiments = ab_user.active_experiments
211
- expect(experiments.size).to be > 1
219
+ context "when user already has experiment" do
220
+ let(:mock_user){ Split::User.new(self, {'test_0' => 'test-alt'}) }
221
+ before{
222
+ Split.configure do |config|
223
+ config.allow_multiple_experiments = 'control'
224
+ end
225
+ Split::ExperimentCatalog.find_or_initialize('test_0', 'control', 'test-alt').save
226
+ Split::ExperimentCatalog.find_or_initialize('test_1', 'control', 'test-alt').save
227
+ }
212
228
 
213
- count_control = experiments.values.count { |g| g == 'control' }
214
- expect(count_control).to eq(experiments.size - 1)
229
+ it "should restore previously selected alternative" do
230
+ expect(ab_user.active_experiments.size).to eq 1
231
+ expect(ab_test(:test_0, {'control' => 100}, {"test-alt" => 1})).to eq 'test-alt'
232
+ expect(ab_test(:test_0, {'control' => 1}, {"test-alt" => 100})).to eq 'test-alt'
233
+ end
234
+
235
+ it "lets override existing choice" do
236
+ pending "this requires user store reset on first call not depending on whelther it is current trial"
237
+ @params = { 'ab_test' => { 'test_1' => 'test-alt' } }
238
+
239
+ expect(ab_test(:test_0, {'control' => 0}, {"test-alt" => 100})).to eq 'control'
240
+ expect(ab_test(:test_1, {'control' => 100}, {"test-alt" => 1})).to eq 'test-alt'
241
+ end
242
+
243
+ end
215
244
 
216
- count_alts = groups.count { |g| g != 'control' }
217
- expect(count_alts).to eq(1)
218
245
  end
219
246
 
220
247
  it "should not over-write a finished key when an experiment is on a later version" do
@@ -642,6 +669,22 @@ describe Split::Helper do
642
669
 
643
670
  it_behaves_like "a disabled test"
644
671
  end
672
+
673
+ context "when ignored other address" do
674
+ before do
675
+ @request = OpenStruct.new(:ip => '1.1.1.1')
676
+ Split.configure do |c|
677
+ c.ignore_ip_addresses << '81.19.48.130'
678
+ end
679
+ end
680
+
681
+ it "works as usual" do
682
+ alternative_name = ab_test('link_color', 'red', 'blue')
683
+ expect{
684
+ ab_finished('link_color')
685
+ }.to change(Split::Alternative.new(alternative_name, 'link_color'), :completed_count).by(1)
686
+ end
687
+ end
645
688
  end
646
689
 
647
690
  describe 'versioned experiments' do
@@ -774,7 +817,7 @@ describe Split::Helper do
774
817
  end
775
818
  end
776
819
 
777
- expect(Split.configuration.db_failover_on_db_error).to receive(:call)
820
+ expect(Split.configuration.db_failover_on_db_error).to receive(:call).and_call_original
778
821
  ab_test('link_color', 'blue', 'red')
779
822
  end
780
823
 
@@ -833,7 +876,7 @@ describe Split::Helper do
833
876
  end
834
877
  end
835
878
 
836
- expect(Split.configuration.db_failover_on_db_error).to receive(:call)
879
+ expect(Split.configuration.db_failover_on_db_error).to receive(:call).and_call_original
837
880
  ab_finished('link_color')
838
881
  end
839
882
  end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe Split::Persistence::DualAdapter do
5
+
6
+ let(:context){ "some context" }
7
+
8
+ let(:just_adapter){ Class.new }
9
+ let(:selected_adapter_instance){ double }
10
+ let(:selected_adapter){
11
+ c = Class.new
12
+ expect(c).to receive(:new){ selected_adapter_instance }
13
+ c
14
+ }
15
+ let(:not_selected_adapter){
16
+ c = Class.new
17
+ expect(c).not_to receive(:new)
18
+ c
19
+ }
20
+
21
+ shared_examples_for "forwarding calls" do
22
+ it "#[]=" do
23
+ expect(selected_adapter_instance).to receive(:[]=).with('my_key', 'my_value')
24
+ expect_any_instance_of(not_selected_adapter).not_to receive(:[]=)
25
+ subject["my_key"] = "my_value"
26
+ end
27
+
28
+ it "#[]" do
29
+ expect(selected_adapter_instance).to receive(:[]).with('my_key'){'my_value'}
30
+ expect_any_instance_of(not_selected_adapter).not_to receive(:[])
31
+ expect(subject["my_key"]).to eq('my_value')
32
+ end
33
+
34
+ it "#delete" do
35
+ expect(selected_adapter_instance).to receive(:delete).with('my_key'){'my_value'}
36
+ expect_any_instance_of(not_selected_adapter).not_to receive(:delete)
37
+ expect(subject.delete("my_key")).to eq('my_value')
38
+ end
39
+
40
+ it "#keys" do
41
+ expect(selected_adapter_instance).to receive(:keys){'my_value'}
42
+ expect_any_instance_of(not_selected_adapter).not_to receive(:keys)
43
+ expect(subject.keys).to eq('my_value')
44
+ end
45
+ end
46
+
47
+ context "when logged in" do
48
+ subject {
49
+ described_class.with_config(
50
+ logged_in: -> (context) { true },
51
+ logged_in_adapter: selected_adapter,
52
+ logged_out_adapter: not_selected_adapter
53
+ ).new(context)
54
+ }
55
+
56
+ it_should_behave_like "forwarding calls"
57
+ end
58
+
59
+ context "when not logged in" do
60
+ subject {
61
+ described_class.with_config(
62
+ logged_in: -> (context) { false },
63
+ logged_in_adapter: not_selected_adapter,
64
+ logged_out_adapter: selected_adapter
65
+ ).new(context)
66
+ }
67
+
68
+ it_should_behave_like "forwarding calls"
69
+ end
70
+
71
+ describe "when errors in config" do
72
+ before{
73
+ described_class.config.clear
74
+ }
75
+ let(:some_proc){ ->{} }
76
+ it "when no logged in adapter" do
77
+ expect{
78
+ described_class.with_config(
79
+ logged_in: some_proc,
80
+ logged_out_adapter: just_adapter
81
+ ).new(context)
82
+ }.to raise_error(StandardError, /:logged_in_adapter/)
83
+ end
84
+ it "when no logged out adapter" do
85
+ expect{
86
+ described_class.with_config(
87
+ logged_in: some_proc,
88
+ logged_in_adapter: just_adapter
89
+ ).new(context)
90
+ }.to raise_error(StandardError, /:logged_out_adapter/)
91
+ end
92
+ it "when no logged in detector" do
93
+ expect{
94
+ described_class.with_config(
95
+ logged_in_adapter: just_adapter,
96
+ logged_out_adapter: just_adapter
97
+ ).new(context)
98
+ }.to raise_error(StandardError, /:logged_in$/)
99
+ end
100
+ end
101
+
102
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Split::RedisInterface do
4
+ let(:list_name) { 'list_name' }
5
+ let(:set_name) { 'set_name' }
6
+ let(:interface) { described_class.new }
7
+
8
+ describe '#persist_list' do
9
+ subject(:persist_list) do
10
+ interface.persist_list(list_name, %w(a b c d))
11
+ end
12
+
13
+ specify do
14
+ 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'
19
+ expect(Split.redis.llen(list_name)).to eq 4
20
+ end
21
+
22
+ context 'list is overwritten but not deleted' do
23
+ specify do
24
+ 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
+ expect(Split.redis.llen(list_name)).to eq 1
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#add_to_list' do
33
+ subject(:add_to_list) do
34
+ interface.add_to_list(list_name, 'y')
35
+ interface.add_to_list(list_name, 'z')
36
+ end
37
+
38
+ specify do
39
+ add_to_list
40
+ expect(Split.redis.lindex(list_name, 0)).to eq 'y'
41
+ expect(Split.redis.lindex(list_name, 1)).to eq 'z'
42
+ expect(Split.redis.llen(list_name)).to eq 2
43
+ end
44
+ end
45
+
46
+ describe '#set_list_index' do
47
+ subject(:set_list_index) do
48
+ interface.add_to_list(list_name, 'y')
49
+ interface.add_to_list(list_name, 'z')
50
+ interface.set_list_index(list_name, 0, 'a')
51
+ end
52
+
53
+ specify do
54
+ set_list_index
55
+ expect(Split.redis.lindex(list_name, 0)).to eq 'a'
56
+ expect(Split.redis.lindex(list_name, 1)).to eq 'z'
57
+ expect(Split.redis.llen(list_name)).to eq 2
58
+ end
59
+ end
60
+
61
+ describe '#list_length' do
62
+ subject(:list_length) do
63
+ interface.add_to_list(list_name, 'y')
64
+ interface.add_to_list(list_name, 'z')
65
+ interface.list_length(list_name)
66
+ end
67
+
68
+ specify do
69
+ expect(list_length).to eq 2
70
+ end
71
+ end
72
+
73
+ describe '#remove_last_item_from_list' do
74
+ subject(:remove_last_item_from_list) do
75
+ interface.add_to_list(list_name, 'y')
76
+ interface.add_to_list(list_name, 'z')
77
+ interface.remove_last_item_from_list(list_name)
78
+ end
79
+
80
+ specify do
81
+ remove_last_item_from_list
82
+ expect(Split.redis.lindex(list_name, 0)).to eq 'y'
83
+ expect(Split.redis.llen(list_name)).to eq 1
84
+ end
85
+ end
86
+
87
+ describe '#make_list_length' do
88
+ subject(:make_list_length) do
89
+ interface.add_to_list(list_name, 'y')
90
+ interface.add_to_list(list_name, 'z')
91
+ interface.make_list_length(list_name, 1)
92
+ end
93
+
94
+ specify do
95
+ make_list_length
96
+ expect(Split.redis.lindex(list_name, 0)).to eq 'y'
97
+ expect(Split.redis.llen(list_name)).to eq 1
98
+ end
99
+ end
100
+
101
+ describe '#add_to_set' do
102
+ subject(:add_to_set) do
103
+ interface.add_to_set(set_name, 'something')
104
+ end
105
+
106
+ specify do
107
+ add_to_set
108
+ expect(Split.redis.sismember(set_name, 'something')).to be true
109
+ end
110
+ end
111
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,33 +4,34 @@ ENV['RACK_ENV'] = "test"
4
4
  require 'rubygems'
5
5
  require 'bundler/setup'
6
6
 
7
- require 'coveralls'
8
- Coveralls.wear!
7
+ require 'simplecov'
8
+ SimpleCov.start
9
9
 
10
10
  require 'split'
11
11
  require 'ostruct'
12
12
  require 'yaml'
13
- require 'complex' if RUBY_VERSION.match(/1\.8/)
14
13
 
15
14
  Dir['./spec/support/*.rb'].each { |f| require f }
16
15
 
17
16
  require "fakeredis"
18
17
 
19
- fakeredis = Redis.new
18
+ G_fakeredis = Redis.new
20
19
 
21
- RSpec.configure do |config|
22
- config.order = 'random'
23
- config.before(:each) do
20
+ module GlobalSharedContext
21
+ extend RSpec::SharedContext
22
+ let(:mock_user){ Split::User.new(double(session: {})) }
23
+ before(:each) do
24
24
  Split.configuration = Split::Configuration.new
25
- Split.redis = fakeredis
25
+ Split.redis = G_fakeredis
26
26
  Split.redis.flushall
27
27
  @ab_user = mock_user
28
28
  params = nil
29
29
  end
30
30
  end
31
31
 
32
- def mock_user
33
- Split::User.new(double(session: {}))
32
+ RSpec.configure do |config|
33
+ config.order = 'random'
34
+ config.include GlobalSharedContext
34
35
  end
35
36
 
36
37
  def session
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Split do
5
+
6
+ around(:each) do |ex|
7
+ old_env, old_redis = [ENV.delete('REDIS_URL'), Split.redis]
8
+ ex.run
9
+ ENV['REDIS_URL'] = old_env
10
+ Split.redis = old_redis
11
+ end
12
+
13
+ describe '#redis=' do
14
+ it 'accepts a url string' do
15
+ Split.redis = 'redis://localhost:6379'
16
+ expect(Split.redis).to be_a(Redis)
17
+
18
+ client = Split.redis.client
19
+ expect(client.host).to eq("localhost")
20
+ expect(client.port).to eq(6379)
21
+ end
22
+
23
+ it 'accepts an options hash' do
24
+ Split.redis = {host: 'localhost', port: 6379, db: 12}
25
+ expect(Split.redis).to be_a(Redis)
26
+
27
+ client = Split.redis.client
28
+ expect(client.host).to eq("localhost")
29
+ expect(client.port).to eq(6379)
30
+ expect(client.db).to eq(12)
31
+ end
32
+
33
+ it 'accepts a valid Redis instance' do
34
+ other_redis = Redis.new(url: "redis://localhost:6379")
35
+ Split.redis = other_redis
36
+ expect(Split.redis).to eq(other_redis)
37
+ end
38
+
39
+ it 'raises an ArgumentError when server cannot be determined' do
40
+ expect { Split.redis = Object.new }.to raise_error(ArgumentError)
41
+ end
42
+ end
43
+ end
data/split.gemspec CHANGED
@@ -21,15 +21,14 @@ Gem::Specification.new do |s|
21
21
  s.require_paths = ["lib"]
22
22
 
23
23
  s.add_dependency 'redis', '>= 2.1'
24
- s.add_dependency 'redis-namespace', '>= 1.1.0'
25
24
  s.add_dependency 'sinatra', '>= 1.2.6'
26
25
  s.add_dependency 'simple-random', '>= 0.9.3'
27
26
 
28
27
  s.add_development_dependency 'bundler', '~> 1.10'
29
- s.add_development_dependency 'coveralls', '~> 0.8'
28
+ s.add_development_dependency 'simplecov', '~> 0.12'
30
29
  s.add_development_dependency 'rack-test', '~> 0.6'
31
30
  s.add_development_dependency 'rake', '~> 11.1'
32
31
  s.add_development_dependency 'rspec', '~> 3.4'
33
32
  s.add_development_dependency 'pry', '~> 0.10'
34
- s.add_development_dependency 'fakeredis', '~> 0.5.0'
33
+ s.add_development_dependency 'fakeredis', '~> 0.6.0'
35
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: split
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nesbitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-17 00:00:00.000000000 Z
11
+ date: 2017-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.1'
27
- - !ruby/object:Gem::Dependency
28
- name: redis-namespace
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 1.1.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 1.1.0
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: sinatra
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -81,19 +67,19 @@ dependencies:
81
67
  - !ruby/object:Gem::Version
82
68
  version: '1.10'
83
69
  - !ruby/object:Gem::Dependency
84
- name: coveralls
70
+ name: simplecov
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: '0.8'
75
+ version: '0.12'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: '0.8'
82
+ version: '0.12'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: rack-test
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +142,14 @@ dependencies:
156
142
  requirements:
157
143
  - - "~>"
158
144
  - !ruby/object:Gem::Version
159
- version: 0.5.0
145
+ version: 0.6.0
160
146
  type: :development
161
147
  prerelease: false
162
148
  version_requirements: !ruby/object:Gem::Requirement
163
149
  requirements:
164
150
  - - "~>"
165
151
  - !ruby/object:Gem::Version
166
- version: 0.5.0
152
+ version: 0.6.0
167
153
  description:
168
154
  email:
169
155
  - andrewnez@gmail.com
@@ -171,7 +157,12 @@ executables: []
171
157
  extensions: []
172
158
  extra_rdoc_files: []
173
159
  files:
160
+ - ".codeclimate.yml"
161
+ - ".csslintrc"
162
+ - ".eslintignore"
163
+ - ".eslintrc"
174
164
  - ".gitignore"
165
+ - ".rubocop.yml"
175
166
  - ".travis.yml"
176
167
  - Appraisals
177
168
  - CHANGELOG.md
@@ -181,10 +172,10 @@ files:
181
172
  - LICENSE
182
173
  - README.md
183
174
  - Rakefile
184
- - gemfiles/4.1.gemfile
185
175
  - gemfiles/4.2.gemfile
176
+ - gemfiles/5.0.gemfile
186
177
  - lib/split.rb
187
- - lib/split/algorithms.rb
178
+ - lib/split/algorithms/block_randomization.rb
188
179
  - lib/split/algorithms/weighted_sample.rb
189
180
  - lib/split/algorithms/whiplash.rb
190
181
  - lib/split/alternative.rb
@@ -206,8 +197,6 @@ files:
206
197
  - lib/split/exceptions.rb
207
198
  - lib/split/experiment.rb
208
199
  - lib/split/experiment_catalog.rb
209
- - lib/split/extensions.rb
210
- - lib/split/extensions/array.rb
211
200
  - lib/split/extensions/string.rb
212
201
  - lib/split/goals_collection.rb
213
202
  - lib/split/helper.rb
@@ -217,10 +206,12 @@ files:
217
206
  - lib/split/persistence/dual_adapter.rb
218
207
  - lib/split/persistence/redis_adapter.rb
219
208
  - lib/split/persistence/session_adapter.rb
209
+ - lib/split/redis_interface.rb
220
210
  - lib/split/trial.rb
221
211
  - lib/split/user.rb
222
212
  - lib/split/version.rb
223
213
  - lib/split/zscore.rb
214
+ - spec/algorithms/block_randomization_spec.rb
224
215
  - spec/algorithms/weighted_sample_spec.rb
225
216
  - spec/algorithms/whiplash_spec.rb
226
217
  - spec/alternative_spec.rb
@@ -234,10 +225,13 @@ files:
234
225
  - spec/helper_spec.rb
235
226
  - spec/metric_spec.rb
236
227
  - spec/persistence/cookie_adapter_spec.rb
228
+ - spec/persistence/dual_adapter_spec.rb
237
229
  - spec/persistence/redis_adapter_spec.rb
238
230
  - spec/persistence/session_adapter_spec.rb
239
231
  - spec/persistence_spec.rb
232
+ - spec/redis_interface_spec.rb
240
233
  - spec/spec_helper.rb
234
+ - spec/split_spec.rb
241
235
  - spec/support/cookies_mock.rb
242
236
  - spec/trial_spec.rb
243
237
  - spec/user_spec.rb
@@ -267,6 +261,7 @@ signing_key:
267
261
  specification_version: 4
268
262
  summary: Rack based split testing framework
269
263
  test_files:
264
+ - spec/algorithms/block_randomization_spec.rb
270
265
  - spec/algorithms/weighted_sample_spec.rb
271
266
  - spec/algorithms/whiplash_spec.rb
272
267
  - spec/alternative_spec.rb
@@ -280,11 +275,13 @@ test_files:
280
275
  - spec/helper_spec.rb
281
276
  - spec/metric_spec.rb
282
277
  - spec/persistence/cookie_adapter_spec.rb
278
+ - spec/persistence/dual_adapter_spec.rb
283
279
  - spec/persistence/redis_adapter_spec.rb
284
280
  - spec/persistence/session_adapter_spec.rb
285
281
  - spec/persistence_spec.rb
282
+ - spec/redis_interface_spec.rb
286
283
  - spec/spec_helper.rb
284
+ - spec/split_spec.rb
287
285
  - spec/support/cookies_mock.rb
288
286
  - spec/trial_spec.rb
289
287
  - spec/user_spec.rb
290
- has_rdoc:
data/gemfiles/4.1.gemfile DELETED
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "rails", "~> 4.1"
7
-
8
- gemspec :path => "../"
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
- %w[weighted_sample whiplash].each do |f|
3
- require "split/algorithms/#{f}"
4
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
- class Array
3
- # maintain backwards compatibility with 1.8.7
4
- alias_method :sample, :choice unless method_defined?(:sample)
5
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
- %w[array string].each do |f|
3
- require "split/extensions/#{f}"
4
- end