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 CHANGED
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
+ bundler_args: ''
2
3
  rvm:
3
4
  - 1.8.7
4
5
  - 1.9.2
@@ -13,6 +14,8 @@ rvm:
13
14
  matrix:
14
15
  allow_failures:
15
16
  - rvm: ruby-head
17
+ - rvm: rbx-18mode
18
+ - rvm: rbx-19mode
16
19
  exclude:
17
20
  - rvm: 1.8.7
18
21
  gemfile: gemfiles/4.0.gemfile
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 instead of redis
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.completed_count)
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
@@ -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
@@ -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
- if (agree)
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
- if (agree)
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
- if (agree)
20
- return true;
21
- else
22
- return false;
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
  }
@@ -75,6 +75,14 @@ body {
75
75
  color: #fff;
76
76
  }
77
77
 
78
+ .header p.environment {
79
+ clear: both;
80
+ padding: 10px 0 0 0;
81
+ color: #BBB;
82
+ font-style: italic;
83
+ float: right;
84
+ }
85
+
78
86
  #main {
79
87
  padding: 10px 5%;
80
88
  background: #f9f9f9;
@@ -11,6 +11,7 @@
11
11
  <body>
12
12
  <div class="header">
13
13
  <h1>Split Dashboard</h1>
14
+ <p class="environment"><%= @current_env %></p>
14
15
  </div>
15
16
 
16
17
  <div id="main">
@@ -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
@@ -1,6 +1,6 @@
1
1
  module Split
2
2
  MAJOR = 0
3
3
  MINOR = 6
4
- PATCH = 3
4
+ PATCH = 4
5
5
  VERSION = [MAJOR, MINOR, PATCH].join('.')
6
6
  end
@@ -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.3
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-07-08 00:00:00.000000000 Z
12
+ date: 2013-08-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis