vanity 1.5.3 → 1.6.0
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.
- data/CHANGELOG +61 -13
- data/Gemfile +5 -5
- data/README.rdoc +10 -1
- data/lib/vanity/adapters/mongodb_adapter.rb +23 -7
- data/lib/vanity/adapters/redis_adapter.rb +8 -2
- data/lib/vanity/experiment/ab_test.rb +55 -30
- data/lib/vanity/experiment/base.rb +4 -2
- data/lib/vanity/frameworks/rails.rb +30 -2
- data/lib/vanity/helpers.rb +8 -1
- data/lib/vanity/playground.rb +35 -2
- data/lib/vanity/templates/_vanity.js.erb +20 -0
- data/lib/vanity/version.rb +1 -1
- data/test/adapters/redis_adapter_test.rb +17 -0
- data/test/experiment/ab_test.rb +83 -11
- data/test/experiment/base_test.rb +14 -0
- data/test/myapp/log/production.log +165 -0
- data/test/playground_test.rb +10 -0
- data/test/rails_dashboard_test.rb +37 -0
- data/test/rails_helper_test.rb +28 -0
- data/test/rails_test.rb +73 -4
- data/test/test_helper.rb +4 -6
- data/vanity.gemspec +1 -1
- metadata +42 -51
- data/test/myapp/app/controllers/application_controller.rbc +0 -66
- data/test/myapp/app/controllers/main_controller.rbc +0 -347
- data/test/myapp/config/boot.rbc +0 -2534
- data/test/myapp/config/environment.rbc +0 -403
- data/test/myapp/config/routes.rbc +0 -174
- data/test/passenger_test.rbc +0 -0
- data/test/playground_test.rbc +0 -256
- data/test/rails_test.rbc +0 -4086
- data/test/test_helper.rbc +0 -4297
data/test/experiment/ab_test.rb
CHANGED
@@ -118,6 +118,21 @@ class AbTestTest < ActionController::TestCase
|
|
118
118
|
assert_equal 1, experiment(:abcd).alternatives.sum(&:conversions)
|
119
119
|
end
|
120
120
|
|
121
|
+
# -- use_js! --
|
122
|
+
|
123
|
+
def test_does_not_record_participant_when_using_js
|
124
|
+
Vanity.playground.use_js!
|
125
|
+
ids = (0...10).to_a
|
126
|
+
new_ab_test :foobar do
|
127
|
+
alternatives "foo", "bar"
|
128
|
+
identify { ids.pop }
|
129
|
+
metrics :coolness
|
130
|
+
end
|
131
|
+
10.times { experiment(:foobar).choose }
|
132
|
+
alts = experiment(:foobar).alternatives
|
133
|
+
assert_equal 0, alts.map(&:participants).sum
|
134
|
+
end
|
135
|
+
|
121
136
|
|
122
137
|
# -- Running experiment --
|
123
138
|
|
@@ -127,10 +142,10 @@ class AbTestTest < ActionController::TestCase
|
|
127
142
|
identify { "6e98ec" }
|
128
143
|
metrics :coolness
|
129
144
|
end
|
130
|
-
assert value = experiment(:foobar).choose
|
145
|
+
assert value = experiment(:foobar).choose.value
|
131
146
|
assert_match /foo|bar/, value
|
132
147
|
1000.times do
|
133
|
-
assert_equal value, experiment(:foobar).choose
|
148
|
+
assert_equal value, experiment(:foobar).choose.value
|
134
149
|
end
|
135
150
|
end
|
136
151
|
|
@@ -140,7 +155,7 @@ class AbTestTest < ActionController::TestCase
|
|
140
155
|
identify { rand }
|
141
156
|
metrics :coolness
|
142
157
|
end
|
143
|
-
alts = Array.new(1000) { experiment(:foobar).choose }
|
158
|
+
alts = Array.new(1000) { experiment(:foobar).choose.value }
|
144
159
|
assert_equal %w{bar foo}, alts.uniq.sort
|
145
160
|
assert_in_delta alts.select { |a| a == "foo" }.size, 500, 100 # this may fail, such is propability
|
146
161
|
end
|
@@ -324,7 +339,7 @@ class AbTestTest < ActionController::TestCase
|
|
324
339
|
fake :abcd, :a=>[182, 35], :b=>[180, 45], :c=>[189,28], :d=>[188, 61]
|
325
340
|
|
326
341
|
z_scores = experiment(:abcd).score.alts.map { |alt| "%.2f" % alt.z_score }
|
327
|
-
assert_equal %w{-1.33 0.00 -2.
|
342
|
+
assert_equal %w{-1.33 0.00 -2.46 1.58}, z_scores
|
328
343
|
probabilities = experiment(:abcd).score.alts.map(&:probability)
|
329
344
|
assert_equal [90, 0, 99, 90], probabilities
|
330
345
|
|
@@ -466,7 +481,7 @@ Option C did not convert.
|
|
466
481
|
|
467
482
|
assert_equal <<-TEXT, experiment(:abcd).conclusion.join("\n") << "\n"
|
468
483
|
There are 374 participants in this experiment.
|
469
|
-
The best choice is option D: it converted at 32.4
|
484
|
+
The best choice is option D: it converted at 32.4% (1% better than option B).
|
470
485
|
This result is not statistically significant, suggest you continue this experiment.
|
471
486
|
Option B converted at 32.3%.
|
472
487
|
Option A did not convert.
|
@@ -530,7 +545,7 @@ This experiment did not run long enough to find a clear winner.
|
|
530
545
|
def test_completion_if_fails
|
531
546
|
new_ab_test :simple do
|
532
547
|
identify { rand }
|
533
|
-
complete_if { fail }
|
548
|
+
complete_if { fail "Testing complete_if raises exception" }
|
534
549
|
metrics :coolness
|
535
550
|
end
|
536
551
|
experiment(:simple).choose
|
@@ -564,7 +579,7 @@ This experiment did not run long enough to find a clear winner.
|
|
564
579
|
# Run experiment to completion (100 participants)
|
565
580
|
results = Set.new
|
566
581
|
100.times do
|
567
|
-
results << experiment(:simple).choose
|
582
|
+
results << experiment(:simple).choose.value
|
568
583
|
metric(:coolness).track!
|
569
584
|
end
|
570
585
|
assert results.include?(true) && results.include?(false)
|
@@ -572,7 +587,7 @@ This experiment did not run long enough to find a clear winner.
|
|
572
587
|
|
573
588
|
# Test that we always get the same choice (true)
|
574
589
|
100.times do
|
575
|
-
assert_equal true, experiment(:simple).choose
|
590
|
+
assert_equal true, experiment(:simple).choose.value
|
576
591
|
metric(:coolness).track!
|
577
592
|
end
|
578
593
|
# We don't get to count the 100 participant's conversion, but that's ok.
|
@@ -592,6 +607,18 @@ This experiment did not run long enough to find a clear winner.
|
|
592
607
|
assert_equal experiment(:quick).alternatives[1], experiment(:quick).outcome
|
593
608
|
end
|
594
609
|
|
610
|
+
def test_error_in_completion
|
611
|
+
new_ab_test :quick do
|
612
|
+
outcome_is { raise RuntimeError }
|
613
|
+
metrics :coolness
|
614
|
+
end
|
615
|
+
e = experiment(:quick)
|
616
|
+
e.expects(:warn)
|
617
|
+
assert_nothing_raised do
|
618
|
+
e.complete!
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
595
622
|
def test_outcome_is_returns_nil
|
596
623
|
new_ab_test :quick do
|
597
624
|
outcome_is { nil }
|
@@ -612,7 +639,7 @@ This experiment did not run long enough to find a clear winner.
|
|
612
639
|
|
613
640
|
def test_outcome_is_fails
|
614
641
|
new_ab_test :quick do
|
615
|
-
outcome_is { fail }
|
642
|
+
outcome_is { fail "Testing outcome_is raising exception" }
|
616
643
|
metrics :coolness
|
617
644
|
end
|
618
645
|
experiment(:quick).complete!
|
@@ -669,10 +696,54 @@ This experiment did not run long enough to find a clear winner.
|
|
669
696
|
assert_nil experiment(:quick).outcome
|
670
697
|
end
|
671
698
|
|
699
|
+
def test_chooses_records_participants
|
700
|
+
new_ab_test :simple do
|
701
|
+
alternatives :a, :b, :c
|
702
|
+
metrics :coolness
|
703
|
+
end
|
704
|
+
experiment(:simple).chooses(:b)
|
705
|
+
assert_equal experiment(:simple).alternatives[1].participants, 1
|
706
|
+
end
|
707
|
+
|
708
|
+
def test_chooses_moves_participant_to_new_alternative
|
709
|
+
new_ab_test :simple do
|
710
|
+
alternatives :a, :b, :c
|
711
|
+
metrics :coolness
|
712
|
+
identify { "1" }
|
713
|
+
end
|
714
|
+
val = experiment(:simple).choose.value
|
715
|
+
alternative = experiment(:simple).alternatives.detect {|a| a.value != val }
|
716
|
+
experiment(:simple).chooses(alternative.value)
|
717
|
+
assert_equal experiment(:simple).choose.value, alternative.value
|
718
|
+
experiment(:simple).chooses(val)
|
719
|
+
assert_equal experiment(:simple).choose.value, val
|
720
|
+
end
|
721
|
+
|
722
|
+
def test_chooses_records_participants_only_once
|
723
|
+
new_ab_test :simple do
|
724
|
+
alternatives :a, :b, :c
|
725
|
+
metrics :coolness
|
726
|
+
end
|
727
|
+
2.times { experiment(:simple).chooses(:b) }
|
728
|
+
assert_equal experiment(:simple).alternatives[1].participants, 1
|
729
|
+
end
|
730
|
+
|
731
|
+
def test_chooses_records_participants_for_new_alternatives
|
732
|
+
new_ab_test :simple do
|
733
|
+
alternatives :a, :b, :c
|
734
|
+
metrics :coolness
|
735
|
+
end
|
736
|
+
experiment(:simple).chooses(:b)
|
737
|
+
experiment(:simple).chooses(:c)
|
738
|
+
assert_equal experiment(:simple).alternatives[1].participants, 1
|
739
|
+
assert_equal experiment(:simple).alternatives[2].participants, 1
|
740
|
+
end
|
741
|
+
|
672
742
|
def test_no_collection_and_chooses
|
673
743
|
not_collecting!
|
674
744
|
new_ab_test :simple do
|
675
745
|
alternatives :a, :b, :c
|
746
|
+
metrics :coolness
|
676
747
|
end
|
677
748
|
assert !experiment(:simple).showing?(experiment(:simple).alternatives[1])
|
678
749
|
experiment(:simple).chooses(:b)
|
@@ -684,10 +755,11 @@ This experiment did not run long enough to find a clear winner.
|
|
684
755
|
not_collecting!
|
685
756
|
new_ab_test :simple do
|
686
757
|
alternatives :a, :b, :c
|
758
|
+
metrics :coolness
|
687
759
|
end
|
688
|
-
choice = experiment(:simple).choose
|
760
|
+
choice = experiment(:simple).choose.value
|
689
761
|
assert [:a, :b, :c].include?(choice)
|
690
|
-
assert_equal choice, experiment(:simple).choose
|
762
|
+
assert_equal choice, experiment(:simple).choose.value
|
691
763
|
end
|
692
764
|
|
693
765
|
|
@@ -132,5 +132,19 @@ class ExperimentTest < Test::Unit::TestCase
|
|
132
132
|
new_ab_test(:ice_cream_flavor) { metrics :happiness }
|
133
133
|
experiment(:ice_cream_flavor).complete!
|
134
134
|
end
|
135
|
+
|
136
|
+
# -- completion -- #
|
137
|
+
|
138
|
+
# check_completion is called by derived classes, but since it's
|
139
|
+
# part of the base_test I'm testing it here.
|
140
|
+
def test_error_in_check_completion
|
141
|
+
new_ab_test(:ab) { metrics :happiness }
|
142
|
+
e = experiment(:ab)
|
143
|
+
e.complete_if { true }
|
144
|
+
e.stubs(:complete!).raises(RuntimeError, "A forced error")
|
145
|
+
e.expects(:warn)
|
146
|
+
e.stubs(:identity).returns(:b)
|
147
|
+
e.track!(:a, Time.now, 10)
|
148
|
+
end
|
135
149
|
|
136
150
|
end
|
@@ -3179,3 +3179,168 @@ Completed in 7ms (View: 1 | 200 OK [http://:? ]
|
|
3179
3179
|
Processing MainController#index (for at 2011-04-11 15:57:26) [GET]
|
3180
3180
|
Parameters: {" "=>nil}
|
3181
3181
|
Completed in 7ms (View: 1 | 200 OK [http://:? ]
|
3182
|
+
|
3183
|
+
|
3184
|
+
Processing MainController#index (for at 2011-04-25 19:24:33) [GET]
|
3185
|
+
Parameters: {" "=>nil}
|
3186
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3187
|
+
|
3188
|
+
|
3189
|
+
Processing MainController#index (for at 2011-04-25 19:26:00) [GET]
|
3190
|
+
Parameters: {" "=>nil}
|
3191
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3192
|
+
|
3193
|
+
|
3194
|
+
Processing MainController#index (for at 2011-04-25 19:27:11) [GET]
|
3195
|
+
Parameters: {" "=>nil}
|
3196
|
+
Completed in 8ms (View: 1 | 200 OK [http://:? ]
|
3197
|
+
|
3198
|
+
|
3199
|
+
Processing MainController#index (for at 2011-04-25 19:29:07) [GET]
|
3200
|
+
Parameters: {" "=>nil}
|
3201
|
+
Completed in 7ms (View: 1 | 200 OK [http://:? ]
|
3202
|
+
|
3203
|
+
|
3204
|
+
Processing MainController#index (for at 2011-04-25 19:31:28) [GET]
|
3205
|
+
Parameters: {" "=>nil}
|
3206
|
+
Completed in 7ms (View: 1 | 200 OK [http://:? ]
|
3207
|
+
|
3208
|
+
|
3209
|
+
Processing MainController#index (for at 2011-04-25 19:59:03) [GET]
|
3210
|
+
Parameters: {" "=>nil}
|
3211
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3212
|
+
|
3213
|
+
|
3214
|
+
Processing MainController#index (for at 2011-04-25 19:59:52) [GET]
|
3215
|
+
Parameters: {" "=>nil}
|
3216
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3217
|
+
|
3218
|
+
|
3219
|
+
Processing MainController#index (for at 2011-05-28 21:17:06) [GET]
|
3220
|
+
Parameters: {" "=>nil}
|
3221
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3222
|
+
|
3223
|
+
|
3224
|
+
Processing MainController#index (for at 2011-05-28 21:19:49) [GET]
|
3225
|
+
Parameters: {" "=>nil}
|
3226
|
+
Completed in 11ms (View: 1 | 200 OK [http://:? ]
|
3227
|
+
|
3228
|
+
|
3229
|
+
Processing MainController#index (for at 2011-05-28 21:22:33) [GET]
|
3230
|
+
Parameters: {" "=>nil}
|
3231
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3232
|
+
|
3233
|
+
|
3234
|
+
Processing MainController#index (for at 2011-06-08 21:30:59) [GET]
|
3235
|
+
Parameters: {" "=>nil}
|
3236
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3237
|
+
|
3238
|
+
|
3239
|
+
Processing MainController#index (for at 2011-06-16 10:17:11) [GET]
|
3240
|
+
Parameters: {" "=>nil}
|
3241
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3242
|
+
|
3243
|
+
|
3244
|
+
Processing MainController#index (for at 2011-07-18 20:29:45) [GET]
|
3245
|
+
Parameters: {" "=>nil}
|
3246
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3247
|
+
|
3248
|
+
|
3249
|
+
Processing MainController#index (for at 2011-07-18 20:31:56) [GET]
|
3250
|
+
Parameters: {" "=>nil}
|
3251
|
+
Completed in 3ms (View: 1 | 200 OK [http://:? ]
|
3252
|
+
|
3253
|
+
|
3254
|
+
Processing MainController#index (for at 2011-07-18 20:34:07) [GET]
|
3255
|
+
Parameters: {" "=>nil}
|
3256
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
3257
|
+
|
3258
|
+
|
3259
|
+
Processing MainController#index (for at 2011-07-18 20:34:35) [GET]
|
3260
|
+
Parameters: {" "=>nil}
|
3261
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3262
|
+
|
3263
|
+
|
3264
|
+
Processing MainController#index (for at 2011-07-18 20:35:51) [GET]
|
3265
|
+
Parameters: {" "=>nil}
|
3266
|
+
Completed in 2ms (View: 1 | 200 OK [http://:? ]
|
3267
|
+
|
3268
|
+
|
3269
|
+
Processing MainController#index (for at 2011-07-18 20:37:01) [GET]
|
3270
|
+
Parameters: {" "=>nil}
|
3271
|
+
Completed in 5ms (View: 1 | 200 OK [http://:? ]
|
3272
|
+
|
3273
|
+
|
3274
|
+
Processing MainController#index (for at 2011-07-18 20:37:43) [GET]
|
3275
|
+
Parameters: {" "=>nil}
|
3276
|
+
Completed in 3ms (View: 1 | 200 OK [http://:? ]
|
3277
|
+
|
3278
|
+
|
3279
|
+
Processing MainController#index (for at 2011-07-18 20:38:23) [GET]
|
3280
|
+
Parameters: {" "=>nil}
|
3281
|
+
Completed in 10ms (View: 2 | 200 OK [http://:? ]
|
3282
|
+
|
3283
|
+
|
3284
|
+
Processing MainController#index (for at 2011-07-18 20:51:29) [GET]
|
3285
|
+
Parameters: {" "=>nil}
|
3286
|
+
Completed in 9ms (View: 2 | 200 OK [http://:? ]
|
3287
|
+
|
3288
|
+
|
3289
|
+
Processing MainController#index (for at 2011-07-18 20:52:27) [GET]
|
3290
|
+
Parameters: {" "=>nil}
|
3291
|
+
Completed in 4ms (View: 1 | 200 OK [http://:? ]
|
3292
|
+
|
3293
|
+
|
3294
|
+
Processing MainController#index (for at 2011-07-18 23:51:49) [GET]
|
3295
|
+
Parameters: {" "=>nil}
|
3296
|
+
Completed in 3ms (View: 1 | 200 OK [http://:? ]
|
3297
|
+
|
3298
|
+
|
3299
|
+
Processing MainController#index (for at 2011-07-19 09:29:26) [GET]
|
3300
|
+
Parameters: {" "=>nil}
|
3301
|
+
Completed in 3ms (View: 1 | 200 OK [http://:? ]
|
3302
|
+
|
3303
|
+
|
3304
|
+
Processing MainController#index (for at 2011-07-19 10:03:46) [GET]
|
3305
|
+
Parameters: {" "=>nil}
|
3306
|
+
Completed in 2ms (View: 1 | 200 OK [http://:? ]
|
3307
|
+
|
3308
|
+
|
3309
|
+
Processing MainController#index (for at 2011-07-19 10:05:27) [GET]
|
3310
|
+
Parameters: {" "=>nil}
|
3311
|
+
Completed in 3ms (View: 1 | 200 OK [http://:? ]
|
3312
|
+
|
3313
|
+
|
3314
|
+
Processing MainController#index (for at 2011-07-19 10:05:58) [GET]
|
3315
|
+
Parameters: {" "=>nil}
|
3316
|
+
Completed in 2ms (View: 1 | 200 OK [http://:? ]
|
3317
|
+
|
3318
|
+
|
3319
|
+
Processing MainController#index (for at 2011-07-19 10:06:23) [GET]
|
3320
|
+
Parameters: {" "=>nil}
|
3321
|
+
Completed in 8ms (View: 1 | 200 OK [http://:? ]
|
3322
|
+
|
3323
|
+
|
3324
|
+
Processing MainController#index (for at 2011-07-19 10:06:43) [GET]
|
3325
|
+
Parameters: {" "=>nil}
|
3326
|
+
Completed in 2ms (View: 1 | 200 OK [http://:? ]
|
3327
|
+
|
3328
|
+
|
3329
|
+
Processing MainController#index (for at 2011-07-19 10:07:19) [GET]
|
3330
|
+
Parameters: {" "=>nil}
|
3331
|
+
Completed in 2ms (View: 1 | 200 OK [http://:? ]
|
3332
|
+
|
3333
|
+
|
3334
|
+
Processing MainController#index (for at 2011-07-19 10:09:19) [GET]
|
3335
|
+
Parameters: {" "=>nil}
|
3336
|
+
Completed in 4ms (View: 1 | 200 OK [http://:? ]
|
3337
|
+
|
3338
|
+
|
3339
|
+
Processing MainController#index (for at 2011-07-20 11:52:11) [GET]
|
3340
|
+
Parameters: {" "=>nil}
|
3341
|
+
Completed in 2ms (View: 1 | 200 OK [http://:? ]
|
3342
|
+
|
3343
|
+
|
3344
|
+
Processing MainController#index (for at 2011-07-20 11:53:47) [GET]
|
3345
|
+
Parameters: {" "=>nil}
|
3346
|
+
Completed in 6ms (View: 1 | 200 OK [http://:? ]
|
data/test/playground_test.rb
CHANGED
@@ -7,4 +7,14 @@ class PlaygroundTest < Test::Unit::TestCase
|
|
7
7
|
assert_equal instance, Vanity.playground
|
8
8
|
end
|
9
9
|
|
10
|
+
def test_be_use_js
|
11
|
+
assert !Vanity.playground.using_js?
|
12
|
+
Vanity.playground.use_js!
|
13
|
+
assert Vanity.playground.using_js?
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_chooses_path_sets_default
|
17
|
+
assert_equal Vanity.playground.add_participant_path, Vanity::Playground::DEFAULT_ADD_PARTICIPANT_PATH
|
18
|
+
end
|
19
|
+
|
10
20
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "test/test_helper"
|
2
|
+
|
3
|
+
class VanityController < ActionController::Base
|
4
|
+
include Vanity::Rails::Dashboard
|
5
|
+
end
|
6
|
+
|
7
|
+
# Pages accessible to everyone, e.g. sign in, community search.
|
8
|
+
class RailsDashboardTest < ActionController::TestCase
|
9
|
+
tests VanityController
|
10
|
+
|
11
|
+
def setup
|
12
|
+
Vanity.playground.collecting = true
|
13
|
+
metric :sugar_high
|
14
|
+
new_ab_test :food do
|
15
|
+
alternatives :apple, :orange
|
16
|
+
metrics :sugar_high
|
17
|
+
identify { '1' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_add_participant
|
22
|
+
xhr :post, :add_participant, :e => "food", :a => 0
|
23
|
+
assert_response :success
|
24
|
+
assert @response.body.blank?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_add_participant_no_params
|
28
|
+
xhr :post, :add_participant
|
29
|
+
assert_response :not_found
|
30
|
+
assert @response.body.blank?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_chooses
|
34
|
+
xhr :post, :chooses, :e => "food", :a => 0
|
35
|
+
assert_response :success
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "test/test_helper"
|
2
|
+
|
3
|
+
class RailsHelperTest < ActionView::TestCase
|
4
|
+
include Vanity::Rails::Helpers
|
5
|
+
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
metric :sugar_high
|
9
|
+
new_ab_test :pie_or_cake do
|
10
|
+
metrics :sugar_high
|
11
|
+
identify { '1' }
|
12
|
+
alternatives :pie, :cake
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_ab_test_returns_one_of_the_alternatives
|
17
|
+
assert [:pie, :cake].include?(ab_test(:pie_or_cake))
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_ab_test_using_js_returns_the_same_alternative
|
21
|
+
Vanity.playground.use_js!
|
22
|
+
result = ab_test(:pie_or_cake)
|
23
|
+
assert [:pie, :cake].include?(result)
|
24
|
+
10.times do
|
25
|
+
assert result == ab_test(:pie_or_cake)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/rails_test.rb
CHANGED
@@ -21,8 +21,22 @@ class UseVanityTest < ActionController::TestCase
|
|
21
21
|
UseVanityController.class_eval do
|
22
22
|
use_vanity :current_user
|
23
23
|
end
|
24
|
+
if ::Rails.respond_to?(:application) # Rails 3 configuration
|
25
|
+
::Rails.application.config.session_options[:domain] = '.foo.bar'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_chooses_sets_alternatives_for_rails_tests
|
30
|
+
experiment(:pie_or_cake).chooses(true)
|
31
|
+
get :index
|
32
|
+
assert_equal 'true', @response.body
|
33
|
+
|
34
|
+
experiment(:pie_or_cake).chooses(false)
|
35
|
+
get :index
|
36
|
+
assert_equal 'false', @response.body
|
24
37
|
end
|
25
38
|
|
39
|
+
|
26
40
|
def test_vanity_cookie_is_persistent
|
27
41
|
get :index
|
28
42
|
assert cookie = @response["Set-Cookie"].find { |c| c[/^vanity_id=/] }
|
@@ -81,22 +95,28 @@ class UseVanityTest < ActionController::TestCase
|
|
81
95
|
|
82
96
|
def test_sets_choices_from_vanity_query_parameter
|
83
97
|
first = experiment(:pie_or_cake).alternatives.first
|
84
|
-
|
98
|
+
fingerprint = experiment(:pie_or_cake).fingerprint(first)
|
85
99
|
10.times do
|
86
100
|
@controller = nil ; setup_controller_request_and_response
|
87
|
-
get :index, :_vanity=>
|
88
|
-
|
101
|
+
get :index, :_vanity => fingerprint
|
102
|
+
assert_equal experiment(:pie_or_cake).choose, experiment(:pie_or_cake).alternatives.first
|
89
103
|
assert experiment(:pie_or_cake).showing?(first)
|
90
104
|
end
|
91
105
|
end
|
92
106
|
|
93
107
|
def test_does_nothing_with_vanity_query_parameter_for_posts
|
108
|
+
experiment(:pie_or_cake).chooses(experiment(:pie_or_cake).alternatives.last.value)
|
94
109
|
first = experiment(:pie_or_cake).alternatives.first
|
95
|
-
|
110
|
+
fingerprint = experiment(:pie_or_cake).fingerprint(first)
|
111
|
+
post :index, :foo => "bar", :_vanity => fingerprint
|
96
112
|
assert_response :success
|
97
113
|
assert !experiment(:pie_or_cake).showing?(first)
|
98
114
|
end
|
99
115
|
|
116
|
+
def test_cookie_domain_from_rails_configuration
|
117
|
+
get :index
|
118
|
+
assert_equal cookies["vanity_id"][:domain], '.foo.bar' if ::Rails.respond_to?(:application)
|
119
|
+
end
|
100
120
|
|
101
121
|
# -- Load path --
|
102
122
|
|
@@ -160,6 +180,55 @@ $stdout << Vanity.playground.connection
|
|
160
180
|
File.unlink "tmp/config/vanity.yml"
|
161
181
|
end
|
162
182
|
|
183
|
+
def test_mongo_connection_from_yaml
|
184
|
+
FileUtils.mkpath "tmp/config"
|
185
|
+
File.open("tmp/config/vanity.yml", "w") do |io|
|
186
|
+
io.write <<-YML
|
187
|
+
mongodb:
|
188
|
+
adapter: mongodb
|
189
|
+
host: localhost
|
190
|
+
port: 27017
|
191
|
+
database: vanity_test
|
192
|
+
YML
|
193
|
+
end
|
194
|
+
|
195
|
+
ENV["RAILS_ENV"] = "mongodb"
|
196
|
+
assert_equal "mongodb://localhost:27017/vanity_test", load_rails(<<-RB)
|
197
|
+
initializer.after_initialize
|
198
|
+
$stdout << Vanity.playground.connection
|
199
|
+
RB
|
200
|
+
ensure
|
201
|
+
File.unlink "tmp/config/vanity.yml"
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_mongodb_replica_set_connection
|
205
|
+
FileUtils.mkpath "tmp/config"
|
206
|
+
File.open("tmp/config/vanity.yml", "w") do |io|
|
207
|
+
io.write <<-YML
|
208
|
+
mongodb:
|
209
|
+
adapter: mongodb
|
210
|
+
hosts:
|
211
|
+
- localhost
|
212
|
+
port: 27017
|
213
|
+
database: vanity_test
|
214
|
+
YML
|
215
|
+
end
|
216
|
+
|
217
|
+
ENV["RAILS_ENV"] = "mongodb"
|
218
|
+
assert_equal "mongodb://localhost:27017/vanity_test", load_rails(<<-RB)
|
219
|
+
initializer.after_initialize
|
220
|
+
$stdout << Vanity.playground.connection
|
221
|
+
RB
|
222
|
+
|
223
|
+
ENV["RAILS_ENV"] = "mongodb"
|
224
|
+
assert_equal "Mongo::ReplSetConnection", load_rails(<<-RB)
|
225
|
+
initializer.after_initialize
|
226
|
+
$stdout << Vanity.playground.connection.mongo.class
|
227
|
+
RB
|
228
|
+
ensure
|
229
|
+
File.unlink "tmp/config/vanity.yml"
|
230
|
+
end
|
231
|
+
|
163
232
|
def test_connection_from_yaml_url
|
164
233
|
FileUtils.mkpath "tmp/config"
|
165
234
|
ENV["RAILS_ENV"] = "production"
|
data/test/test_helper.rb
CHANGED
@@ -6,6 +6,7 @@ require "test/unit"
|
|
6
6
|
require "mocha"
|
7
7
|
require "action_controller"
|
8
8
|
require "action_controller/test_case"
|
9
|
+
require "action_view/test_case"
|
9
10
|
require "active_record"
|
10
11
|
require "initializer"
|
11
12
|
Rails.configuration = Rails::Configuration.new
|
@@ -21,14 +22,11 @@ if $VERBOSE
|
|
21
22
|
end
|
22
23
|
|
23
24
|
class Test::Unit::TestCase
|
24
|
-
include WebMock
|
25
|
+
include WebMock::API
|
25
26
|
|
26
27
|
def setup
|
27
28
|
FileUtils.mkpath "tmp/experiments/metrics"
|
28
29
|
new_playground
|
29
|
-
#WebMock.after_request do |request_signature, response|
|
30
|
-
# puts "Request #{request_signature} was made and #{response} was returned"
|
31
|
-
#end
|
32
30
|
end
|
33
31
|
|
34
32
|
# Call this on teardown. It wipes put the playground and any state held in it
|
@@ -92,7 +90,7 @@ class Test::Unit::TestCase
|
|
92
90
|
Vanity.context = nil
|
93
91
|
FileUtils.rm_rf "tmp"
|
94
92
|
Vanity.playground.connection.flushdb if Vanity.playground.connected?
|
95
|
-
WebMock.
|
93
|
+
WebMock.reset!
|
96
94
|
end
|
97
95
|
|
98
96
|
end
|
@@ -103,7 +101,7 @@ end
|
|
103
101
|
|
104
102
|
|
105
103
|
ActiveRecord::Base.logger = $logger
|
106
|
-
ActiveRecord::Base.establish_connection :adapter=>"
|
104
|
+
ActiveRecord::Base.establish_connection :adapter=>"mysql", :database=>"vanity_test"
|
107
105
|
|
108
106
|
|
109
107
|
class Array
|
data/vanity.gemspec
CHANGED