split 1.4.4 → 1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +10 -2
- data/lib/split/configuration.rb +22 -28
- data/lib/split/experiment.rb +23 -20
- data/lib/split/trial.rb +9 -6
- data/lib/split/user.rb +6 -1
- data/lib/split/version.rb +1 -1
- data/spec/user_spec.rb +16 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c048eebd0c41a821d257be6a6ee61175df3d413
|
4
|
+
data.tar.gz: 1585aa44b15a8ba0258f545f84a880d06b1b58fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d65b2592b5c29c53da81491234d00264444a5261bcb354eed72914aa3b6e9faf9b9b9a533412895899d54dffb93b9483b6943318b53771a257faf71518860361
|
7
|
+
data.tar.gz: 856c23b850dee54c658c73cca8bb6b5f02220f5c44d394bb2281c4d948eeb7529773867fa1403ca6b20122c2a032c405378faa1baac7dff8eaf6e9f64e153066
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 1.4.5 (June 7th, 2016)
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- FIX Negative numbers on non-finished (@divineforest, #408)
|
6
|
+
- Eliminate extra RedisAdapter hget (@karmakaze, #407)
|
7
|
+
- Remove unecessary code from Experiment class (@pakallis, #391, #392, #393)
|
8
|
+
|
9
|
+
Misc:
|
10
|
+
|
11
|
+
- Simplify Configuration#normalized_experiments (@pakallis, #395)
|
12
|
+
- Clarify test running instructions (@henrik, #397)
|
13
|
+
|
1
14
|
## 1.4.4 (May 9th, 2016)
|
2
15
|
|
3
16
|
Bugfixes:
|
data/README.md
CHANGED
@@ -700,11 +700,19 @@ Over 70 different people have contributed to the project, you can see them all h
|
|
700
700
|
|
701
701
|
## Development
|
702
702
|
|
703
|
+
Run the tests like this:
|
704
|
+
|
705
|
+
# Start a Redis server in another tab.
|
706
|
+
redis-server
|
707
|
+
|
708
|
+
bundle
|
709
|
+
rake spec
|
710
|
+
|
703
711
|
Source hosted at [GitHub](http://github.com/splitrb/split).
|
712
|
+
|
704
713
|
Report Issues/Feature requests on [GitHub Issues](http://github.com/splitrb/split/issues).
|
705
|
-
Discussion at [Google Groups](https://groups.google.com/d/forum/split-ruby)
|
706
714
|
|
707
|
-
|
715
|
+
Discussion at [Google Groups](https://groups.google.com/d/forum/split-ruby).
|
708
716
|
|
709
717
|
### Note on Patches/Pull Requests
|
710
718
|
|
data/lib/split/configuration.rb
CHANGED
@@ -130,38 +130,32 @@ module Split
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def normalized_experiments
|
133
|
-
if @experiments.nil?
|
134
|
-
nil
|
135
|
-
else
|
136
|
-
experiment_config = {}
|
137
|
-
@experiments.keys.each do |name|
|
138
|
-
experiment_config[name.to_sym] = {}
|
139
|
-
end
|
140
|
-
|
141
|
-
@experiments.each do |experiment_name, settings|
|
142
|
-
if alternatives = value_for(settings, :alternatives)
|
143
|
-
experiment_config[experiment_name.to_sym][:alternatives] = normalize_alternatives(alternatives)
|
144
|
-
end
|
133
|
+
return nil if @experiments.nil?
|
145
134
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
if metadata = value_for(settings, :metadata)
|
151
|
-
experiment_config[experiment_name.to_sym][:metadata] = metadata
|
152
|
-
end
|
153
|
-
|
154
|
-
if algorithm = value_for(settings, :algorithm)
|
155
|
-
experiment_config[experiment_name.to_sym][:algorithm] = algorithm
|
156
|
-
end
|
135
|
+
experiment_config = {}
|
136
|
+
@experiments.keys.each do |name|
|
137
|
+
experiment_config[name.to_sym] = {}
|
138
|
+
end
|
157
139
|
|
158
|
-
|
159
|
-
|
160
|
-
|
140
|
+
@experiments.each do |experiment_name, settings|
|
141
|
+
alternatives = if (alts = value_for(settings, :alternatives))
|
142
|
+
normalize_alternatives(alts)
|
143
|
+
end
|
144
|
+
|
145
|
+
experiment_data = {
|
146
|
+
alternatives: alternatives,
|
147
|
+
goals: value_for(settings, :goals),
|
148
|
+
metadata: value_for(settings, :metadata),
|
149
|
+
algorithm: value_for(settings, :algorithm),
|
150
|
+
resettable: value_for(settings, :resettable)
|
151
|
+
}
|
152
|
+
|
153
|
+
experiment_data.each do |name, value|
|
154
|
+
experiment_config[experiment_name.to_sym][name] = value if value != nil
|
161
155
|
end
|
162
|
-
|
163
|
-
experiment_config
|
164
156
|
end
|
157
|
+
|
158
|
+
experiment_config
|
165
159
|
end
|
166
160
|
|
167
161
|
def normalize_alternatives(alternatives)
|
data/lib/split/experiment.rb
CHANGED
@@ -21,22 +21,22 @@ module Split
|
|
21
21
|
alternatives = extract_alternatives_from_options(options)
|
22
22
|
|
23
23
|
if alternatives.empty? && (exp_config = Split.configuration.experiment_for(name))
|
24
|
-
|
24
|
+
options = {
|
25
25
|
alternatives: load_alternatives_from_configuration,
|
26
26
|
goals: Split::GoalsCollection.new(@name).load_from_configuration,
|
27
27
|
metadata: load_metadata_from_configuration,
|
28
28
|
resettable: exp_config[:resettable],
|
29
29
|
algorithm: exp_config[:algorithm]
|
30
|
-
|
30
|
+
}
|
31
31
|
else
|
32
|
-
|
33
|
-
alternatives: alternatives,
|
34
|
-
goals: options[:goals],
|
35
|
-
metadata: options[:metadata],
|
36
|
-
resettable: options[:resettable],
|
37
|
-
algorithm: options[:algorithm]
|
38
|
-
)
|
32
|
+
options[:alternatives] = alternatives
|
39
33
|
end
|
34
|
+
|
35
|
+
set_alternatives_and_options(options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.finished_key(key)
|
39
|
+
"#{key}:finished"
|
40
40
|
end
|
41
41
|
|
42
42
|
def set_alternatives_and_options(options)
|
@@ -67,10 +67,9 @@ module Split
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
self.resettable = options[:resettable]
|
70
|
+
options[:alternatives] = alts
|
71
|
+
|
72
|
+
set_alternatives_and_options(options)
|
74
73
|
|
75
74
|
# calculate probability that each alternative is the winner
|
76
75
|
@alternative_probabilities = {}
|
@@ -86,7 +85,6 @@ module Split
|
|
86
85
|
@alternatives.reverse.each {|a| Split.redis.lpush(name, a.name)}
|
87
86
|
goals_collection.save
|
88
87
|
save_metadata
|
89
|
-
Split.redis.set(metadata_key, @metadata.to_json) unless @metadata.nil?
|
90
88
|
else
|
91
89
|
existing_alternatives = load_alternatives_from_redis
|
92
90
|
existing_goals = Split::GoalsCollection.new(@name).load_from_redis
|
@@ -227,7 +225,7 @@ module Split
|
|
227
225
|
end
|
228
226
|
|
229
227
|
def finished_key
|
230
|
-
|
228
|
+
self.class.finished_key(key)
|
231
229
|
end
|
232
230
|
|
233
231
|
def metadata_key
|
@@ -267,11 +265,16 @@ module Split
|
|
267
265
|
|
268
266
|
def load_from_redis
|
269
267
|
exp_config = Split.redis.hgetall(experiment_config_key)
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
268
|
+
|
269
|
+
options = {
|
270
|
+
resettable: exp_config['resettable'],
|
271
|
+
algorithm: exp_config['algorithm'],
|
272
|
+
alternatives: load_alternatives_from_redis,
|
273
|
+
goals: Split::GoalsCollection.new(@name).load_from_redis,
|
274
|
+
metadata: load_metadata_from_redis
|
275
|
+
}
|
276
|
+
|
277
|
+
set_alternatives_and_options(options)
|
275
278
|
end
|
276
279
|
|
277
280
|
def calc_winning_alternatives
|
data/lib/split/trial.rb
CHANGED
@@ -67,15 +67,18 @@ module Split
|
|
67
67
|
|
68
68
|
if exclude_user?
|
69
69
|
self.alternative = @experiment.control
|
70
|
-
elsif @user[@experiment.key]
|
71
|
-
self.alternative = @user[@experiment.key]
|
72
70
|
else
|
73
|
-
|
71
|
+
value = @user[@experiment.key]
|
72
|
+
if value
|
73
|
+
self.alternative = value
|
74
|
+
else
|
75
|
+
self.alternative = @experiment.next_alternative
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
+
# Increment the number of participants since we are actually choosing a new alternative
|
78
|
+
self.alternative.increment_participation
|
77
79
|
|
78
|
-
|
80
|
+
run_callback context, Split.configuration.on_trial_choose
|
81
|
+
end
|
79
82
|
end
|
80
83
|
end
|
81
84
|
|
data/lib/split/user.rb
CHANGED
@@ -9,10 +9,11 @@ module Split
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def cleanup_old_experiments!
|
12
|
-
user.keys.each do |key|
|
12
|
+
keys_without_finished(user.keys).each do |key|
|
13
13
|
experiment = ExperimentCatalog.find key_without_version(key)
|
14
14
|
if experiment.nil? || experiment.has_winner? || experiment.start_time.nil?
|
15
15
|
user.delete key
|
16
|
+
user.delete Experiment.finished_key(key)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
@@ -45,6 +46,10 @@ module Split
|
|
45
46
|
keys.reject { |k| k.match(Regexp.new("^#{experiment_key}(:finished)?$")) }
|
46
47
|
end
|
47
48
|
|
49
|
+
def keys_without_finished(keys)
|
50
|
+
keys.reject { |k| k.include?(":finished") }
|
51
|
+
end
|
52
|
+
|
48
53
|
def key_without_version(key)
|
49
54
|
key.split(/\:\d(?!\:)/)[0]
|
50
55
|
end
|
data/lib/split/version.rb
CHANGED
data/spec/user_spec.rb
CHANGED
@@ -44,6 +44,20 @@ describe Split::User do
|
|
44
44
|
allow(experiment).to receive(:has_winner?).and_return(false)
|
45
45
|
@subject.cleanup_old_experiments!
|
46
46
|
expect(@subject.keys).to be_empty
|
47
|
-
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with finished key' do
|
50
|
+
let(:user_keys) { { 'link_color' => 'blue', 'link_color:finished' => true } }
|
51
|
+
|
52
|
+
it 'does not remove finished key for experiment without a winner' do
|
53
|
+
allow(Split::ExperimentCatalog).to receive(:find).with('link_color').and_return(experiment)
|
54
|
+
allow(Split::ExperimentCatalog).to receive(:find).with('link_color:finished').and_return(nil)
|
55
|
+
allow(experiment).to receive(:start_time).and_return(Date.today)
|
56
|
+
allow(experiment).to receive(:has_winner?).and_return(false)
|
57
|
+
@subject.cleanup_old_experiments!
|
58
|
+
expect(@subject.keys).to include("link_color")
|
59
|
+
expect(@subject.keys).to include("link_color:finished")
|
60
|
+
end
|
61
|
+
end
|
48
62
|
end
|
49
|
-
end
|
63
|
+
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: 1.4.
|
4
|
+
version: 1.4.5
|
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-
|
11
|
+
date: 2016-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -272,3 +272,4 @@ test_files:
|
|
272
272
|
- spec/support/cookies_mock.rb
|
273
273
|
- spec/trial_spec.rb
|
274
274
|
- spec/user_spec.rb
|
275
|
+
has_rdoc:
|