split 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +3 -0
- data/CHANGELOG.mdown +16 -0
- data/README.mdown +14 -1
- data/lib/split/algorithms/whiplash.rb +6 -6
- data/lib/split/configuration.rb +4 -0
- data/lib/split/dashboard.rb +6 -0
- data/lib/split/dashboard/public/dashboard.js +11 -15
- data/lib/split/dashboard/public/style.css +8 -0
- data/lib/split/dashboard/views/layout.erb +1 -0
- data/lib/split/experiment.rb +2 -0
- data/lib/split/helper.rb +2 -2
- data/lib/split/version.rb +1 -1
- data/spec/experiment_spec.rb +10 -0
- metadata +2 -2
data/.travis.yml
CHANGED
data/CHANGELOG.mdown
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
## 0.6.4 (August 8, 2013)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Add hooks for experiment deletion and resetting (@craigmcnamara, #198)
|
6
|
+
- Allow Split::Helper to be used outside of a controller (@nfm, #190)
|
7
|
+
- Show current Rails/Rack Env in dashboard (@rceee, #187)
|
8
|
+
|
9
|
+
Bugfixes:
|
10
|
+
|
11
|
+
- Fix whiplash algorithm when using goals (@swrobel, #193)
|
12
|
+
|
13
|
+
Misc:
|
14
|
+
|
15
|
+
- Refactor dashboard js (@buddhamagnet)
|
16
|
+
|
1
17
|
## 0.6.3 (July 8, 2013)
|
2
18
|
|
3
19
|
Features:
|
data/README.mdown
CHANGED
@@ -247,6 +247,19 @@ def log_trial_complete(trial)
|
|
247
247
|
end
|
248
248
|
```
|
249
249
|
|
250
|
+
### Experiment Hooks
|
251
|
+
|
252
|
+
You can assign a proc that will be called when an experiment is reset or deleted. You can use these hooks to call methods within your application to keep data related to experiments in sync with Split.
|
253
|
+
|
254
|
+
For example:
|
255
|
+
|
256
|
+
``` ruby
|
257
|
+
Split.configure do |config|
|
258
|
+
config.on_experiment_reset = proc{ |experiment| # Do something on reset }
|
259
|
+
config.on_experiment_delete = proc{ |experiment| # Do something else on delete }
|
260
|
+
end
|
261
|
+
```
|
262
|
+
|
250
263
|
## Web Interface
|
251
264
|
|
252
265
|
Split comes with a Sinatra-based front end to get an overview of how your experiments are doing.
|
@@ -551,7 +564,7 @@ Users may also write their own algorithms. The default algorithm may be specifie
|
|
551
564
|
|
552
565
|
- [Split::Export](http://github.com/andrew/split-export) - easily export ab test data out of Split
|
553
566
|
- [Split::Analytics](http://github.com/andrew/split-analytics) - push test data to google analytics
|
554
|
-
- [Split::Mongoid](https://github.com/MongoHQ/split-mongoid) - store data in mongoid
|
567
|
+
- [Split::Mongoid](https://github.com/MongoHQ/split-mongoid) - store experiment data in mongoid (still uses redis)
|
555
568
|
|
556
569
|
## Screencast
|
557
570
|
|
@@ -10,26 +10,26 @@ module Split
|
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
13
|
-
|
13
|
+
|
14
14
|
def self.arm_guess(participants, completions)
|
15
15
|
a = [participants, 0].max
|
16
16
|
b = [participants-completions, 0].max
|
17
17
|
s = SimpleRandom.new; s.set_seed; s.beta(a+fairness_constant, b+fairness_constant)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def self.best_guess(alternatives)
|
21
21
|
guesses = {}
|
22
|
-
alternatives.each do |alternative|
|
23
|
-
guesses[alternative.name] = arm_guess(alternative.participant_count, alternative.
|
22
|
+
alternatives.each do |alternative|
|
23
|
+
guesses[alternative.name] = arm_guess(alternative.participant_count, alternative.all_completed_count)
|
24
24
|
end
|
25
25
|
gmax = guesses.values.max
|
26
26
|
best = guesses.keys.select {|name| guesses[name] == gmax }
|
27
27
|
return best.sample
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def self.fairness_constant
|
31
31
|
7
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
data/lib/split/configuration.rb
CHANGED
@@ -14,6 +14,8 @@ module Split
|
|
14
14
|
attr_accessor :store_override
|
15
15
|
attr_accessor :on_trial_choose
|
16
16
|
attr_accessor :on_trial_complete
|
17
|
+
attr_accessor :on_experiment_reset
|
18
|
+
attr_accessor :on_experiment_delete
|
17
19
|
|
18
20
|
attr_reader :experiments
|
19
21
|
|
@@ -161,6 +163,8 @@ module Split
|
|
161
163
|
@ignore_filter = proc{ |request| is_robot? || is_ignored_ip_address? }
|
162
164
|
@db_failover = false
|
163
165
|
@db_failover_on_db_error = proc{|error|} # e.g. use Rails logger here
|
166
|
+
@on_experiment_reset = proc{|experiment|}
|
167
|
+
@on_experiment_delete = proc{|experiment|}
|
164
168
|
@db_failover_allow_parameter_override = false
|
165
169
|
@allow_multiple_experiments = false
|
166
170
|
@enabled = true
|
data/lib/split/dashboard.rb
CHANGED
@@ -16,6 +16,12 @@ module Split
|
|
16
16
|
|
17
17
|
get '/' do
|
18
18
|
@experiments = Split::Experiment.all
|
19
|
+
# Display Rails Environment mode (or Rack version if not using Rails)
|
20
|
+
if Object.const_defined?('Rails')
|
21
|
+
@current_env = Rails.env.titlecase
|
22
|
+
else
|
23
|
+
@current_env = "Rack: #{Rack.version}"
|
24
|
+
end
|
19
25
|
erb :index
|
20
26
|
end
|
21
27
|
|
@@ -1,23 +1,19 @@
|
|
1
1
|
function confirmReset() {
|
2
|
-
var agree=confirm("This will delete all data for this experiment?");
|
3
|
-
|
4
|
-
return true;
|
5
|
-
else
|
6
|
-
return false;
|
2
|
+
var agree = confirm("This will delete all data for this experiment?");
|
3
|
+
return agree ? true : false;
|
7
4
|
}
|
8
5
|
|
9
6
|
function confirmDelete() {
|
10
|
-
var agree=confirm("Are you sure you want to delete this experiment and all its data?");
|
11
|
-
|
12
|
-
return true;
|
13
|
-
else
|
14
|
-
return false;
|
7
|
+
var agree = confirm("Are you sure you want to delete this experiment and all its data?");
|
8
|
+
return agree ? true : false;
|
15
9
|
}
|
16
10
|
|
17
11
|
function confirmWinner() {
|
18
|
-
var agree=confirm("This will now be returned for all users. Are you sure?");
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
var agree = confirm("This will now be returned for all users. Are you sure?");
|
13
|
+
return agree ? true : false;
|
14
|
+
}
|
15
|
+
|
16
|
+
function confirmStep(step) {
|
17
|
+
var agree = confirm(step);
|
18
|
+
return agree ? true : false;
|
23
19
|
}
|
data/lib/split/experiment.rb
CHANGED
@@ -210,6 +210,7 @@ module Split
|
|
210
210
|
def reset
|
211
211
|
alternatives.each(&:reset)
|
212
212
|
reset_winner
|
213
|
+
Split.configuration.on_experiment_reset.call(self)
|
213
214
|
increment_version
|
214
215
|
end
|
215
216
|
|
@@ -219,6 +220,7 @@ module Split
|
|
219
220
|
Split.redis.srem(:experiments, name)
|
220
221
|
Split.redis.del(name)
|
221
222
|
delete_goals
|
223
|
+
Split.configuration.on_experiment_delete.call(self)
|
222
224
|
increment_version
|
223
225
|
end
|
224
226
|
|
data/lib/split/helper.rb
CHANGED
@@ -135,14 +135,14 @@ module Split
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def is_robot?
|
138
|
-
request.user_agent =~ Split.configuration.robot_regex
|
138
|
+
defined?(request) && request.user_agent =~ Split.configuration.robot_regex
|
139
139
|
end
|
140
140
|
|
141
141
|
def is_ignored_ip_address?
|
142
142
|
return false if Split.configuration.ignore_ip_addresses.empty?
|
143
143
|
|
144
144
|
Split.configuration.ignore_ip_addresses.each do |ip|
|
145
|
-
return true if request.ip == ip || (ip.class == Regexp && request.ip =~ ip)
|
145
|
+
return true if defined?(request) && (request.ip == ip || (ip.class == Regexp && request.ip =~ ip))
|
146
146
|
end
|
147
147
|
false
|
148
148
|
end
|
data/lib/split/version.rb
CHANGED
data/spec/experiment_spec.rb
CHANGED
@@ -174,6 +174,11 @@ describe Split::Experiment do
|
|
174
174
|
experiment.delete
|
175
175
|
experiment.version.should eql(1)
|
176
176
|
end
|
177
|
+
|
178
|
+
it "should call the on_experiment_delete hook" do
|
179
|
+
expect(Split.configuration.on_experiment_delete).to receive(:call)
|
180
|
+
experiment.delete
|
181
|
+
end
|
177
182
|
end
|
178
183
|
|
179
184
|
|
@@ -219,6 +224,11 @@ describe Split::Experiment do
|
|
219
224
|
experiment.reset
|
220
225
|
experiment.version.should eql(1)
|
221
226
|
end
|
227
|
+
|
228
|
+
it "should call the on_experiment_reset hook" do
|
229
|
+
expect(Split.configuration.on_experiment_reset).to receive(:call)
|
230
|
+
experiment.reset
|
231
|
+
end
|
222
232
|
end
|
223
233
|
|
224
234
|
describe 'algorithm' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: split
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|