vanity 2.0.0.beta7 → 2.0.0.beta8
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +8 -14
- data/Appraisals +4 -3
- data/Gemfile +12 -4
- data/Gemfile.lock +76 -24
- data/README.rdoc +20 -2
- data/Rakefile +8 -8
- data/gemfiles/rails32.gemfile +19 -10
- data/gemfiles/rails32.gemfile.lock +136 -81
- data/gemfiles/rails4.gemfile +17 -9
- data/gemfiles/rails4.gemfile.lock +18 -11
- data/gemfiles/rails41.gemfile +17 -9
- data/gemfiles/rails41.gemfile.lock +62 -31
- data/gemfiles/rails42.gemfile +17 -9
- data/gemfiles/rails42.gemfile.lock +32 -19
- data/lib/vanity/experiment/ab_test.rb +12 -20
- data/lib/vanity/version.rb +1 -1
- data/test/cli_test.rb +15 -13
- data/test/experiment/ab_test.rb +37 -2
- data/test/helper_test.rb +13 -3
- data/test/test_helper.rb +1 -6
- metadata +3 -3
@@ -7,13 +7,14 @@ GIT
|
|
7
7
|
PATH
|
8
8
|
remote: ..
|
9
9
|
specs:
|
10
|
-
vanity (2.0.0.
|
10
|
+
vanity (2.0.0.beta8)
|
11
11
|
i18n
|
12
12
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
16
|
RedCloth (4.2.9)
|
17
|
+
RedCloth (4.2.9-java)
|
17
18
|
actionmailer (4.2.0)
|
18
19
|
actionpack (= 4.2.0)
|
19
20
|
actionview (= 4.2.0)
|
@@ -43,6 +44,8 @@ GEM
|
|
43
44
|
activemodel (= 4.2.0)
|
44
45
|
activesupport (= 4.2.0)
|
45
46
|
arel (~> 6.0)
|
47
|
+
activerecord-jdbc-adapter (1.3.15)
|
48
|
+
activerecord (>= 2.2)
|
46
49
|
activesupport (4.2.0)
|
47
50
|
i18n (~> 0.7)
|
48
51
|
json (~> 1.7, >= 1.7.7)
|
@@ -57,6 +60,7 @@ GEM
|
|
57
60
|
arel (6.0.0)
|
58
61
|
blankslate (2.1.2.4)
|
59
62
|
bson (1.10.0)
|
63
|
+
bson (1.10.0-java)
|
60
64
|
bson_ext (1.10.0)
|
61
65
|
bson (~> 1.10.0)
|
62
66
|
builder (3.2.2)
|
@@ -64,18 +68,18 @@ GEM
|
|
64
68
|
timers (~> 4.0.0)
|
65
69
|
classifier-reborn (2.0.3)
|
66
70
|
fast-stemmer (~> 1.0)
|
67
|
-
coffee-script (2.
|
71
|
+
coffee-script (2.4.1)
|
68
72
|
coffee-script-source
|
69
73
|
execjs
|
70
|
-
coffee-script-source (1.
|
74
|
+
coffee-script-source (1.9.1)
|
71
75
|
colorator (0.1)
|
72
76
|
crack (0.4.2)
|
73
77
|
safe_yaml (~> 1.0.0)
|
74
78
|
daemon_controller (1.2.0)
|
75
79
|
erubis (2.7.0)
|
76
|
-
execjs (2.
|
80
|
+
execjs (2.5.2)
|
77
81
|
fast-stemmer (1.0.2)
|
78
|
-
ffi (1.9.
|
82
|
+
ffi (1.9.8)
|
79
83
|
garb (0.9.1)
|
80
84
|
activesupport (>= 2.2.0)
|
81
85
|
crack (>= 0.1.6)
|
@@ -85,6 +89,7 @@ GEM
|
|
85
89
|
hitimes (1.2.2)
|
86
90
|
i18n (0.7.0)
|
87
91
|
integration (0.1.0)
|
92
|
+
jdbc-sqlite3 (3.8.7)
|
88
93
|
jekyll (2.5.3)
|
89
94
|
classifier-reborn (~> 2.0)
|
90
95
|
colorator (~> 0.1)
|
@@ -102,17 +107,18 @@ GEM
|
|
102
107
|
toml (~> 0.1.0)
|
103
108
|
jekyll-coffeescript (1.0.1)
|
104
109
|
coffee-script (~> 2.2)
|
105
|
-
jekyll-gist (1.1
|
110
|
+
jekyll-gist (1.2.1)
|
106
111
|
jekyll-paginate (1.1.0)
|
107
112
|
jekyll-sass-converter (1.3.0)
|
108
113
|
sass (~> 3.2)
|
109
|
-
jekyll-watch (1.2.
|
114
|
+
jekyll-watch (1.2.1)
|
110
115
|
listen (~> 2.7)
|
111
116
|
json (1.8.2)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
117
|
+
json (1.8.2-java)
|
118
|
+
kramdown (1.6.0)
|
119
|
+
liquid (2.6.2)
|
120
|
+
listen (2.10.0)
|
121
|
+
celluloid (~> 0.16.0)
|
116
122
|
rb-fsevent (>= 0.9.3)
|
117
123
|
rb-inotify (>= 0.9)
|
118
124
|
loofah (2.0.1)
|
@@ -128,9 +134,12 @@ GEM
|
|
128
134
|
metaclass (~> 0.0.1)
|
129
135
|
mongo (1.10.0)
|
130
136
|
bson (~> 1.10.0)
|
137
|
+
mongo (1.10.0-java)
|
138
|
+
bson (~> 1.10.0)
|
131
139
|
multi_json (1.10.1)
|
132
140
|
nokogiri (1.6.5)
|
133
141
|
mini_portile (~> 0.6.0)
|
142
|
+
nokogiri (1.6.5-java)
|
134
143
|
parslet (1.5.0)
|
135
144
|
blankslate (~> 2.0)
|
136
145
|
passenger (3.0.21)
|
@@ -138,10 +147,10 @@ GEM
|
|
138
147
|
fastthread (>= 1.0.1)
|
139
148
|
rack
|
140
149
|
rake (>= 0.8.1)
|
141
|
-
posix-spawn (0.3.
|
142
|
-
pygments.rb (0.6.
|
150
|
+
posix-spawn (0.3.11)
|
151
|
+
pygments.rb (0.6.3)
|
143
152
|
posix-spawn (~> 0.3.6)
|
144
|
-
yajl-ruby (~> 1.
|
153
|
+
yajl-ruby (~> 1.2.0)
|
145
154
|
rack (1.6.0)
|
146
155
|
rack-test (0.6.3)
|
147
156
|
rack (>= 1.0)
|
@@ -173,13 +182,13 @@ GEM
|
|
173
182
|
rb-fsevent (0.9.4)
|
174
183
|
rb-inotify (0.9.5)
|
175
184
|
ffi (>= 0.5.0)
|
176
|
-
redcarpet (3.2.
|
185
|
+
redcarpet (3.2.3)
|
177
186
|
redis (3.2.0)
|
178
187
|
redis-namespace (1.5.1)
|
179
188
|
redis (~> 3.0, >= 3.0.4)
|
180
189
|
rubystats (0.2.3)
|
181
190
|
safe_yaml (1.0.4)
|
182
|
-
sass (3.4.
|
191
|
+
sass (3.4.13)
|
183
192
|
sprockets (2.12.3)
|
184
193
|
hike (~> 1.2)
|
185
194
|
multi_json (~> 1.0)
|
@@ -192,6 +201,7 @@ GEM
|
|
192
201
|
sqlite3 (1.3.10)
|
193
202
|
thor (0.19.1)
|
194
203
|
thread_safe (0.3.4)
|
204
|
+
thread_safe (0.3.4-java)
|
195
205
|
tilt (1.4.1)
|
196
206
|
timecop (0.7.1)
|
197
207
|
timers (4.0.1)
|
@@ -203,20 +213,23 @@ GEM
|
|
203
213
|
webmock (1.20.4)
|
204
214
|
addressable (>= 2.3.6)
|
205
215
|
crack (>= 0.3.2)
|
206
|
-
yajl-ruby (1.1
|
216
|
+
yajl-ruby (1.2.1)
|
207
217
|
yard (0.8.7.6)
|
208
218
|
|
209
219
|
PLATFORMS
|
220
|
+
java
|
210
221
|
ruby
|
211
222
|
|
212
223
|
DEPENDENCIES
|
213
224
|
RedCloth
|
214
|
-
|
225
|
+
activerecord-jdbc-adapter
|
226
|
+
appraisal (~> 1.0.2)
|
215
227
|
bson_ext
|
216
228
|
bundler (>= 1.0.0)
|
217
229
|
fastthread!
|
218
230
|
garb (< 0.9.2)
|
219
231
|
integration (<= 0.1.0)
|
232
|
+
jdbc-sqlite3
|
220
233
|
jekyll
|
221
234
|
minitest (>= 4.2)
|
222
235
|
mocha (~> 1.0)
|
@@ -228,7 +241,7 @@ DEPENDENCIES
|
|
228
241
|
redis (>= 2.1)
|
229
242
|
redis-namespace (>= 1.1.0)
|
230
243
|
rubystats
|
231
|
-
sqlite3
|
244
|
+
sqlite3 (~> 1.3.10)
|
232
245
|
timecop
|
233
246
|
vanity!
|
234
247
|
webmock
|
@@ -59,22 +59,12 @@ module Vanity
|
|
59
59
|
# alts = experiment(:background_color).alternatives
|
60
60
|
# puts "#{alts.count} alternatives, with the colors: #{alts.map(&:value).join(", ")}"
|
61
61
|
def alternatives(*args)
|
62
|
-
@alternatives
|
63
|
-
|
64
|
-
|
62
|
+
@alternatives ||= args.empty? ? [true, false] : args.clone
|
63
|
+
@alternatives.each_with_index.map do |value, i|
|
64
|
+
Alternative.new(self, i, value)
|
65
65
|
end
|
66
|
-
nil
|
67
66
|
end
|
68
67
|
|
69
|
-
def _alternatives
|
70
|
-
alts = []
|
71
|
-
@alternatives.each_with_index do |value, i|
|
72
|
-
alts << Alternative.new(self, i, value)
|
73
|
-
end
|
74
|
-
alts
|
75
|
-
end
|
76
|
-
private :_alternatives
|
77
|
-
|
78
68
|
# Returns an Alternative with the specified value.
|
79
69
|
#
|
80
70
|
# @example
|
@@ -137,7 +127,7 @@ module Vanity
|
|
137
127
|
if @playground.collecting?
|
138
128
|
if active?
|
139
129
|
identity = identity()
|
140
|
-
index = connection.ab_showing(@id, identity)
|
130
|
+
index = connection.ab_showing(@id, identity) || connection.ab_assigned(@id, identity)
|
141
131
|
unless index
|
142
132
|
index = alternative_for(identity).to_i
|
143
133
|
save_assignment_if_valid_visitor(identity, index, request) unless @playground.using_js?
|
@@ -151,6 +141,7 @@ module Vanity
|
|
151
141
|
@showing[identity] ||= alternative_for(identity)
|
152
142
|
index = @showing[identity]
|
153
143
|
end
|
144
|
+
|
154
145
|
alternatives[index.to_i]
|
155
146
|
end
|
156
147
|
|
@@ -414,7 +405,7 @@ module Vanity
|
|
414
405
|
def outcome
|
415
406
|
return unless @playground.collecting?
|
416
407
|
outcome = connection.ab_get_outcome(@id)
|
417
|
-
outcome &&
|
408
|
+
outcome && alternatives[outcome]
|
418
409
|
end
|
419
410
|
|
420
411
|
def complete!(outcome = nil)
|
@@ -445,7 +436,7 @@ module Vanity
|
|
445
436
|
connection.destroy_experiment @id
|
446
437
|
super
|
447
438
|
end
|
448
|
-
|
439
|
+
|
449
440
|
# clears all collected data for the experiment
|
450
441
|
def reset
|
451
442
|
connection.destroy_experiment @id
|
@@ -471,12 +462,12 @@ module Vanity
|
|
471
462
|
# Called via a hook by the associated metric.
|
472
463
|
def track!(metric_id, timestamp, count, *args)
|
473
464
|
return unless active?
|
474
|
-
identity = identity()
|
475
|
-
identity ||=
|
465
|
+
identity = args.last[:identity] if args.last.is_a?(Hash)
|
466
|
+
identity ||= identity() rescue nil
|
476
467
|
if identity
|
477
468
|
return if connection.ab_showing(@id, identity)
|
478
469
|
index = alternative_for(identity)
|
479
|
-
connection.ab_add_conversion
|
470
|
+
connection.ab_add_conversion(@id, index, identity, count)
|
480
471
|
check_completion!
|
481
472
|
end
|
482
473
|
end
|
@@ -517,7 +508,8 @@ module Vanity
|
|
517
508
|
return alternative.id if random_outcome < max_prob
|
518
509
|
end
|
519
510
|
end
|
520
|
-
|
511
|
+
|
512
|
+
Digest::MD5.hexdigest("#{name}/#{identity}").to_i(17) % @alternatives.size
|
521
513
|
end
|
522
514
|
|
523
515
|
# Saves the assignment of an alternative to a person and performs the
|
data/lib/vanity/version.rb
CHANGED
data/test/cli_test.rb
CHANGED
@@ -7,21 +7,23 @@ describe "bin/vanity" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "responds to version" do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
assert_output(nil) do
|
11
|
+
proc {
|
12
|
+
ARGV.clear
|
13
|
+
ARGV << '--version'
|
14
|
+
load "bin/vanity"
|
15
|
+
}.must_raise SystemExit
|
16
|
+
end
|
16
17
|
end
|
17
18
|
|
18
19
|
it "responds to help" do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
assert_output(nil) do
|
21
|
+
proc {
|
22
|
+
ARGV.clear
|
23
|
+
ARGV << '--help'
|
24
|
+
load "bin/vanity"
|
25
|
+
}.must_raise SystemExit
|
26
|
+
end
|
25
27
|
end
|
26
28
|
|
27
29
|
it "responds to list" do
|
@@ -47,4 +49,4 @@ describe "bin/vanity" do
|
|
47
49
|
load "bin/vanity"
|
48
50
|
end
|
49
51
|
end
|
50
|
-
end
|
52
|
+
end
|
data/test/experiment/ab_test.rb
CHANGED
@@ -118,6 +118,23 @@ class AbTestTest < ActionController::TestCase
|
|
118
118
|
assert_equal 1, experiment(:abcd).alternatives.sum(&:conversions)
|
119
119
|
end
|
120
120
|
|
121
|
+
# -- track! --
|
122
|
+
|
123
|
+
def test_track_with_identity_overrides_default
|
124
|
+
identities = ["quux"]
|
125
|
+
new_ab_test :foobar do
|
126
|
+
alternatives "foo", "bar"
|
127
|
+
identify { identities.pop || "6e98ec" }
|
128
|
+
metrics :coolness
|
129
|
+
end
|
130
|
+
2.times { experiment(:foobar).choose }
|
131
|
+
assert_equal 0, experiment(:foobar).alternatives.sum(&:converted)
|
132
|
+
experiment(:foobar).track!(:coolness, Time.now, 1)
|
133
|
+
assert_equal 1, experiment(:foobar).alternatives.sum(&:converted)
|
134
|
+
experiment(:foobar).track!(:coolness, Time.now, 1, :identity=>"quux")
|
135
|
+
assert_equal 2, experiment(:foobar).alternatives.sum(&:converted)
|
136
|
+
end
|
137
|
+
|
121
138
|
# -- use_js! --
|
122
139
|
|
123
140
|
def test_choose_does_not_record_participant_when_using_js
|
@@ -327,6 +344,24 @@ class AbTestTest < ActionController::TestCase
|
|
327
344
|
end
|
328
345
|
end
|
329
346
|
|
347
|
+
def test_respects_out_of_band_assignment
|
348
|
+
new_ab_test :foobar do
|
349
|
+
alternatives "a", "b", "c"
|
350
|
+
identify { "6e98ec" }
|
351
|
+
metrics :coolness
|
352
|
+
end
|
353
|
+
# Note that this is explicitly not the alternative id that alternative_for
|
354
|
+
# would assign based on identity
|
355
|
+
assigned_alternative_id = 1
|
356
|
+
Vanity.playground.connection.ab_add_participant(
|
357
|
+
experiment(:foobar).id,
|
358
|
+
assigned_alternative_id,
|
359
|
+
"6e98ec"
|
360
|
+
)
|
361
|
+
chosen_alternative_id = experiment(:foobar).choose.id
|
362
|
+
assert_equal assigned_alternative_id, chosen_alternative_id
|
363
|
+
end
|
364
|
+
|
330
365
|
def test_returns_different_alternatives_for_each_participant
|
331
366
|
new_ab_test :foobar do
|
332
367
|
alternatives "foo", "bar"
|
@@ -1021,7 +1056,7 @@ This experiment did not run long enough to find a clear winner.
|
|
1021
1056
|
assert [:a, :b, :c].include?(choice)
|
1022
1057
|
assert_equal choice, experiment(:simple).choose.value
|
1023
1058
|
end
|
1024
|
-
|
1059
|
+
|
1025
1060
|
def test_reset_clears_participants
|
1026
1061
|
new_ab_test :simple do
|
1027
1062
|
alternatives :a, :b, :c
|
@@ -1032,7 +1067,7 @@ This experiment did not run long enough to find a clear winner.
|
|
1032
1067
|
experiment(:simple).reset
|
1033
1068
|
assert_equal experiment(:simple).alternatives[1].participants, 0
|
1034
1069
|
end
|
1035
|
-
|
1070
|
+
|
1036
1071
|
def test_clears_outcome_and_completed_at
|
1037
1072
|
new_ab_test :simple do
|
1038
1073
|
alternatives :a, :b, :c
|
data/test/helper_test.rb
CHANGED
@@ -8,10 +8,20 @@ describe Object do
|
|
8
8
|
alternatives "foo", "bar"
|
9
9
|
metrics :coolness
|
10
10
|
end
|
11
|
-
track!
|
11
|
+
track!(:coolness, :identity=>'quux')
|
12
|
+
|
13
|
+
assert_equal 1, experiment(:foobar).alternatives.sum(&:conversions)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "accepts value for conversion" do
|
17
|
+
metric "Coolness"
|
18
|
+
new_ab_test :foobar do
|
19
|
+
alternatives "foo", "bar"
|
20
|
+
metrics :coolness
|
21
|
+
end
|
22
|
+
track!(:coolness, :identity=>'quux', :values=>[2])
|
12
23
|
|
13
|
-
# experiment(:foobar).alternatives.sum(&:conversions).must_equal 2
|
14
24
|
assert_equal 2, experiment(:foobar).alternatives.sum(&:conversions)
|
15
25
|
end
|
16
26
|
end
|
17
|
-
end
|
27
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -20,12 +20,7 @@ require "rails/test_help"
|
|
20
20
|
|
21
21
|
require "vanity"
|
22
22
|
require "timecop"
|
23
|
-
|
24
|
-
if defined?(Mocha::VERSION) && Mocha::VERSION < "0.13.0"
|
25
|
-
require "mocha"
|
26
|
-
else
|
27
|
-
require "mocha/mini_test"
|
28
|
-
end
|
23
|
+
require "mocha/mini_test"
|
29
24
|
require "webmock/minitest"
|
30
25
|
|
31
26
|
# Due to load order differences in Rails boot and test requires we have to
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vanity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.beta8
|
5
5
|
prerelease: 6
|
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: 2015-
|
12
|
+
date: 2015-07-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: i18n
|
@@ -205,7 +205,7 @@ licenses:
|
|
205
205
|
post_install_message: To get started run vanity --help
|
206
206
|
rdoc_options:
|
207
207
|
- --title
|
208
|
-
- Vanity 2.0.0.
|
208
|
+
- Vanity 2.0.0.beta8
|
209
209
|
- --main
|
210
210
|
- README.rdoc
|
211
211
|
- --webcvs
|