vanity 1.3.0 → 1.4.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/CHANGELOG +61 -3
  2. data/Gemfile +22 -14
  3. data/README.rdoc +9 -4
  4. data/Rakefile +72 -12
  5. data/bin/vanity +16 -4
  6. data/lib/vanity.rb +7 -5
  7. data/lib/vanity/adapters/abstract_adapter.rb +135 -0
  8. data/lib/vanity/adapters/mock_adapter.rb +157 -0
  9. data/lib/vanity/adapters/mongo_adapter.rb +162 -0
  10. data/lib/vanity/adapters/redis_adapter.rb +154 -0
  11. data/lib/vanity/backport.rb +0 -17
  12. data/lib/vanity/commands/upgrade.rb +34 -0
  13. data/lib/vanity/experiment/ab_test.rb +46 -41
  14. data/lib/vanity/experiment/base.rb +13 -15
  15. data/lib/vanity/frameworks/rails.rb +5 -9
  16. data/lib/vanity/metric/active_record.rb +10 -4
  17. data/lib/vanity/metric/base.rb +46 -23
  18. data/lib/vanity/metric/google_analytics.rb +7 -0
  19. data/lib/vanity/metric/remote.rb +53 -0
  20. data/lib/vanity/playground.rb +133 -49
  21. data/test/{ab_test_test.rb → experiment/ab_test.rb} +47 -3
  22. data/test/{experiment_test.rb → experiment/base_test.rb} +8 -8
  23. data/test/metric/active_record_test.rb +253 -0
  24. data/test/metric/base_test.rb +293 -0
  25. data/test/metric/google_analytics_test.rb +104 -0
  26. data/test/metric/remote_test.rb +108 -0
  27. data/test/myapp/app/controllers/application_controller.rbc +66 -0
  28. data/test/myapp/app/controllers/main_controller.rb +3 -3
  29. data/test/myapp/app/controllers/main_controller.rbc +347 -0
  30. data/test/myapp/config/boot.rbc +2534 -0
  31. data/test/myapp/config/environment.rbc +403 -0
  32. data/test/myapp/config/routes.rbc +174 -0
  33. data/test/myapp/log/production.log +2601 -0
  34. data/test/passenger_test.rb +14 -5
  35. data/test/passenger_test.rbc +0 -0
  36. data/test/playground_test.rbc +256 -0
  37. data/test/rails_test.rb +75 -22
  38. data/test/rails_test.rbc +4086 -0
  39. data/test/test_helper.rb +30 -7
  40. data/test/test_helper.rbc +4297 -0
  41. data/vanity.gemspec +6 -2
  42. metadata +74 -73
  43. data/lib/vanity/commands.rb +0 -2
  44. data/lib/vanity/mock_redis.rb +0 -76
  45. data/test/metric_test.rb +0 -622
  46. data/vendor/cache/RedCloth-4.2.2.gem +0 -0
  47. data/vendor/cache/actionmailer-2.3.5.gem +0 -0
  48. data/vendor/cache/actionpack-2.3.5.gem +0 -0
  49. data/vendor/cache/activerecord-2.3.5.gem +0 -0
  50. data/vendor/cache/activeresource-2.3.5.gem +0 -0
  51. data/vendor/cache/activesupport-2.3.5.gem +0 -0
  52. data/vendor/cache/autotest-4.2.7.gem +0 -0
  53. data/vendor/cache/autotest-fsevent-0.2.1.gem +0 -0
  54. data/vendor/cache/autotest-growl-0.2.0.gem +0 -0
  55. data/vendor/cache/bundler-0.9.7.gem +0 -0
  56. data/vendor/cache/classifier-1.3.1.gem +0 -0
  57. data/vendor/cache/directory_watcher-1.3.1.gem +0 -0
  58. data/vendor/cache/fastthread-1.0.7.gem +0 -0
  59. data/vendor/cache/garb-0.7.0.gem +0 -0
  60. data/vendor/cache/happymapper-0.3.0.gem +0 -0
  61. data/vendor/cache/jekyll-0.5.7.gem +0 -0
  62. data/vendor/cache/libxml-ruby-1.1.3.gem +0 -0
  63. data/vendor/cache/liquid-2.0.0.gem +0 -0
  64. data/vendor/cache/maruku-0.6.0.gem +0 -0
  65. data/vendor/cache/mocha-0.9.8.gem +0 -0
  66. data/vendor/cache/open4-1.0.1.gem +0 -0
  67. data/vendor/cache/passenger-2.2.9.gem +0 -0
  68. data/vendor/cache/rack-1.0.1.gem +0 -0
  69. data/vendor/cache/rails-2.3.5.gem +0 -0
  70. data/vendor/cache/rake-0.8.7.gem +0 -0
  71. data/vendor/cache/rubygems-update-1.3.5.gem +0 -0
  72. data/vendor/cache/shoulda-2.10.3.gem +0 -0
  73. data/vendor/cache/sqlite3-ruby-1.2.5.gem +0 -0
  74. data/vendor/cache/stemmer-1.0.1.gem +0 -0
  75. data/vendor/cache/syntax-1.0.0.gem +0 -0
  76. data/vendor/cache/sys-uname-0.8.4.gem +0 -0
  77. data/vendor/cache/timecop-0.3.4.gem +0 -0
  78. data/vendor/redis-rb/LICENSE +0 -20
  79. data/vendor/redis-rb/README.markdown +0 -36
  80. data/vendor/redis-rb/Rakefile +0 -62
  81. data/vendor/redis-rb/bench.rb +0 -44
  82. data/vendor/redis-rb/benchmarking/suite.rb +0 -24
  83. data/vendor/redis-rb/benchmarking/worker.rb +0 -71
  84. data/vendor/redis-rb/bin/distredis +0 -33
  85. data/vendor/redis-rb/examples/basic.rb +0 -16
  86. data/vendor/redis-rb/examples/incr-decr.rb +0 -18
  87. data/vendor/redis-rb/examples/list.rb +0 -26
  88. data/vendor/redis-rb/examples/sets.rb +0 -36
  89. data/vendor/redis-rb/lib/dist_redis.rb +0 -124
  90. data/vendor/redis-rb/lib/hash_ring.rb +0 -128
  91. data/vendor/redis-rb/lib/pipeline.rb +0 -21
  92. data/vendor/redis-rb/lib/redis.rb +0 -370
  93. data/vendor/redis-rb/lib/redis/raketasks.rb +0 -1
  94. data/vendor/redis-rb/profile.rb +0 -22
  95. data/vendor/redis-rb/redis-rb.gemspec +0 -30
  96. data/vendor/redis-rb/spec/redis_spec.rb +0 -637
  97. data/vendor/redis-rb/spec/spec_helper.rb +0 -4
  98. data/vendor/redis-rb/speed.rb +0 -16
  99. data/vendor/redis-rb/tasks/redis.tasks.rb +0 -140
