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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3272611f8e1b67b852c92022c86d10c79d60adfa
4
- data.tar.gz: 560dc5662f892e2dd5909c1d1588954bedf11feb
3
+ metadata.gz: 1c048eebd0c41a821d257be6a6ee61175df3d413
4
+ data.tar.gz: 1585aa44b15a8ba0258f545f84a880d06b1b58fc
5
5
  SHA512:
6
- metadata.gz: 17cdb89c56142fccc390986303f156d1a71a6c65e1e2759c1ad96394dc8620ccf2515e9d3ecc8fad0f6db7503381c5cb056ac985b2ba235d6130a171f7d82441
7
- data.tar.gz: 330ae49fc82430ec36f810f6b07e0a6b78802f9610b531d86995955284e4252fcc37d7d7ed63c69056f6a4c069d125492ceab2f40183ae11864b00a15cf86a4f
6
+ metadata.gz: d65b2592b5c29c53da81491234d00264444a5261bcb354eed72914aa3b6e9faf9b9b9a533412895899d54dffb93b9483b6943318b53771a257faf71518860361
7
+ data.tar.gz: 856c23b850dee54c658c73cca8bb6b5f02220f5c44d394bb2281c4d948eeb7529773867fa1403ca6b20122c2a032c405378faa1baac7dff8eaf6e9f64e153066
@@ -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
- Tests can be ran with `rake spec`
715
+ Discussion at [Google Groups](https://groups.google.com/d/forum/split-ruby).
708
716
 
709
717
  ### Note on Patches/Pull Requests
710
718
 
@@ -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
- if goals = value_for(settings, :goals)
147
- experiment_config[experiment_name.to_sym][:goals] = goals
148
- end
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
- if (resettable = value_for(settings, :resettable)) != nil
159
- experiment_config[experiment_name.to_sym][:resettable] = resettable
160
- end
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)
@@ -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
- set_alternatives_and_options(
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
- set_alternatives_and_options(
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
- self.alternatives = alts
71
- self.goals = options[:goals]
72
- self.algorithm = options[:algorithm]
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
- "#{key}:finished"
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
- self.resettable = exp_config['resettable']
271
- self.algorithm = exp_config['algorithm']
272
- self.alternatives = load_alternatives_from_redis
273
- self.goals = Split::GoalsCollection.new(@name).load_from_redis
274
- self.metadata = load_metadata_from_redis
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
@@ -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
- self.alternative = @experiment.next_alternative
71
+ value = @user[@experiment.key]
72
+ if value
73
+ self.alternative = value
74
+ else
75
+ self.alternative = @experiment.next_alternative
74
76
 
75
- # Increment the number of participants since we are actually choosing a new alternative
76
- self.alternative.increment_participation
77
+ # Increment the number of participants since we are actually choosing a new alternative
78
+ self.alternative.increment_participation
77
79
 
78
- run_callback context, Split.configuration.on_trial_choose
80
+ run_callback context, Split.configuration.on_trial_choose
81
+ end
79
82
  end
80
83
  end
81
84
 
@@ -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
@@ -2,6 +2,6 @@
2
2
  module Split
3
3
  MAJOR = 1
4
4
  MINOR = 4
5
- PATCH = 4
5
+ PATCH = 5
6
6
  VERSION = [MAJOR, MINOR, PATCH].join('.')
7
7
  end
@@ -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
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-05-09 00:00:00.000000000 Z
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: