moses-vanity 1.7.1
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/.autotest +22 -0
- data/.gitignore +7 -0
- data/.rvmrc +3 -0
- data/.travis.yml +13 -0
- data/CHANGELOG +374 -0
- data/Gemfile +28 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +108 -0
- data/Rakefile +189 -0
- data/bin/vanity +16 -0
- data/doc/_config.yml +2 -0
- data/doc/_layouts/_header.html +34 -0
- data/doc/_layouts/page.html +47 -0
- data/doc/_metrics.textile +12 -0
- data/doc/ab_testing.textile +210 -0
- data/doc/configuring.textile +45 -0
- data/doc/contributing.textile +93 -0
- data/doc/credits.textile +23 -0
- data/doc/css/page.css +83 -0
- data/doc/css/print.css +43 -0
- data/doc/css/syntax.css +7 -0
- data/doc/email.textile +129 -0
- data/doc/experimental.textile +31 -0
- data/doc/faq.textile +8 -0
- data/doc/identity.textile +43 -0
- data/doc/images/ab_in_dashboard.png +0 -0
- data/doc/images/clear_winner.png +0 -0
- data/doc/images/price_options.png +0 -0
- data/doc/images/sidebar_test.png +0 -0
- data/doc/images/signup_metric.png +0 -0
- data/doc/images/vanity.png +0 -0
- data/doc/index.textile +91 -0
- data/doc/metrics.textile +231 -0
- data/doc/rails.textile +89 -0
- data/doc/site.js +27 -0
- data/generators/templates/vanity_migration.rb +53 -0
- data/generators/vanity_generator.rb +8 -0
- data/lib/generators/templates/vanity_migration.rb +53 -0
- data/lib/generators/vanity_generator.rb +15 -0
- data/lib/vanity.rb +36 -0
- data/lib/vanity/adapters/abstract_adapter.rb +140 -0
- data/lib/vanity/adapters/active_record_adapter.rb +248 -0
- data/lib/vanity/adapters/mock_adapter.rb +157 -0
- data/lib/vanity/adapters/mongodb_adapter.rb +178 -0
- data/lib/vanity/adapters/redis_adapter.rb +160 -0
- data/lib/vanity/backport.rb +26 -0
- data/lib/vanity/commands/list.rb +21 -0
- data/lib/vanity/commands/report.rb +64 -0
- data/lib/vanity/commands/upgrade.rb +34 -0
- data/lib/vanity/experiment/ab_test.rb +507 -0
- data/lib/vanity/experiment/base.rb +214 -0
- data/lib/vanity/frameworks.rb +16 -0
- data/lib/vanity/frameworks/rails.rb +318 -0
- data/lib/vanity/helpers.rb +66 -0
- data/lib/vanity/images/x.gif +0 -0
- data/lib/vanity/metric/active_record.rb +85 -0
- data/lib/vanity/metric/base.rb +244 -0
- data/lib/vanity/metric/google_analytics.rb +83 -0
- data/lib/vanity/metric/remote.rb +53 -0
- data/lib/vanity/playground.rb +396 -0
- data/lib/vanity/templates/_ab_test.erb +28 -0
- data/lib/vanity/templates/_experiment.erb +5 -0
- data/lib/vanity/templates/_experiments.erb +7 -0
- data/lib/vanity/templates/_metric.erb +14 -0
- data/lib/vanity/templates/_metrics.erb +13 -0
- data/lib/vanity/templates/_report.erb +27 -0
- data/lib/vanity/templates/_vanity.js.erb +20 -0
- data/lib/vanity/templates/flot.min.js +1 -0
- data/lib/vanity/templates/jquery.min.js +19 -0
- data/lib/vanity/templates/vanity.css +26 -0
- data/lib/vanity/templates/vanity.js +82 -0
- data/lib/vanity/version.rb +11 -0
- data/test/adapters/redis_adapter_test.rb +17 -0
- data/test/experiment/ab_test.rb +771 -0
- data/test/experiment/base_test.rb +150 -0
- data/test/experiments/age_and_zipcode.rb +19 -0
- data/test/experiments/metrics/cheers.rb +3 -0
- data/test/experiments/metrics/signups.rb +2 -0
- data/test/experiments/metrics/yawns.rb +3 -0
- data/test/experiments/null_abc.rb +5 -0
- data/test/metric/active_record_test.rb +277 -0
- data/test/metric/base_test.rb +293 -0
- data/test/metric/google_analytics_test.rb +104 -0
- data/test/metric/remote_test.rb +109 -0
- data/test/myapp/app/controllers/application_controller.rb +2 -0
- data/test/myapp/app/controllers/main_controller.rb +7 -0
- data/test/myapp/config/boot.rb +110 -0
- data/test/myapp/config/environment.rb +10 -0
- data/test/myapp/config/environments/production.rb +0 -0
- data/test/myapp/config/routes.rb +3 -0
- data/test/passenger_test.rb +43 -0
- data/test/playground_test.rb +26 -0
- data/test/rails_dashboard_test.rb +37 -0
- data/test/rails_helper_test.rb +36 -0
- data/test/rails_test.rb +389 -0
- data/test/test_helper.rb +145 -0
- data/vanity.gemspec +26 -0
- metadata +202 -0
@@ -0,0 +1,150 @@
|
|
1
|
+
require "test/test_helper"
|
2
|
+
|
3
|
+
class ExperimentTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
metric "Happiness"
|
8
|
+
end
|
9
|
+
|
10
|
+
# -- Defining experiment --
|
11
|
+
|
12
|
+
def test_can_access_experiment_by_id
|
13
|
+
exp = new_ab_test(:ice_cream_flavor) { metrics :happiness }
|
14
|
+
assert_equal exp, experiment(:ice_cream_flavor)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_fail_when_defining_same_experiment_twice
|
18
|
+
File.open "tmp/experiments/ice_cream_flavor.rb", "w" do |f|
|
19
|
+
f.write <<-RUBY
|
20
|
+
ab_test "Ice Cream Flavor" do
|
21
|
+
metrics :happiness
|
22
|
+
end
|
23
|
+
ab_test "Ice Cream Flavor" do
|
24
|
+
metrics :happiness
|
25
|
+
end
|
26
|
+
RUBY
|
27
|
+
end
|
28
|
+
assert_raises NameError do
|
29
|
+
experiment(:ice_cream_flavor)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# -- Loading experiments --
|
35
|
+
|
36
|
+
def test_fails_if_cannot_load_named_experiment
|
37
|
+
assert_raises NameError do
|
38
|
+
experiment(:ice_cream_flavor)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_loading_experiment
|
43
|
+
File.open "tmp/experiments/ice_cream_flavor.rb", "w" do |f|
|
44
|
+
f.write <<-RUBY
|
45
|
+
ab_test "Ice Cream Flavor" do
|
46
|
+
def xmts
|
47
|
+
"x"
|
48
|
+
end
|
49
|
+
metrics :happiness
|
50
|
+
end
|
51
|
+
RUBY
|
52
|
+
end
|
53
|
+
assert_equal "x", experiment(:ice_cream_flavor).xmts
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_fails_if_error_loading_experiment
|
57
|
+
File.open "tmp/experiments/ice_cream_flavor.rb", "w" do |f|
|
58
|
+
f.write "fail 'yawn!'"
|
59
|
+
end
|
60
|
+
assert_raises NameError do
|
61
|
+
experiment(:ice_cream_flavor)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_complains_if_not_defined_where_expected
|
66
|
+
File.open "tmp/experiments/ice_cream_flavor.rb", "w" do |f|
|
67
|
+
f.write ""
|
68
|
+
end
|
69
|
+
assert_raises NameError do
|
70
|
+
experiment(:ice_cream_flavor)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_reloading_experiments
|
75
|
+
new_ab_test(:ab) { metrics :happiness }
|
76
|
+
new_ab_test(:cd) { metrics :happiness }
|
77
|
+
assert_equal 2, Vanity.playground.experiments.size
|
78
|
+
Vanity.playground.reload!
|
79
|
+
assert Vanity.playground.experiments.empty?
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# -- Attributes --
|
84
|
+
|
85
|
+
def test_experiment_mapping_name_to_id
|
86
|
+
experiment = new_ab_test("Ice Cream Flavor/Tastes") { metrics :happiness }
|
87
|
+
assert_equal "Ice Cream Flavor/Tastes", experiment.name
|
88
|
+
assert_equal :ice_cream_flavor_tastes, experiment.id
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_saving_experiment_after_definition
|
92
|
+
File.open "tmp/experiments/ice_cream_flavor.rb", "w" do |f|
|
93
|
+
f.write <<-RUBY
|
94
|
+
ab_test "Ice Cream Flavor" do
|
95
|
+
metrics :happiness
|
96
|
+
expects(:save)
|
97
|
+
end
|
98
|
+
RUBY
|
99
|
+
end
|
100
|
+
Vanity.playground.experiment(:ice_cream_flavor)
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_experiment_has_created_timestamp
|
104
|
+
new_ab_test(:ice_cream_flavor) { metrics :happiness }
|
105
|
+
assert_instance_of Time, experiment(:ice_cream_flavor).created_at
|
106
|
+
assert_in_delta experiment(:ice_cream_flavor).created_at.to_i, Time.now.to_i, 1
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_experiment_keeps_created_timestamp_across_definitions
|
110
|
+
past = Date.today - 1
|
111
|
+
Timecop.freeze past do
|
112
|
+
new_ab_test(:ice_cream_flavor) { metrics :happiness }
|
113
|
+
assert_equal past.to_time.to_i, experiment(:ice_cream_flavor).created_at.to_i
|
114
|
+
end
|
115
|
+
|
116
|
+
new_playground
|
117
|
+
metric :happiness
|
118
|
+
new_ab_test(:ice_cream_flavor) { metrics :happiness }
|
119
|
+
assert_equal past.to_time.to_i, experiment(:ice_cream_flavor).created_at.to_i
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_experiment_has_description
|
123
|
+
new_ab_test :ice_cream_flavor do
|
124
|
+
description "Because 31 is not enough ..."
|
125
|
+
metrics :happiness
|
126
|
+
end
|
127
|
+
assert_equal "Because 31 is not enough ...", experiment(:ice_cream_flavor).description
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_experiment_stores_nothing_when_collection_disabled
|
131
|
+
not_collecting!
|
132
|
+
new_ab_test(:ice_cream_flavor) { metrics :happiness }
|
133
|
+
experiment(:ice_cream_flavor).complete!
|
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
|
149
|
+
|
150
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
ab_test "Age and Zipcode" do
|
2
|
+
description <<-TEXT
|
3
|
+
Testing new registration form that asks for age and zipcode. Option A presents
|
4
|
+
the existing form, and option B adds age and zipcode fields.
|
5
|
+
|
6
|
+
We know option B will convert less, but higher quality leads. If we lose less
|
7
|
+
than 20% conversions, we're going to switch to option B.
|
8
|
+
TEXT
|
9
|
+
metrics :signups
|
10
|
+
|
11
|
+
complete_if do
|
12
|
+
alternatives.all? { |alt| alt.participants > 100 }
|
13
|
+
end
|
14
|
+
outcome_is do
|
15
|
+
one_field = alternative(false)
|
16
|
+
three_fields = alternative(true)
|
17
|
+
three_fields.conversion_rate >= 0.8 * one_field.conversion_rate ? three_fields : one_field
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,277 @@
|
|
1
|
+
require "test/test_helper"
|
2
|
+
|
3
|
+
class Sky < ActiveRecord::Base
|
4
|
+
connection.drop_table :skies if table_exists?
|
5
|
+
connection.create_table :skies do |t|
|
6
|
+
t.integer :height
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
named_scope :high, lambda { { :conditions=>"height >= 4" } }
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
context "ActiveRecord Metric" do
|
15
|
+
|
16
|
+
test "record count" do
|
17
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
18
|
+
f.write <<-RUBY
|
19
|
+
metric "Sky is limit" do
|
20
|
+
model Sky
|
21
|
+
end
|
22
|
+
RUBY
|
23
|
+
end
|
24
|
+
Vanity.playground.metrics
|
25
|
+
Sky.create!
|
26
|
+
assert_equal 1, Sky.count
|
27
|
+
assert_equal 1, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
28
|
+
end
|
29
|
+
|
30
|
+
test "record sum" do
|
31
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
32
|
+
f.write <<-RUBY
|
33
|
+
metric "Sky is limit" do
|
34
|
+
model Sky, :sum=>:height
|
35
|
+
end
|
36
|
+
RUBY
|
37
|
+
end
|
38
|
+
Vanity.playground.metrics
|
39
|
+
Sky.create! :height=>4
|
40
|
+
Sky.create! :height=>2
|
41
|
+
assert_equal 6, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
42
|
+
end
|
43
|
+
|
44
|
+
test "record average" do
|
45
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
46
|
+
f.write <<-RUBY
|
47
|
+
metric "Sky is limit" do
|
48
|
+
model Sky, :average=>:height
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
end
|
52
|
+
Vanity.playground.metrics
|
53
|
+
Sky.create! :height=>8
|
54
|
+
Sky.create! :height=>2
|
55
|
+
assert_equal 5, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
56
|
+
end
|
57
|
+
|
58
|
+
test "record minimum" do
|
59
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
60
|
+
f.write <<-RUBY
|
61
|
+
metric "Sky is limit" do
|
62
|
+
model Sky, :minimum=>:height
|
63
|
+
end
|
64
|
+
RUBY
|
65
|
+
end
|
66
|
+
Vanity.playground.metrics
|
67
|
+
Sky.create! :height=>4
|
68
|
+
Sky.create! :height=>2
|
69
|
+
assert_equal 2, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
70
|
+
end
|
71
|
+
|
72
|
+
test "record maximum" do
|
73
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
74
|
+
f.write <<-RUBY
|
75
|
+
metric "Sky is limit" do
|
76
|
+
model Sky, :maximum=>:height
|
77
|
+
end
|
78
|
+
RUBY
|
79
|
+
end
|
80
|
+
Vanity.playground.metrics
|
81
|
+
Sky.create! :height=>4
|
82
|
+
Sky.create! :height=>2
|
83
|
+
assert_equal 4, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
84
|
+
end
|
85
|
+
|
86
|
+
test "with conditions" do
|
87
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
88
|
+
f.write <<-RUBY
|
89
|
+
metric "Sky is limit" do
|
90
|
+
model Sky, :sum=>:height, :conditions=>["height > 4"]
|
91
|
+
end
|
92
|
+
RUBY
|
93
|
+
end
|
94
|
+
Vanity.playground.metrics
|
95
|
+
high_skies = 0
|
96
|
+
metric(:sky_is_limit).hook do |metric_id, timestamp, height|
|
97
|
+
assert height > 4
|
98
|
+
high_skies += height
|
99
|
+
end
|
100
|
+
[nil,5,3,6].each do |height|
|
101
|
+
Sky.create! :height=>height
|
102
|
+
end
|
103
|
+
assert_equal 11, Vanity::Metric.data(metric(:sky_is_limit)).sum(&:last)
|
104
|
+
assert_equal 11, high_skies
|
105
|
+
end
|
106
|
+
|
107
|
+
test "with scope" do
|
108
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
109
|
+
f.write <<-RUBY
|
110
|
+
metric "Sky is limit" do
|
111
|
+
model Sky.high
|
112
|
+
end
|
113
|
+
RUBY
|
114
|
+
end
|
115
|
+
Vanity.playground.metrics
|
116
|
+
total = 0
|
117
|
+
metric(:sky_is_limit).hook do |metric_id, timestamp, count|
|
118
|
+
total += count
|
119
|
+
end
|
120
|
+
Sky.create! :height=>4
|
121
|
+
Sky.create! :height=>2
|
122
|
+
assert_equal 1, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
123
|
+
assert_equal 1, total
|
124
|
+
end
|
125
|
+
|
126
|
+
test "with timestamp" do
|
127
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
128
|
+
f.write <<-RUBY
|
129
|
+
metric "Sky is limit" do
|
130
|
+
model Sky, :timestamp => :created_at
|
131
|
+
end
|
132
|
+
RUBY
|
133
|
+
end
|
134
|
+
Vanity.playground.metrics
|
135
|
+
Sky.create!
|
136
|
+
assert_equal 1, Sky.count
|
137
|
+
assert_equal 1, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
138
|
+
end
|
139
|
+
|
140
|
+
test "with timestamp and table" do
|
141
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
142
|
+
f.write <<-RUBY
|
143
|
+
metric "Sky is limit" do
|
144
|
+
model Sky, :timestamp => 'skies.created_at'
|
145
|
+
end
|
146
|
+
RUBY
|
147
|
+
end
|
148
|
+
Vanity.playground.metrics
|
149
|
+
Sky.create!
|
150
|
+
assert_equal 1, Sky.count
|
151
|
+
assert_equal 1, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
152
|
+
end
|
153
|
+
|
154
|
+
test "hooks" do
|
155
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
156
|
+
f.write <<-RUBY
|
157
|
+
metric "Sky is limit" do
|
158
|
+
model Sky, :sum=>:height
|
159
|
+
end
|
160
|
+
RUBY
|
161
|
+
end
|
162
|
+
Vanity.playground.metrics
|
163
|
+
total = 0
|
164
|
+
metric(:sky_is_limit).hook do |metric_id, timestamp, count|
|
165
|
+
assert_equal :sky_is_limit, metric_id
|
166
|
+
assert_in_delta Time.now.to_i, timestamp.to_i, 1
|
167
|
+
total += count
|
168
|
+
end
|
169
|
+
Sky.create! :height=>4
|
170
|
+
assert_equal 4, total
|
171
|
+
end
|
172
|
+
|
173
|
+
test "no hooks when metrics disabled" do
|
174
|
+
not_collecting!
|
175
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
176
|
+
f.write <<-RUBY
|
177
|
+
metric "Sky is limit" do
|
178
|
+
model Sky, :sum=>:height
|
179
|
+
end
|
180
|
+
RUBY
|
181
|
+
end
|
182
|
+
Vanity.playground.metrics
|
183
|
+
total = 0
|
184
|
+
metric(:sky_is_limit).hook do |metric_id, timestamp, count|
|
185
|
+
total += count
|
186
|
+
end
|
187
|
+
Sky.create! :height=>4
|
188
|
+
assert_equal 0, total
|
189
|
+
end
|
190
|
+
|
191
|
+
test "after_create not after_save" do
|
192
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
193
|
+
f.write <<-RUBY
|
194
|
+
metric "Sky is limit" do
|
195
|
+
model Sky
|
196
|
+
end
|
197
|
+
RUBY
|
198
|
+
end
|
199
|
+
Vanity.playground.metrics
|
200
|
+
once = nil
|
201
|
+
metric(:sky_is_limit).hook do
|
202
|
+
fail "Metric tracked twice" if once
|
203
|
+
once = true
|
204
|
+
end
|
205
|
+
Sky.create!
|
206
|
+
Sky.last.update_attributes :height=>4
|
207
|
+
end
|
208
|
+
|
209
|
+
test "with after_save" do
|
210
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
211
|
+
f.write <<-RUBY
|
212
|
+
metric "Sky is limit" do
|
213
|
+
model Sky, :conditions=>["height > 3"]
|
214
|
+
Sky.after_save { |sky| track! if sky.height_changed? && sky.height > 3 }
|
215
|
+
end
|
216
|
+
RUBY
|
217
|
+
end
|
218
|
+
Vanity.playground.metrics
|
219
|
+
times = 0
|
220
|
+
metric(:sky_is_limit).hook do
|
221
|
+
times += 1
|
222
|
+
end
|
223
|
+
Sky.create!
|
224
|
+
(1..5).each do |height|
|
225
|
+
Sky.last.update_attributes! :height=>height
|
226
|
+
end
|
227
|
+
assert_equal 2, times
|
228
|
+
end
|
229
|
+
|
230
|
+
test "do it youself" do
|
231
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
232
|
+
f.write <<-RUBY
|
233
|
+
metric "Sky is limit" do
|
234
|
+
Sky.after_save { |sky| track! if sky.height_changed? && sky.height > 3 }
|
235
|
+
end
|
236
|
+
RUBY
|
237
|
+
end
|
238
|
+
Vanity.playground.metrics
|
239
|
+
(1..5).each do |height|
|
240
|
+
Sky.create! :height=>height
|
241
|
+
end
|
242
|
+
Sky.first.update_attributes! :height=>4
|
243
|
+
assert_equal 3, Vanity::Metric.data(metric(:sky_is_limit)).last.last
|
244
|
+
end
|
245
|
+
|
246
|
+
test "last update for new metric" do
|
247
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
248
|
+
f.write <<-RUBY
|
249
|
+
metric "Sky is limit" do
|
250
|
+
model Sky
|
251
|
+
end
|
252
|
+
RUBY
|
253
|
+
end
|
254
|
+
assert_nil metric(:sky_is_limit).last_update_at
|
255
|
+
end
|
256
|
+
|
257
|
+
test "last update with records" do
|
258
|
+
File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
|
259
|
+
f.write <<-RUBY
|
260
|
+
metric "Sky is limit" do
|
261
|
+
model Sky
|
262
|
+
end
|
263
|
+
RUBY
|
264
|
+
end
|
265
|
+
Sky.create! :height=>1
|
266
|
+
Timecop.freeze Time.now + 1.day do
|
267
|
+
Sky.create! :height=>1
|
268
|
+
end
|
269
|
+
assert_in_delta metric(:sky_is_limit).last_update_at.to_i, (Time.now + 1.day).to_i, 1
|
270
|
+
end
|
271
|
+
|
272
|
+
teardown do
|
273
|
+
Sky.delete_all
|
274
|
+
Sky.after_create.clear
|
275
|
+
Sky.after_save.clear
|
276
|
+
end
|
277
|
+
end
|