@@ -0,0 +1,293 @@
1
+ require "test/test_helper"
2
+
3
+
4
+ context "Metric via playground" do
5
+
6
+ test "knows all loaded metrics" do
7
+ metric "Yawns/sec", "Cheers/sec"
8
+ assert Vanity.playground.metrics.keys.include?(:yawns_sec)
9
+ assert Vanity.playground.metrics.keys.include?(:cheers_sec)
10
+ end
11
+
12
+ test "loads metric definitions" do
13
+ File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
14
+ f.write <<-RUBY
15
+ metric "Yawns/sec" do
16
+ def xmts
17
+ "x"
18
+ end
19
+ end
20
+ RUBY
21
+ end
22
+ assert_equal "x", Vanity.playground.metric(:yawns_sec).xmts
23
+ end
24
+
25
+ test "bubbles up loaded metrics" do
26
+ File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
27
+ f.write "fail 'yawn!'"
28
+ end
29
+ assert_raises NameError do
30
+ Vanity.playground.metric(:yawns_sec)
31
+ end
32
+ end
33
+
34
+ test "map identifier from file name" do
35
+ File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
36
+ f.write <<-RUBY
37
+ metric "yawns/hour" do
38
+ end
39
+ RUBY
40
+ end
41
+ assert Vanity.playground.metric(:yawns_sec)
42
+ end
43
+
44
+ test "fails tracking unknown metric" do
45
+ assert_raises NameError do
46
+ Vanity.playground.track! :yawns_sec
47
+ end
48
+ end
49
+
50
+ test "reloading metrics" do
51
+ metric "Yawns/sec", "Cheers/sec"
52
+ Vanity.playground.metric(:yawns_sec)
53
+ Vanity.playground.metric(:cheers_sec)
54
+ assert_equal 2, Vanity.playground.metrics.size
55
+ metrics = Vanity.playground.metrics.values
56
+ Vanity.playground.reload!
57
+ assert_equal 0, Vanity.playground.metrics.size
58
+ assert_not_equal metrics, Vanity.playground.metrics.values
59
+ end
60
+
61
+ test "ignores undefined metrics in database" do
62
+ metric "Yawns/sec"
63
+ Vanity.playground.reload!
64
+ assert Vanity.playground.metrics.empty?
65
+ end
66
+
67
+ end
68
+
69
+
70
+ context "Metric tracking" do
71
+ test "disabled when metrics are disabled" do
72
+ not_collecting!
73
+ metric "Yawns/sec", "Cheers/sec"
74
+ Vanity.playground.track! :yawns_sec
75
+ Vanity.playground.track! :cheers_sec
76
+ end
77
+
78
+ test "can count" do
79
+ metric "Yawns/sec", "Cheers/sec"
80
+ 4.times { Vanity.playground.track! :yawns_sec }
81
+ 2.times { Vanity.playground.track! :cheers_sec }
82
+ yawns = Vanity.playground.metric(:yawns_sec).values(today, today).first
83
+ cheers = Vanity.playground.metric(:cheers_sec).values(today, today).first
84
+ assert yawns = 2 * cheers
85
+ end
86
+
87
+ test "can tell the time" do
88
+ metric "Yawns/sec"
89
+ Timecop.freeze(today - 4) { 4.times { Vanity.playground.track! :yawns_sec } }
90
+ Timecop.freeze(today - 2) { 2.times { Vanity.playground.track! :yawns_sec } }
91
+ 1.times { Vanity.playground.track! :yawns_sec }
92
+ boredom = Vanity.playground.metric(:yawns_sec).values(today - 5, today)
93
+ assert_equal [0,4,0,2,0,1], boredom
94
+ end
95
+
96
+ test "with no value" do
97
+ metric "Yawns/sec", "Cheers/sec", "Looks"
98
+ Vanity.playground.track! :yawns_sec, 0
99
+ Vanity.playground.track! :cheers_sec
100
+ assert_equal 0, Vanity.playground.metric(:yawns_sec).values(today, today).sum
101
+ assert_equal 1, Vanity.playground.metric(:cheers_sec).values(today, today).sum
102
+ end
103
+
104
+ test "with count" do
105
+ metric "Yawns/sec"
106
+ Timecop.freeze(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
107
+ Timecop.freeze(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
108
+ Vanity.playground.track! :yawns_sec
109
+ boredom = Vanity.playground.metric(:yawns_sec).values(today - 5, today)
110
+ assert_equal [0,4,0,2,0,1], boredom
111
+ end
112
+
113
+ test "runs hook" do
114
+ metric "Many Happy Returns"
115
+ total = 0
116
+ Vanity.playground.metric(:many_happy_returns).hook do |metric_id, timestamp, count|
117
+ assert_equal :many_happy_returns, metric_id
118
+ assert_in_delta Time.now.to_i, timestamp.to_i, 1
119
+ total += count
120
+ end
121
+ Vanity.playground.track! :many_happy_returns, 6
122
+ assert_equal 6, total
123
+ end
124
+
125
+ test "doesn't runs hook when metrics disabled" do
126
+ not_collecting!
127
+ metric "Many Happy Returns"
128
+ total = 0
129
+ Vanity.playground.metric(:many_happy_returns).hook do |metric_id, timestamp, count|
130
+ total += count
131
+ end
132
+ Vanity.playground.track! :many_happy_returns, 6
133
+ assert_equal 0, total
134
+ end
135
+
136
+ test "runs multiple hooks" do
137
+ metric "Many Happy Returns"
138
+ returns = 0
139
+ Vanity.playground.metric(:many_happy_returns).hook { returns += 1 }
140
+ Vanity.playground.metric(:many_happy_returns).hook { returns += 1 }
141
+ Vanity.playground.metric(:many_happy_returns).hook { returns += 1 }
142
+ Vanity.playground.track! :many_happy_returns
143
+ assert_equal 3, returns
144
+ end
145
+
146
+ test "destroy wipes metrics" do
147
+ metric "Many Happy Returns"
148
+ Vanity.playground.track! :many_happy_returns, 3
149
+ assert_equal [3], Vanity.playground.metric(:many_happy_returns).values(today, today)
150
+ Vanity.playground.metric(:many_happy_returns).destroy!
151
+ assert_equal [0], Vanity.playground.metric(:many_happy_returns).values(today, today)
152
+ end
153
+ end
154
+
155
+
156
+ context "Metric name" do
157
+ test "can be whatever" do
158
+ File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
159
+ f.write <<-RUBY
160
+ metric "Yawns per second" do
161
+ end
162
+ RUBY
163
+ end
164
+ assert_equal "Yawns per second", Vanity.playground.metric(:yawns_sec).name
165
+ end
166
+ end
167
+
168
+
169
+ context "Metric description" do
170
+ test "metric with description" do
171
+ File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
172
+ f.write <<-RUBY
173
+ metric "Yawns/sec" do
174
+ description "Am I that boring?"
175
+ end
176
+ RUBY
177
+ end
178
+ assert_equal "Am I that boring?", Vanity::Metric.description(Vanity.playground.metric(:yawns_sec))
179
+ end
180
+
181
+ test "metric without description" do
182
+ File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
183
+ f.write <<-RUBY
184
+ metric "Yawns/sec" do
185
+ end
186
+ RUBY
187
+ end
188
+ assert_nil Vanity::Metric.description(Vanity.playground.metric(:yawns_sec))
189
+ end
190
+
191
+ test "metric with no method description" do
192
+ metric = Object.new
193
+ assert_nil Vanity::Metric.description(metric)
194
+ end
195
+ end
196
+
197
+
198
+ context "Metric bounds" do
199
+ test "metric with bounds" do
200
+ File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
201
+ f.write <<-RUBY
202
+ metric "Sky is limit" do
203
+ def bounds
204
+ [6,12]
205
+ end
206
+ end
207
+ RUBY
208
+ end
209
+ assert_equal [6,12], Vanity::Metric.bounds(Vanity.playground.metric(:sky_is_limit))
210
+ end
211
+
212
+ test "metric without bounds" do
213
+ metric "Sky is limit"
214
+ assert_equal [nil, nil], Vanity::Metric.bounds(Vanity.playground.metric(:sky_is_limit))
215
+ end
216
+
217
+ test "metric with no method bounds" do
218
+ metric = Object.new
219
+ assert_equal [nil, nil], Vanity::Metric.bounds(metric)
220
+ end
221
+ end
222
+
223
+
224
+ context "Metric last_update_at" do
225
+ test "for new metric" do
226
+ metric "Coolness"
227
+ metric = Vanity.playground.metric(:coolness)
228
+ assert_nil metric.last_update_at
229
+ end
230
+
231
+ test "with data point" do
232
+ metric "Coolness"
233
+ metric = Vanity.playground.metric(:coolness)
234
+ metric.track!
235
+ Timecop.freeze Time.now + 1.day do
236
+ metric.track!
237
+ end
238
+ assert_in_delta metric.last_update_at.to_i, (Time.now + 1.day).to_i, 1
239
+ end
240
+ end
241
+
242
+
243
+ context "Metric data" do
244
+ test "explicit dates" do
245
+ metric "Yawns/sec"
246
+ Timecop.freeze(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
247
+ Timecop.freeze(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
248
+ Vanity.playground.track! :yawns_sec
249
+ boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec), Date.today - 5, Date.today)
250
+ assert_equal [[today - 5, 0], [today - 4, 4], [today - 3, 0], [today - 2, 2], [today - 1, 0], [today, 1]], boredom
251
+ end
252
+
253
+ test "start date only" do
254
+ metric "Yawns/sec"
255
+ Timecop.freeze(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
256
+ Timecop.freeze(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
257
+ Vanity.playground.track! :yawns_sec
258
+ boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec), Date.today - 4)
259
+ assert_equal [[today - 4, 4], [today - 3, 0], [today - 2, 2], [today - 1, 0], [today, 1]], boredom
260
+ end
261
+
262
+ test "start date and duration" do
263
+ metric "Yawns/sec"
264
+ Timecop.freeze(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
265
+ Timecop.freeze(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
266
+ Vanity.playground.track! :yawns_sec
267
+ boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec), 5)
268
+ assert_equal [[today - 4, 4], [today - 3, 0], [today - 2, 2], [today - 1, 0], [today, 1]], boredom
269
+ end
270
+
271
+ test "no data" do
272
+ metric "Yawns/sec"
273
+ boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec))
274
+ assert_equal 90, boredom.size
275
+ assert_equal [today - 89, 0], boredom.first
276
+ assert_equal [today, 0], boredom.last
277
+ end
278
+
279
+ test "using custom values method" do
280
+ File.open "tmp/experiments/metrics/hours_in_day.rb", "w" do |f|
281
+ f.write <<-RUBY
282
+ metric "Hours in day" do
283
+ def values(from, to)
284
+ (from..to).map { |d| 24 }
285
+ end
286
+ end
287
+ RUBY
288
+ end
289
+ data = Vanity::Metric.data(Vanity.playground.metric(:hours_in_day))
290
+ assert_equal [24] * 90, data.map(&:last)
291
+ end
292
+
293
+ end
@@ -0,0 +1,104 @@
1
+ require "test/test_helper"
2
+
3
+
4
+ context "Google Analytics" do
5
+
6
+ setup do
7
+ File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
8
+ f.write <<-RUBY
9
+ metric "GA" do
10
+ google_analytics "UA2"
11
+ end
12
+ RUBY
13
+ end
14
+ end
15
+
16
+ GA_RESULT = Struct.new(:date, :pageviews, :visits)
17
+ GA_PROFILE = Struct.new(:web_property_id)
18
+
19
+ test "fail if Garb not available" do
20
+ File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
21
+ f.write <<-RUBY
22
+ metric "GA" do
23
+ expects(:require).raises LoadError
24
+ google_analytics "UA2"
25
+ end
26
+ RUBY
27
+ end
28
+ assert_raise LoadError do
29
+ Vanity.playground.metrics
30
+ end
31
+ end
32
+
33
+ test "constructs a report" do
34
+ Vanity.playground.metrics
35
+ assert metric(:ga).report
36
+ end
37
+
38
+ test "default to pageviews metric" do
39
+ Vanity.playground.metrics
40
+ assert_equal [:pageviews], metric(:ga).report.metrics.elements
41
+ end
42
+
43
+ test "apply data dimension and sort" do
44
+ Vanity.playground.metrics
45
+ assert_equal [:date], metric(:ga).report.dimensions.elements
46
+ assert_equal [:date], metric(:ga).report.sort.elements
47
+ end
48
+
49
+ test "accept other metrics" do
50
+ File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
51
+ f.write <<-RUBY
52
+ metric "GA" do
53
+ google_analytics "UA2", :visitors
54
+ end
55
+ RUBY
56
+ end
57
+ Vanity.playground.metrics
58
+ assert_equal [:visitors], metric(:ga).report.metrics.elements
59
+ end
60
+
61
+ test "does not support hooks" do
62
+ Vanity.playground.metrics
63
+ assert_raises RuntimeError do
64
+ metric(:ga).hook
65
+ end
66
+ end
67
+
68
+ test "should find matching profile" do
69
+ Vanity.playground.metrics
70
+ Garb::Profile.expects(:all).returns(Array.new(3) { |i| GA_PROFILE.new("UA#{i + 1}") })
71
+ metric(:ga).report.stubs(:send_request_for_body).returns(nil)
72
+ Garb::ReportResponse.stubs(:new).returns(mock(:results=>[]))
73
+ metric(:ga).values(Date.parse("2010-02-10"), Date.parse("2010-02-12"))
74
+ assert_equal "UA2", metric(:ga).report.profile.web_property_id
75
+ end
76
+
77
+ test "should map results from report" do
78
+ Vanity.playground.metrics
79
+ today = Date.today
80
+ response = mock(:results=>Array.new(3) { |i| GA_RESULT.new("2010021#{i}", i + 1) })
81
+ Garb::Profile.stubs(:all).returns([])
82
+ Garb::ReportResponse.expects(:new).returns(response)
83
+ metric(:ga).report.stubs(:send_request_for_body).returns(nil)
84
+ assert_equal [1,2,3], metric(:ga).values(Date.parse("2010-02-10"), Date.parse("2010-02-12"))
85
+ end
86
+
87
+ test "mapping GA metrics to single value" do
88
+ File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
89
+ f.write <<-RUBY
90
+ metric "GA" do
91
+ google_analytics "UA2", :mapper=>lambda { |e| e.pageviews * e.visits }
92
+ end
93
+ RUBY
94
+ end
95
+ Vanity.playground.metrics
96
+ today = Date.today
97
+ response = mock(:results=>Array.new(3) { |i| GA_RESULT.new("2010021#{i}", i + 1, i + 1) })
98
+ Garb::Profile.stubs(:all).returns([])
99
+ Garb::ReportResponse.expects(:new).returns(response)
100
+ metric(:ga).report.stubs(:send_request_for_body).returns(nil)
101
+ assert_equal [1,4,9], metric(:ga).values(Date.parse("2010-02-10"), Date.parse("2010-02-12"))
102
+ end
103
+
104
+ end
@@ -0,0 +1,108 @@
1
+ require "test/test_helper"
2
+
3
+
4
+ context "Remote metrics" do
5
+ setup do
6
+ FileUtils.mkpath "tmp/config"
7
+ File.open "tmp/config/vanity.yml", "w" do |f|
8
+ f.write <<-RUBY
9
+ metrics:
10
+ sandbox: http://api.vanitydash.com/metrics/sandbox
11
+ RUBY
12
+ end
13
+ Dir.chdir "tmp" do
14
+ Vanity.playground.load!
15
+ end
16
+ end
17
+
18
+ test "load from configuration file" do
19
+ assert Vanity.playground.metrics[:sandbox]
20
+ end
21
+
22
+ test "create remote metric from configuration file" do
23
+ stub_request :post, /vanitydash/
24
+ metric(:sandbox).track!
25
+ assert_requested :post, /api\.vanitydash\.com/
26
+ end
27
+ end
28
+
29
+
30
+ context "Remote send" do
31
+ setup do
32
+ @metric = Vanity::Metric.new(Vanity.playground, :sandbox)
33
+ @metric.remote "http://api.vanitydash.com/metrics/sandbox"
34
+ Vanity.playground.metrics[:sandbox] = @metric
35
+ stub_request :post, /vanitydash/
36
+ end
37
+
38
+ test "remote send in sequence" do
39
+ Vanity.playground.track! :sandbox
40
+ Vanity.playground.track! :sandbox
41
+ assert_requested(:post, "http://api.vanitydash.com/metrics/sandbox", :times=>2)
42
+ end
43
+
44
+ test "remote sends url-encoded data" do
45
+ Vanity.playground.track! :sandbox, 12
46
+ assert_requested(:post, /api/) { |request| request.headers["Content-Type"] == "application/x-www-form-urlencoded" }
47
+ end
48
+
49
+ test "remote sends metric identifier" do
50
+ Vanity.playground.track! :sandbox, 12
51
+ assert_requested(:post, /api/) { |request| Rack::Utils.parse_query(request.body)["metric"] == "sandbox" }
52
+ end
53
+
54
+ test "remote sends RFC 2616 compliant time stamp" do
55
+ Vanity.playground.track! :sandbox, 12
56
+ assert_requested(:post, /api/) { |request| Time.httpdate(Rack::Utils.parse_query(request.body)["timestamp"]) }
57
+ end
58
+
59
+ test "remote sends array of values" do
60
+ Vanity.playground.track! :sandbox, [1,2,3]
61
+ assert_requested(:post, /api/) { |request| Rack::Utils.parse_query(request.body)["values[]"] == %w{1 2 3} }
62
+ end
63
+
64
+ test "remote sends default of 1" do
65
+ Vanity.playground.track! :sandbox
66
+ assert_requested(:post, /api/) { |request| Rack::Utils.parse_query(request.body)["values[]"] == "1" }
67
+ end
68
+
69
+ test "remote sends current identity" do
70
+ Vanity.context = Object.new
71
+ class << Vanity.context
72
+ def vanity_identity
73
+ "xkcd"
74
+ end
75
+ end
76
+ Vanity.playground.track! :sandbox, 12
77
+ assert_requested(:post, /api/) { |request| Rack::Utils.parse_query(request.body)["identity"] == "xkcd" }
78
+ end
79
+
80
+ test "remote sends with additional query parameters" do
81
+ @metric.remote "http://api.vanitydash.com/metrics/sandbox?ask=receive"
82
+ Vanity.playground.track! :sandbox, 12
83
+ assert_requested(:post, /api/) { |request| Rack::Utils.parse_query(request.body)["ask"] == "receive" }
84
+ end
85
+
86
+ test "remote send handles standard error" do
87
+ stub_request(:post, /api/).to_raise(StandardError)
88
+ Vanity.playground.track! :sandbox
89
+ stub_request(:post, /api/)
90
+ Vanity.playground.track! :sandbox
91
+ assert_requested(:post, /api/, :times=>2)
92
+ end
93
+
94
+ test "remote send handles timeout error" do
95
+ stub_request(:post, /api/).to_timeout
96
+ Vanity.playground.track! :sandbox
97
+ stub_request(:post, /api/)
98
+ Vanity.playground.track! :sandbox
99
+ assert_requested(:post, /api/, :times=>2)
100
+ end
101
+
102
+ test "remote does not send when metrics disabled" do
103
+ not_collecting!
104
+ Vanity.playground.track! :sandbox
105
+ Vanity.playground.track! :sandbox
106
+ assert_requested(:post, /api/, :times=>0)
107
+ end
108
+ end