split 3.4.1 → 4.0.0.pre
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/FUNDING.yml +1 -0
- data/.rubocop.yml +177 -1
- data/.rubocop_todo.yml +40 -493
- data/.travis.yml +14 -42
- data/CHANGELOG.md +35 -0
- data/Gemfile +1 -0
- data/README.md +19 -1
- data/Rakefile +1 -0
- data/lib/split.rb +8 -2
- data/lib/split/algorithms/block_randomization.rb +1 -0
- data/lib/split/algorithms/weighted_sample.rb +2 -1
- data/lib/split/algorithms/whiplash.rb +3 -2
- data/lib/split/alternative.rb +1 -0
- data/lib/split/cache.rb +28 -0
- data/lib/split/combined_experiments_helper.rb +1 -0
- data/lib/split/configuration.rb +6 -12
- data/lib/split/dashboard.rb +17 -2
- data/lib/split/dashboard/helpers.rb +1 -0
- data/lib/split/dashboard/pagination_helpers.rb +1 -0
- data/lib/split/dashboard/paginator.rb +1 -0
- data/lib/split/dashboard/public/dashboard.js +10 -0
- data/lib/split/dashboard/public/style.css +5 -0
- data/lib/split/dashboard/views/_controls.erb +13 -0
- data/lib/split/encapsulated_helper.rb +3 -2
- data/lib/split/engine.rb +1 -0
- data/lib/split/exceptions.rb +1 -0
- data/lib/split/experiment.rb +81 -59
- data/lib/split/experiment_catalog.rb +1 -3
- data/lib/split/extensions/string.rb +1 -0
- data/lib/split/goals_collection.rb +1 -0
- data/lib/split/helper.rb +26 -7
- data/lib/split/metric.rb +2 -1
- data/lib/split/persistence.rb +4 -2
- data/lib/split/persistence/cookie_adapter.rb +1 -0
- data/lib/split/persistence/redis_adapter.rb +5 -0
- data/lib/split/persistence/session_adapter.rb +1 -0
- data/lib/split/redis_interface.rb +8 -28
- data/lib/split/trial.rb +20 -10
- data/lib/split/user.rb +14 -2
- data/lib/split/version.rb +2 -4
- data/lib/split/zscore.rb +1 -0
- data/spec/alternative_spec.rb +1 -1
- data/spec/cache_spec.rb +88 -0
- data/spec/configuration_spec.rb +1 -14
- data/spec/dashboard_spec.rb +45 -5
- data/spec/encapsulated_helper_spec.rb +1 -1
- data/spec/experiment_spec.rb +78 -7
- data/spec/goals_collection_spec.rb +1 -1
- data/spec/helper_spec.rb +68 -32
- data/spec/persistence/cookie_adapter_spec.rb +1 -1
- data/spec/persistence/redis_adapter_spec.rb +9 -0
- data/spec/redis_interface_spec.rb +0 -69
- data/spec/spec_helper.rb +5 -6
- data/spec/trial_spec.rb +45 -19
- data/spec/user_spec.rb +17 -0
- data/split.gemspec +7 -7
- metadata +23 -34
- data/gemfiles/4.2.gemfile +0 -9
data/spec/helper_spec.rb
CHANGED
@@ -229,13 +229,15 @@ describe Split::Helper do
|
|
229
229
|
|
230
230
|
context "when user already has experiment" do
|
231
231
|
let(:mock_user){ Split::User.new(self, {'test_0' => 'test-alt'}) }
|
232
|
-
|
232
|
+
|
233
|
+
before do
|
233
234
|
Split.configure do |config|
|
234
235
|
config.allow_multiple_experiments = 'control'
|
235
236
|
end
|
237
|
+
|
236
238
|
Split::ExperimentCatalog.find_or_initialize('test_0', 'control', 'test-alt').save
|
237
239
|
Split::ExperimentCatalog.find_or_initialize('test_1', 'control', 'test-alt').save
|
238
|
-
|
240
|
+
end
|
239
241
|
|
240
242
|
it "should restore previously selected alternative" do
|
241
243
|
expect(ab_user.active_experiments.size).to eq 1
|
@@ -243,6 +245,16 @@ describe Split::Helper do
|
|
243
245
|
expect(ab_test(:test_0, {'control' => 1}, {"test-alt" => 100})).to eq 'test-alt'
|
244
246
|
end
|
245
247
|
|
248
|
+
it "should select the correct alternatives after experiment resets" do
|
249
|
+
experiment = Split::ExperimentCatalog.find(:test_0)
|
250
|
+
experiment.reset
|
251
|
+
mock_user[experiment.key] = 'test-alt'
|
252
|
+
|
253
|
+
expect(ab_user.active_experiments.size).to eq 1
|
254
|
+
expect(ab_test(:test_0, {'control' => 100}, {"test-alt" => 1})).to eq 'test-alt'
|
255
|
+
expect(ab_test(:test_0, {'control' => 0}, {"test-alt" => 100})).to eq 'test-alt'
|
256
|
+
end
|
257
|
+
|
246
258
|
it "lets override existing choice" do
|
247
259
|
pending "this requires user store reset on first call not depending on whelther it is current trial"
|
248
260
|
@params = { 'ab_test' => { 'test_1' => 'test-alt' } }
|
@@ -265,33 +277,63 @@ describe Split::Helper do
|
|
265
277
|
end
|
266
278
|
|
267
279
|
describe 'metadata' do
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
:
|
272
|
-
|
273
|
-
|
280
|
+
context 'is defined' do
|
281
|
+
before do
|
282
|
+
Split.configuration.experiments = {
|
283
|
+
:my_experiment => {
|
284
|
+
:alternatives => ["one", "two"],
|
285
|
+
:resettable => false,
|
286
|
+
:metadata => { 'one' => 'Meta1', 'two' => 'Meta2' }
|
287
|
+
}
|
274
288
|
}
|
275
|
-
|
276
|
-
end
|
289
|
+
end
|
277
290
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
291
|
+
it 'should be passed to helper block' do
|
292
|
+
@params = { 'ab_test' => { 'my_experiment' => 'two' } }
|
293
|
+
expect(ab_test('my_experiment')).to eq 'two'
|
294
|
+
expect(ab_test('my_experiment') do |alternative, meta|
|
295
|
+
meta
|
296
|
+
end).to eq('Meta2')
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should pass control metadata helper block if library disabled' do
|
300
|
+
Split.configure do |config|
|
301
|
+
config.enabled = false
|
302
|
+
end
|
303
|
+
|
304
|
+
expect(ab_test('my_experiment')).to eq 'one'
|
305
|
+
expect(ab_test('my_experiment') do |_, meta|
|
306
|
+
meta
|
307
|
+
end).to eq('Meta1')
|
308
|
+
end
|
284
309
|
end
|
285
310
|
|
286
|
-
|
287
|
-
|
288
|
-
|
311
|
+
context 'is not defined' do
|
312
|
+
before do
|
313
|
+
Split.configuration.experiments = {
|
314
|
+
:my_experiment => {
|
315
|
+
:alternatives => ["one", "two"],
|
316
|
+
:resettable => false,
|
317
|
+
:metadata => nil
|
318
|
+
}
|
319
|
+
}
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'should be passed to helper block' do
|
323
|
+
expect(ab_test('my_experiment') do |alternative, meta|
|
324
|
+
meta
|
325
|
+
end).to eq({})
|
289
326
|
end
|
290
327
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
328
|
+
it 'should pass control metadata helper block if library disabled' do
|
329
|
+
Split.configure do |config|
|
330
|
+
config.enabled = false
|
331
|
+
end
|
332
|
+
|
333
|
+
expect(ab_test('my_experiment') do |_, meta|
|
334
|
+
meta
|
335
|
+
end).to eq({})
|
336
|
+
end
|
295
337
|
end
|
296
338
|
end
|
297
339
|
|
@@ -1096,15 +1138,9 @@ describe Split::Helper do
|
|
1096
1138
|
end
|
1097
1139
|
|
1098
1140
|
it "should increment the counter for the specified-goal completed alternative" do
|
1099
|
-
expect(
|
1100
|
-
|
1101
|
-
|
1102
|
-
}).not_to change {
|
1103
|
-
Split::Alternative.new(@alternative_name, @experiment_name).completed_count(@goal2)
|
1104
|
-
}
|
1105
|
-
}).to change {
|
1106
|
-
Split::Alternative.new(@alternative_name, @experiment_name).completed_count(@goal1)
|
1107
|
-
}.by(1)
|
1141
|
+
expect{ ab_finished({"link_color" => ["purchase"]}) }
|
1142
|
+
.to change{ Split::Alternative.new(@alternative_name, @experiment_name).completed_count(@goal2) }.by(0)
|
1143
|
+
.and change{ Split::Alternative.new(@alternative_name, @experiment_name).completed_count(@goal1) }.by(1)
|
1108
1144
|
end
|
1109
1145
|
end
|
1110
1146
|
end
|
@@ -52,7 +52,7 @@ describe Split::Persistence::CookieAdapter do
|
|
52
52
|
it "puts multiple experiments in a single cookie" do
|
53
53
|
subject["foo"] = "FOO"
|
54
54
|
subject["bar"] = "BAR"
|
55
|
-
expect(context.response.headers["Set-Cookie"]).to match(/\Asplit=%7B%22foo%22%3A%22FOO%22%2C%22bar%22%3A%22BAR%22%7D; path=\/; expires=[a-zA-Z]{3}, \d{2} [a-zA-Z]{3} \d{4} \d{2}:\d{2}:\d{2} -
|
55
|
+
expect(context.response.headers["Set-Cookie"]).to match(/\Asplit=%7B%22foo%22%3A%22FOO%22%2C%22bar%22%3A%22BAR%22%7D; path=\/; expires=[a-zA-Z]{3}, \d{2} [a-zA-Z]{3} \d{4} \d{2}:\d{2}:\d{2} [A-Z]{3}\Z/)
|
56
56
|
end
|
57
57
|
|
58
58
|
it "ensure other added cookies are not overriden" do
|
@@ -60,6 +60,15 @@ describe Split::Persistence::RedisAdapter do
|
|
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') }
|
65
|
+
|
66
|
+
it "should create and user from a given key" do
|
67
|
+
adapter = Split::Persistence::RedisAdapter.find(2)
|
68
|
+
expect(adapter.redis_key).to eq("a_namespace:2")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
63
72
|
context 'functional tests' do
|
64
73
|
before { Split::Persistence::RedisAdapter.with_config(:lookup_by => 'lookup') }
|
65
74
|
|
@@ -29,75 +29,6 @@ describe Split::RedisInterface do
|
|
29
29
|
end
|
30
30
|
end
|
31
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
32
|
describe '#add_to_set' do
|
102
33
|
subject(:add_to_set) do
|
103
34
|
interface.add_to_set(set_name, 'something')
|
data/spec/spec_helper.rb
CHANGED
@@ -13,17 +13,16 @@ require 'yaml'
|
|
13
13
|
|
14
14
|
Dir['./spec/support/*.rb'].each { |f| require f }
|
15
15
|
|
16
|
-
require "fakeredis"
|
17
|
-
|
18
|
-
G_fakeredis = Redis.new
|
19
|
-
|
20
16
|
module GlobalSharedContext
|
21
17
|
extend RSpec::SharedContext
|
22
18
|
let(:mock_user){ Split::User.new(double(session: {})) }
|
19
|
+
|
23
20
|
before(:each) do
|
24
21
|
Split.configuration = Split::Configuration.new
|
25
|
-
Split.redis =
|
26
|
-
Split.redis.
|
22
|
+
Split.redis = Redis.new
|
23
|
+
Split.redis.select(10)
|
24
|
+
Split.redis.flushdb
|
25
|
+
Split::Cache.clear
|
27
26
|
@ab_user = mock_user
|
28
27
|
params = nil
|
29
28
|
end
|
data/spec/trial_spec.rb
CHANGED
@@ -198,42 +198,68 @@ describe Split::Trial do
|
|
198
198
|
expect(trial.alternative.name).to_not be_empty
|
199
199
|
Split.configuration.on_trial_choose = nil
|
200
200
|
end
|
201
|
+
|
202
|
+
it "assigns user to an alternative" do
|
203
|
+
trial.choose! context
|
204
|
+
|
205
|
+
expect(alternatives).to include(user[experiment.name])
|
206
|
+
end
|
207
|
+
|
208
|
+
context "when cohorting is disabled" do
|
209
|
+
before(:each) { allow(experiment).to receive(:cohorting_disabled?).and_return(true) }
|
210
|
+
|
211
|
+
it "picks the control and does not run on_trial callbacks" do
|
212
|
+
Split.configuration.on_trial = :on_trial_callback
|
213
|
+
|
214
|
+
expect(experiment).to_not receive(:next_alternative)
|
215
|
+
expect(context).not_to receive(:on_trial_callback)
|
216
|
+
expect_alternative(trial, 'basket')
|
217
|
+
|
218
|
+
Split.configuration.enabled = true
|
219
|
+
Split.configuration.on_trial = nil
|
220
|
+
end
|
221
|
+
|
222
|
+
it "user is not assigned an alternative" do
|
223
|
+
trial.choose! context
|
224
|
+
|
225
|
+
expect(user[experiment]).to eq(nil)
|
226
|
+
end
|
227
|
+
end
|
201
228
|
end
|
202
229
|
end
|
203
230
|
|
204
231
|
describe "#complete!" do
|
205
|
-
let(:trial) { Split::Trial.new(:user => user, :experiment => experiment) }
|
206
232
|
context 'when there are no goals' do
|
233
|
+
let(:trial) { Split::Trial.new(:user => user, :experiment => experiment) }
|
207
234
|
it 'should complete the trial' do
|
208
235
|
trial.choose!
|
209
236
|
old_completed_count = trial.alternative.completed_count
|
210
237
|
trial.complete!
|
211
|
-
expect(trial.alternative.completed_count).to
|
238
|
+
expect(trial.alternative.completed_count).to eq(old_completed_count + 1)
|
212
239
|
end
|
213
240
|
end
|
214
241
|
|
215
|
-
context
|
216
|
-
let(:goals) { [
|
242
|
+
context "when there are many goals" do
|
243
|
+
let(:goals) { [ "goal1", "goal2" ] }
|
217
244
|
let(:trial) { Split::Trial.new(:user => user, :experiment => experiment, :goals => goals) }
|
218
|
-
shared_examples_for "goal completion" do
|
219
|
-
it 'should not complete the trial' do
|
220
|
-
trial.choose!
|
221
|
-
old_completed_count = trial.alternative.completed_count
|
222
|
-
trial.complete!(goal)
|
223
|
-
expect(trial.alternative.completed_count).to_not be(old_completed_count+1)
|
224
|
-
end
|
225
|
-
end
|
226
245
|
|
227
|
-
|
228
|
-
|
229
|
-
|
246
|
+
it "increments the completed count corresponding to the goals" do
|
247
|
+
trial.choose!
|
248
|
+
old_completed_counts = goals.map{ |goal| [goal, trial.alternative.completed_count(goal)] }.to_h
|
249
|
+
trial.complete!
|
250
|
+
goals.each { | goal | expect(trial.alternative.completed_count(goal)).to eq(old_completed_counts[goal] + 1) }
|
230
251
|
end
|
252
|
+
end
|
231
253
|
|
232
|
-
|
233
|
-
|
234
|
-
|
254
|
+
context "when there is 1 goal of type string" do
|
255
|
+
let(:goal) { "goal" }
|
256
|
+
let(:trial) { Split::Trial.new(:user => user, :experiment => experiment, :goals => goal) }
|
257
|
+
it "increments the completed count corresponding to the goal" do
|
258
|
+
trial.choose!
|
259
|
+
old_completed_count = trial.alternative.completed_count(goal)
|
260
|
+
trial.complete!
|
261
|
+
expect(trial.alternative.completed_count(goal)).to eq(old_completed_count + 1)
|
235
262
|
end
|
236
|
-
|
237
263
|
end
|
238
264
|
end
|
239
265
|
|
data/spec/user_spec.rb
CHANGED
@@ -72,6 +72,23 @@ describe Split::User do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
context 'allows user to be loaded from adapter' do
|
76
|
+
it 'loads user from adapter (RedisAdapter)' do
|
77
|
+
user = Split::Persistence::RedisAdapter.new(nil, 112233)
|
78
|
+
user['foo'] = 'bar'
|
79
|
+
|
80
|
+
ab_user = Split::User.find(112233, :redis)
|
81
|
+
|
82
|
+
expect(ab_user['foo']).to eql('bar')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'returns nil if adapter does not implement a finder method' do
|
86
|
+
ab_user = Split::User.find(112233, :dual_adapter)
|
87
|
+
expect(ab_user).to be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
75
92
|
context "instantiated with custom adapter" do
|
76
93
|
let(:custom_adapter) { double(:persistence_adapter) }
|
77
94
|
|
data/split.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
# frozen_string_literal: true
|
3
|
+
|
3
4
|
$:.push File.expand_path("../lib", __FILE__)
|
4
5
|
require "split/version"
|
5
6
|
|
@@ -22,23 +23,22 @@ Gem::Specification.new do |s|
|
|
22
23
|
"mailing_list_uri" => "https://groups.google.com/d/forum/split-ruby"
|
23
24
|
}
|
24
25
|
|
25
|
-
s.required_ruby_version = '>=
|
26
|
+
s.required_ruby_version = '>= 2.5.0'
|
26
27
|
s.required_rubygems_version = '>= 2.0.0'
|
27
28
|
|
28
29
|
s.files = `git ls-files`.split("\n")
|
29
30
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
30
31
|
s.require_paths = ["lib"]
|
31
32
|
|
32
|
-
s.add_dependency 'redis', '>= 2
|
33
|
+
s.add_dependency 'redis', '>= 4.2'
|
33
34
|
s.add_dependency 'sinatra', '>= 1.2.6'
|
34
|
-
s.add_dependency '
|
35
|
+
s.add_dependency 'rubystats', '>= 0.3.0'
|
35
36
|
|
36
37
|
s.add_development_dependency 'bundler', '>= 1.17'
|
37
38
|
s.add_development_dependency 'simplecov', '~> 0.15'
|
38
|
-
s.add_development_dependency 'rack-test', '~>
|
39
|
-
s.add_development_dependency 'rake', '~>
|
39
|
+
s.add_development_dependency 'rack-test', '~> 1.1'
|
40
|
+
s.add_development_dependency 'rake', '~> 13'
|
40
41
|
s.add_development_dependency 'rspec', '~> 3.7'
|
41
42
|
s.add_development_dependency 'pry', '~> 0.10'
|
42
|
-
s.add_development_dependency '
|
43
|
-
s.add_development_dependency 'rails', '>= 4.2'
|
43
|
+
s.add_development_dependency 'rails', '>= 5.0'
|
44
44
|
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:
|
4
|
+
version: 4.0.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Nesbitt
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2
|
19
|
+
version: '4.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2
|
26
|
+
version: '4.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sinatra
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.2.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rubystats
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 0.3.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 0.3.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,28 +86,28 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '1.1'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '1.1'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rake
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '13'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '13'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rspec
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,35 +136,21 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0.10'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: fakeredis
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0.7'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0.7'
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
140
|
name: rails
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
156
142
|
requirements:
|
157
143
|
- - ">="
|
158
144
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
145
|
+
version: '5.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: '
|
167
|
-
description:
|
152
|
+
version: '5.0'
|
153
|
+
description:
|
168
154
|
email:
|
169
155
|
- andrewnez@gmail.com
|
170
156
|
executables: []
|
@@ -175,6 +161,7 @@ files:
|
|
175
161
|
- ".csslintrc"
|
176
162
|
- ".eslintignore"
|
177
163
|
- ".eslintrc"
|
164
|
+
- ".github/FUNDING.yml"
|
178
165
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
179
166
|
- ".gitignore"
|
180
167
|
- ".rspec"
|
@@ -189,7 +176,6 @@ files:
|
|
189
176
|
- LICENSE
|
190
177
|
- README.md
|
191
178
|
- Rakefile
|
192
|
-
- gemfiles/4.2.gemfile
|
193
179
|
- gemfiles/5.0.gemfile
|
194
180
|
- gemfiles/5.1.gemfile
|
195
181
|
- gemfiles/5.2.gemfile
|
@@ -199,6 +185,7 @@ files:
|
|
199
185
|
- lib/split/algorithms/weighted_sample.rb
|
200
186
|
- lib/split/algorithms/whiplash.rb
|
201
187
|
- lib/split/alternative.rb
|
188
|
+
- lib/split/cache.rb
|
202
189
|
- lib/split/combined_experiments_helper.rb
|
203
190
|
- lib/split/configuration.rb
|
204
191
|
- lib/split/dashboard.rb
|
@@ -238,6 +225,7 @@ files:
|
|
238
225
|
- spec/algorithms/weighted_sample_spec.rb
|
239
226
|
- spec/algorithms/whiplash_spec.rb
|
240
227
|
- spec/alternative_spec.rb
|
228
|
+
- spec/cache_spec.rb
|
241
229
|
- spec/combined_experiments_helper_spec.rb
|
242
230
|
- spec/configuration_spec.rb
|
243
231
|
- spec/dashboard/pagination_helpers_spec.rb
|
@@ -272,7 +260,7 @@ metadata:
|
|
272
260
|
bug_tracker_uri: https://github.com/splitrb/split/issues
|
273
261
|
wiki_uri: https://github.com/splitrb/split/wiki
|
274
262
|
mailing_list_uri: https://groups.google.com/d/forum/split-ruby
|
275
|
-
post_install_message:
|
263
|
+
post_install_message:
|
276
264
|
rdoc_options: []
|
277
265
|
require_paths:
|
278
266
|
- lib
|
@@ -280,15 +268,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
280
268
|
requirements:
|
281
269
|
- - ">="
|
282
270
|
- !ruby/object:Gem::Version
|
283
|
-
version:
|
271
|
+
version: 2.5.0
|
284
272
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
285
273
|
requirements:
|
286
274
|
- - ">="
|
287
275
|
- !ruby/object:Gem::Version
|
288
276
|
version: 2.0.0
|
289
277
|
requirements: []
|
290
|
-
rubygems_version: 3.
|
291
|
-
signing_key:
|
278
|
+
rubygems_version: 3.1.4
|
279
|
+
signing_key:
|
292
280
|
specification_version: 4
|
293
281
|
summary: Rack based split testing framework
|
294
282
|
test_files:
|
@@ -296,6 +284,7 @@ test_files:
|
|
296
284
|
- spec/algorithms/weighted_sample_spec.rb
|
297
285
|
- spec/algorithms/whiplash_spec.rb
|
298
286
|
- spec/alternative_spec.rb
|
287
|
+
- spec/cache_spec.rb
|
299
288
|
- spec/combined_experiments_helper_spec.rb
|
300
289
|
- spec/configuration_spec.rb
|
301
290
|
- spec/dashboard/pagination_helpers_spec.rb
|