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
data/vanity.gemspec CHANGED
@@ -1,10 +1,10 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "vanity"
3
- spec.version = "1.3.0"
3
+ spec.version = "1.4.0.beta"
4
4
  spec.author = "Assaf Arkin"
5
5
  spec.email = "assaf@labnotes.org"
6
6
  spec.homepage = "http://vanity.labnotes.org"
7
- spec.summary = "Experience Driven Development framework for Rails"
7
+ spec.summary = "Experience Driven Development framework for Ruby"
8
8
  spec.description = "Mirror, mirror on the wall ..."
9
9
  spec.post_install_message = "To get started run vanity --help"
10
10
 
@@ -15,4 +15,8 @@ Gem::Specification.new do |spec|
15
15
  spec.extra_rdoc_files = "README.rdoc", "CHANGELOG"
16
16
  spec.rdoc_options = "--title", "Vanity #{spec.version}", "--main", "README.rdoc",
17
17
  "--webcvs", "http://github.com/assaf/#{spec.name}"
18
+
19
+ spec.required_ruby_version = '>= 1.8.7'
20
+ spec.add_dependency "redis", "~>2.0"
21
+ spec.add_dependency "redis-namespace", "~>0.7"
18
22
  end
metadata CHANGED
@@ -1,12 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vanity
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 999657272
5
+ prerelease: true
5
6
  segments:
6
7
  - 1
7
- - 3
8
+ - 4
8
9
  - 0
9
- version: 1.3.0
10
+ - beta
11
+ version: 1.4.0.beta
10
12
  platform: ruby
11
13
  authors:
12
14
  - Assaf Arkin
@@ -14,10 +16,39 @@ autorequire:
14
16
  bindir: bin
15
17
  cert_chain: []
16
18
 
17
- date: 2010-03-01 00:00:00 -08:00
19
+ date: 2010-07-27 00:00:00 -07:00
18
20
  default_executable:
19
- dependencies: []
20
-
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: redis
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 2
33
+ - 0
34
+ version: "2.0"
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: redis-namespace
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 5
46
+ segments:
47
+ - 0
48
+ - 7
49
+ version: "0.7"
50
+ type: :runtime
51
+ version_requirements: *id002
21
52
  description: Mirror, mirror on the wall ...
22
53
  email: assaf@labnotes.org
23
54
  executables:
@@ -29,10 +60,14 @@ extra_rdoc_files:
29
60
  - CHANGELOG
30
61
  files:
31
62
  - bin/vanity
63
+ - lib/vanity/adapters/abstract_adapter.rb
64
+ - lib/vanity/adapters/mock_adapter.rb
65
+ - lib/vanity/adapters/mongo_adapter.rb
66
+ - lib/vanity/adapters/redis_adapter.rb
32
67
  - lib/vanity/backport.rb
33
68
  - lib/vanity/commands/list.rb
34
69
  - lib/vanity/commands/report.rb
35
- - lib/vanity/commands.rb
70
+ - lib/vanity/commands/upgrade.rb
36
71
  - lib/vanity/experiment/ab_test.rb
37
72
  - lib/vanity/experiment/base.rb
38
73
  - lib/vanity/frameworks/rails.rb
@@ -40,7 +75,7 @@ files:
40
75
  - lib/vanity/metric/active_record.rb
41
76
  - lib/vanity/metric/base.rb
42
77
  - lib/vanity/metric/google_analytics.rb
43
- - lib/vanity/mock_redis.rb
78
+ - lib/vanity/metric/remote.rb
44
79
  - lib/vanity/playground.rb
45
80
  - lib/vanity/templates/_ab_test.erb
46
81
  - lib/vanity/templates/_experiment.erb
@@ -53,79 +88,37 @@ files:
53
88
  - lib/vanity/templates/vanity.css
54
89
  - lib/vanity/templates/vanity.js
55
90
  - lib/vanity.rb
56
- - vendor/cache/actionmailer-2.3.5.gem
57
- - vendor/cache/actionpack-2.3.5.gem
58
- - vendor/cache/activerecord-2.3.5.gem
59
- - vendor/cache/activeresource-2.3.5.gem
60
- - vendor/cache/activesupport-2.3.5.gem
61
- - vendor/cache/autotest-4.2.7.gem
62
- - vendor/cache/autotest-fsevent-0.2.1.gem
63
- - vendor/cache/autotest-growl-0.2.0.gem
64
- - vendor/cache/bundler-0.9.7.gem
65
- - vendor/cache/classifier-1.3.1.gem
66
- - vendor/cache/directory_watcher-1.3.1.gem
67
- - vendor/cache/fastthread-1.0.7.gem
68
- - vendor/cache/garb-0.7.0.gem
69
- - vendor/cache/happymapper-0.3.0.gem
70
- - vendor/cache/jekyll-0.5.7.gem
71
- - vendor/cache/libxml-ruby-1.1.3.gem
72
- - vendor/cache/liquid-2.0.0.gem
73
- - vendor/cache/maruku-0.6.0.gem
74
- - vendor/cache/mocha-0.9.8.gem
75
- - vendor/cache/open4-1.0.1.gem
76
- - vendor/cache/passenger-2.2.9.gem
77
- - vendor/cache/rack-1.0.1.gem
78
- - vendor/cache/rails-2.3.5.gem
79
- - vendor/cache/rake-0.8.7.gem
80
- - vendor/cache/RedCloth-4.2.2.gem
81
- - vendor/cache/rubygems-update-1.3.5.gem
82
- - vendor/cache/shoulda-2.10.3.gem
83
- - vendor/cache/sqlite3-ruby-1.2.5.gem
84
- - vendor/cache/stemmer-1.0.1.gem
85
- - vendor/cache/syntax-1.0.0.gem
86
- - vendor/cache/sys-uname-0.8.4.gem
87
- - vendor/cache/timecop-0.3.4.gem
88
- - vendor/redis-rb/bench.rb
89
- - vendor/redis-rb/benchmarking/suite.rb
90
- - vendor/redis-rb/benchmarking/worker.rb
91
- - vendor/redis-rb/bin/distredis
92
- - vendor/redis-rb/examples/basic.rb
93
- - vendor/redis-rb/examples/incr-decr.rb
94
- - vendor/redis-rb/examples/list.rb
95
- - vendor/redis-rb/examples/sets.rb
96
- - vendor/redis-rb/lib/dist_redis.rb
97
- - vendor/redis-rb/lib/hash_ring.rb
98
- - vendor/redis-rb/lib/pipeline.rb
99
- - vendor/redis-rb/lib/redis/raketasks.rb
100
- - vendor/redis-rb/lib/redis.rb
101
- - vendor/redis-rb/LICENSE
102
- - vendor/redis-rb/profile.rb
103
- - vendor/redis-rb/Rakefile
104
- - vendor/redis-rb/README.markdown
105
- - vendor/redis-rb/redis-rb.gemspec
106
- - vendor/redis-rb/spec/redis_spec.rb
107
- - vendor/redis-rb/spec/spec_helper.rb
108
- - vendor/redis-rb/speed.rb
109
- - vendor/redis-rb/tasks/redis.tasks.rb
110
- - test/ab_test_test.rb
111
- - test/experiment_test.rb
91
+ - test/experiment/ab_test.rb
92
+ - test/experiment/base_test.rb
112
93
  - test/experiments/age_and_zipcode.rb
113
94
  - test/experiments/metrics/cheers.rb
114
95
  - test/experiments/metrics/signups.rb
115
96
  - test/experiments/metrics/yawns.rb
116
97
  - test/experiments/null_abc.rb
117
- - test/metric_test.rb
98
+ - test/metric/active_record_test.rb
99
+ - test/metric/base_test.rb
100
+ - test/metric/google_analytics_test.rb
101
+ - test/metric/remote_test.rb
118
102
  - test/myapp/app/controllers/application_controller.rb
103
+ - test/myapp/app/controllers/application_controller.rbc
119
104
  - test/myapp/app/controllers/main_controller.rb
105
+ - test/myapp/app/controllers/main_controller.rbc
120
106
  - test/myapp/config/boot.rb
107
+ - test/myapp/config/boot.rbc
121
108
  - test/myapp/config/environment.rb
109
+ - test/myapp/config/environment.rbc
122
110
  - test/myapp/config/environments/production.rb
123
111
  - test/myapp/config/routes.rb
112
+ - test/myapp/config/routes.rbc
124
113
  - test/myapp/log/production.log
125
114
  - test/passenger_test.rb
115
+ - test/passenger_test.rbc
126
116
  - test/playground_test.rb
117
+ - test/playground_test.rbc
127
118
  - test/rails_test.rb
119
+ - test/rails_test.rbc
128
120
  - test/test_helper.rb
121
+ - test/test_helper.rbc
129
122
  - CHANGELOG
130
123
  - MIT-LICENSE
131
124
  - README.rdoc
@@ -139,7 +132,7 @@ licenses: []
139
132
  post_install_message: To get started run vanity --help
140
133
  rdoc_options:
141
134
  - --title
142
- - Vanity 1.3.0
135
+ - Vanity 1.4.0.beta
143
136
  - --main
144
137
  - README.rdoc
145
138
  - --webcvs
@@ -147,25 +140,33 @@ rdoc_options:
147
140
  require_paths:
148
141
  - lib
149
142
  required_ruby_version: !ruby/object:Gem::Requirement
143
+ none: false
150
144
  requirements:
151
145
  - - ">="
152
146
  - !ruby/object:Gem::Version
147
+ hash: 57
153
148
  segments:
154
- - 0
155
- version: "0"
149
+ - 1
150
+ - 8
151
+ - 7
152
+ version: 1.8.7
156
153
  required_rubygems_version: !ruby/object:Gem::Requirement
154
+ none: false
157
155
  requirements:
158
- - - ">="
156
+ - - ">"
159
157
  - !ruby/object:Gem::Version
158
+ hash: 25
160
159
  segments:
161
- - 0
162
- version: "0"
160
+ - 1
161
+ - 3
162
+ - 1
163
+ version: 1.3.1
163
164
  requirements: []
164
165
 
165
166
  rubyforge_project:
166
- rubygems_version: 1.3.6
167
+ rubygems_version: 1.3.7
167
168
  signing_key:
168
169
  specification_version: 3
169
- summary: Experience Driven Development framework for Rails
170
+ summary: Experience Driven Development framework for Ruby
170
171
  test_files: []
171
172
 
@@ -1,2 +0,0 @@
1
- require "vanity/commands/report"
2
- require "vanity/commands/list"
@@ -1,76 +0,0 @@
1
- module Vanity
2
- # The Redis you should never use in production.
3
- class MockRedis
4
- @@hash = {}
5
-
6
- def initialize(options = {})
7
- end
8
-
9
- def [](key)
10
- @@hash[key]
11
- end
12
-
13
- def []=(key, value)
14
- @@hash[key] = value.to_s
15
- end
16
-
17
- def del(*keys)
18
- keys.flatten.each do |key|
19
- @@hash.delete key
20
- end
21
- end
22
-
23
- def setnx(key, value)
24
- @@hash[key] = value.to_s unless @@hash.has_key?(key)
25
- end
26
-
27
- def incr(key)
28
- @@hash[key] = (@@hash[key].to_i + 1).to_s
29
- end
30
-
31
- def incrby(key, value)
32
- @@hash[key] = (@@hash[key].to_i + value).to_s
33
- end
34
-
35
- def mget(keys)
36
- @@hash.values_at(*keys)
37
- end
38
-
39
- def exists(key)
40
- @@hash.has_key?(key)
41
- end
42
-
43
- def keys(pattern)
44
- regexp = Regexp.new(pattern.split("*").map { |r| Regexp.escape(r) }.join(".*"))
45
- @@hash.keys.select { |key| key =~ regexp }
46
- end
47
-
48
- def flushdb
49
- @@hash.clear
50
- end
51
-
52
- def sismember(key, value)
53
- case set = @@hash[key]
54
- when nil ; false
55
- when Set ; set.member?(value)
56
- else fail "Not a set"
57
- end
58
- end
59
-
60
- def sadd(key, value)
61
- case set = @@hash[key]
62
- when nil ; @@hash[key] = Set.new([value])
63
- when Set ; set.add value
64
- else fail "Not a set"
65
- end
66
- end
67
-
68
- def scard(key)
69
- case set = @@hash[key]
70
- when nil ; 0
71
- when Set ; set.size
72
- else fail "Not a set"
73
- end
74
- end
75
- end
76
- end
data/test/metric_test.rb DELETED
@@ -1,622 +0,0 @@
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 "Metric" do
15
-
16
- # -- Via the playground --
17
-
18
- context "playground" do
19
-
20
- test "knows all loaded metrics" do
21
- metric "Yawns/sec", "Cheers/sec"
22
- assert Vanity.playground.metrics.keys.include?(:yawns_sec)
23
- assert Vanity.playground.metrics.keys.include?(:cheers_sec)
24
- end
25
-
26
- test "loads metric definitions" do
27
- File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
28
- f.write <<-RUBY
29
- metric "Yawns/sec" do
30
- def xmts
31
- "x"
32
- end
33
- end
34
- RUBY
35
- end
36
- assert_equal "x", Vanity.playground.metric(:yawns_sec).xmts
37
- end
38
-
39
- test "bubbles up loaded metrics" do
40
- File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
41
- f.write "fail 'yawn!'"
42
- end
43
- assert_raises NameError do
44
- Vanity.playground.metric(:yawns_sec)
45
- end
46
- end
47
-
48
- test "map identifier from file name" do
49
- File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
50
- f.write <<-RUBY
51
- metric "yawns/hour" do
52
- end
53
- RUBY
54
- end
55
- assert Vanity.playground.metric(:yawns_sec)
56
- end
57
-
58
- test "fails tracking unknown metric" do
59
- assert_raises NameError do
60
- Vanity.playground.track! :yawns_sec
61
- end
62
- end
63
-
64
- test "reloading metrics" do
65
- metric "Yawns/sec", "Cheers/sec"
66
- Vanity.playground.metric(:yawns_sec)
67
- Vanity.playground.metric(:cheers_sec)
68
- assert 2, Vanity.playground.metrics.size
69
- metrics = Vanity.playground.metrics.values
70
- Vanity.playground.reload!
71
- assert 2, Vanity.playground.metrics.size
72
- assert_not_equal metrics, Vanity.playground.metrics.values
73
- end
74
-
75
- test "ignores undefined metrics in database" do
76
- metric "Yawns/sec"
77
- Vanity.playground.reload!
78
- assert Vanity.playground.metrics.empty?
79
- end
80
-
81
- end
82
-
83
-
84
- # -- Tracking --
85
-
86
- context "tracking" do
87
- test "can count" do
88
- metric "Yawns/sec", "Cheers/sec"
89
- 4.times { Vanity.playground.track! :yawns_sec }
90
- 2.times { Vanity.playground.track! :cheers_sec }
91
- yawns = Vanity.playground.metric(:yawns_sec).values(today, today).first
92
- cheers = Vanity.playground.metric(:cheers_sec).values(today, today).first
93
- assert yawns = 2 * cheers
94
- end
95
-
96
- test "can tell the time" do
97
- metric "Yawns/sec"
98
- Timecop.travel(today - 4) { 4.times { Vanity.playground.track! :yawns_sec } }
99
- Timecop.travel(today - 2) { 2.times { Vanity.playground.track! :yawns_sec } }
100
- 1.times { Vanity.playground.track! :yawns_sec }
101
- boredom = Vanity.playground.metric(:yawns_sec).values(today - 5, today)
102
- assert_equal [0,4,0,2,0,1], boredom
103
- end
104
-
105
- test "with no value" do
106
- metric "Yawns/sec", "Cheers/sec", "Looks"
107
- Vanity.playground.track! :yawns_sec, 0
108
- Vanity.playground.track! :cheers_sec, -1
109
- Vanity.playground.track! :looks, 10
110
- assert_equal 0, Vanity.playground.metric(:yawns_sec).values(today, today).sum
111
- assert_equal 0, Vanity.playground.metric(:cheers_sec).values(today, today).sum
112
- assert_equal 10, Vanity.playground.metric(:looks).values(today, today).sum
113
- end
114
-
115
- test "with count" do
116
- metric "Yawns/sec"
117
- Timecop.travel(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
118
- Timecop.travel(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
119
- Vanity.playground.track! :yawns_sec
120
- boredom = Vanity.playground.metric(:yawns_sec).values(today - 5, today)
121
- assert_equal [0,4,0,2,0,1], boredom
122
- end
123
-
124
- test "runs hook" do
125
- metric "Many Happy Returns"
126
- total = 0
127
- Vanity.playground.metric(:many_happy_returns).hook do |metric_id, timestamp, count|
128
- assert_equal :many_happy_returns, metric_id
129
- assert_in_delta Time.now.to_i, timestamp.to_i, 1
130
- total += count
131
- end
132
- Vanity.playground.track! :many_happy_returns, 6
133
- assert_equal 6, 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
- # -- Metric name --
157
-
158
- context "name" do
159
- test "can be whatever" do
160
- File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
161
- f.write <<-RUBY
162
- metric "Yawns per second" do
163
- end
164
- RUBY
165
- end
166
- assert_equal "Yawns per second", Vanity.playground.metric(:yawns_sec).name
167
- end
168
- end
169
-
170
-
171
- # -- Description helper --
172
-
173
- context "description" do
174
- test "metric with description" do
175
- File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
176
- f.write <<-RUBY
177
- metric "Yawns/sec" do
178
- description "Am I that boring?"
179
- end
180
- RUBY
181
- end
182
- assert_equal "Am I that boring?", Vanity::Metric.description(Vanity.playground.metric(:yawns_sec))
183
- end
184
-
185
- test "metric without description" do
186
- File.open "tmp/experiments/metrics/yawns_sec.rb", "w" do |f|
187
- f.write <<-RUBY
188
- metric "Yawns/sec" do
189
- end
190
- RUBY
191
- end
192
- assert_nil Vanity::Metric.description(Vanity.playground.metric(:yawns_sec))
193
- end
194
-
195
- test "metric with no method description" do
196
- metric = Object.new
197
- assert_nil Vanity::Metric.description(metric)
198
- end
199
- end
200
-
201
-
202
- # -- Metric bounds --
203
-
204
- context "bounds" do
205
- test "metric with bounds" do
206
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
207
- f.write <<-RUBY
208
- metric "Sky is limit" do
209
- def bounds
210
- [6,12]
211
- end
212
- end
213
- RUBY
214
- end
215
- assert_equal [6,12], Vanity::Metric.bounds(Vanity.playground.metric(:sky_is_limit))
216
- end
217
-
218
- test "metric without bounds" do
219
- metric "Sky is limit"
220
- assert_equal [nil, nil], Vanity::Metric.bounds(Vanity.playground.metric(:sky_is_limit))
221
- end
222
-
223
- test "metric with no method bounds" do
224
- metric = Object.new
225
- assert_equal [nil, nil], Vanity::Metric.bounds(metric)
226
- end
227
- end
228
-
229
-
230
- # -- Timestamp --
231
-
232
- context "created_at" do
233
- test "for new metric" do
234
- metric "Coolness"
235
- metric = Vanity.playground.metric(:coolness)
236
- assert_instance_of Time, metric.created_at
237
- assert_in_delta metric.created_at.to_i, Time.now.to_i, 1
238
- end
239
-
240
- test "across restarts" do
241
- past = Date.today - 1
242
- Timecop.travel past do
243
- metric "Coolness"
244
- coolness = Vanity.playground.metric(:coolness)
245
- assert_in_delta coolness.created_at.to_i, past.to_time.to_i, 1
246
- end
247
-
248
- new_playground
249
- metric "Coolness"
250
- new_cool = Vanity.playground.metric(:coolness)
251
- assert_in_delta new_cool.created_at.to_i, past.to_time.to_i, 1
252
- end
253
- end
254
-
255
-
256
- # -- Data --
257
-
258
- context "data" do
259
- test "explicit dates" do
260
- metric "Yawns/sec"
261
- Timecop.travel(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
262
- Timecop.travel(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
263
- Vanity.playground.track! :yawns_sec
264
- boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec), Date.today - 5, Date.today)
265
- assert_equal [[today - 5, 0], [today - 4, 4], [today - 3, 0], [today - 2, 2], [today - 1, 0], [today, 1]], boredom
266
- end
267
-
268
- test "start date only" do
269
- metric "Yawns/sec"
270
- Timecop.travel(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
271
- Timecop.travel(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
272
- Vanity.playground.track! :yawns_sec
273
- boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec), Date.today - 4)
274
- assert_equal [[today - 4, 4], [today - 3, 0], [today - 2, 2], [today - 1, 0], [today, 1]], boredom
275
- end
276
-
277
- test "start date and duration" do
278
- metric "Yawns/sec"
279
- Timecop.travel(today - 4) { Vanity.playground.track! :yawns_sec, 4 }
280
- Timecop.travel(today - 2) { Vanity.playground.track! :yawns_sec, 2 }
281
- Vanity.playground.track! :yawns_sec
282
- boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec), 5)
283
- assert_equal [[today - 4, 4], [today - 3, 0], [today - 2, 2], [today - 1, 0], [today, 1]], boredom
284
- end
285
-
286
- test "no data" do
287
- metric "Yawns/sec"
288
- boredom = Vanity::Metric.data(Vanity.playground.metric(:yawns_sec))
289
- assert_equal 90, boredom.size
290
- assert_equal [today - 89, 0], boredom.first
291
- assert_equal [today, 0], boredom.last
292
- end
293
-
294
- test "using custom values method" do
295
- File.open "tmp/experiments/metrics/hours_in_day.rb", "w" do |f|
296
- f.write <<-RUBY
297
- metric "Hours in day" do
298
- def values(from, to)
299
- (from..to).map { |d| 24 }
300
- end
301
- end
302
- RUBY
303
- end
304
- data = Vanity::Metric.data(Vanity.playground.metric(:hours_in_day))
305
- assert_equal [24] * 90, data.map(&:last)
306
- end
307
-
308
- end
309
-
310
-
311
- # -- ActiveRecord --
312
-
313
- context "ActiveRecord" do
314
-
315
- test "record count" do
316
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
317
- f.write <<-RUBY
318
- metric "Sky is limit" do
319
- model Sky
320
- end
321
- RUBY
322
- end
323
- Vanity.playground.metrics
324
- Sky.create!
325
- assert_equal 1, Sky.count
326
- assert_equal 1, Vanity::Metric.data(metric(:sky_is_limit)).last.last
327
- end
328
-
329
- test "record sum" do
330
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
331
- f.write <<-RUBY
332
- metric "Sky is limit" do
333
- model Sky, :sum=>:height
334
- end
335
- RUBY
336
- end
337
- Vanity.playground.metrics
338
- Sky.create! :height=>4
339
- Sky.create! :height=>2
340
- assert_equal 6, Vanity::Metric.data(metric(:sky_is_limit)).last.last
341
- end
342
-
343
- test "record average" do
344
- Sky.aggregates
345
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
346
- f.write <<-RUBY
347
- metric "Sky is limit" do
348
- model Sky, :average=>:height
349
- end
350
- RUBY
351
- end
352
- Vanity.playground.metrics
353
- Sky.create! :height=>4
354
- Sky.create! :height=>2
355
- assert_equal 3, Vanity::Metric.data(metric(:sky_is_limit)).last.last
356
- end
357
-
358
- test "record minimum" do
359
- Sky.aggregates
360
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
361
- f.write <<-RUBY
362
- metric "Sky is limit" do
363
- model Sky, :minimum=>:height
364
- end
365
- RUBY
366
- end
367
- Vanity.playground.metrics
368
- Sky.create! :height=>4
369
- Sky.create! :height=>2
370
- assert_equal 2, Vanity::Metric.data(metric(:sky_is_limit)).last.last
371
- end
372
-
373
- test "record maximum" do
374
- Sky.aggregates
375
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
376
- f.write <<-RUBY
377
- metric "Sky is limit" do
378
- model Sky, :maximum=>:height
379
- end
380
- RUBY
381
- end
382
- Vanity.playground.metrics
383
- Sky.create! :height=>4
384
- Sky.create! :height=>2
385
- assert_equal 4, Vanity::Metric.data(metric(:sky_is_limit)).last.last
386
- end
387
-
388
- test "with conditions" do
389
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
390
- f.write <<-RUBY
391
- metric "Sky is limit" do
392
- model Sky, :sum=>:height, :conditions=>["height > 4"]
393
- end
394
- RUBY
395
- end
396
- Vanity.playground.metrics
397
- high_skies = 0
398
- metric(:sky_is_limit).hook do |metric_id, timestamp, height|
399
- assert height > 4
400
- high_skies += height
401
- end
402
- [nil,5,3,6].each do |height|
403
- Sky.create! :height=>height
404
- end
405
- assert_equal 11, Vanity::Metric.data(metric(:sky_is_limit)).sum(&:last)
406
- assert_equal 11, high_skies
407
- end
408
-
409
- test "with scope" do
410
- Sky.aggregates
411
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
412
- f.write <<-RUBY
413
- metric "Sky is limit" do
414
- model Sky.high
415
- end
416
- RUBY
417
- end
418
- Vanity.playground.metrics
419
- total = 0
420
- metric(:sky_is_limit).hook do |metric_id, timestamp, count|
421
- total += count
422
- end
423
- Sky.create! :height=>4
424
- Sky.create! :height=>2
425
- assert_equal 1, Vanity::Metric.data(metric(:sky_is_limit)).last.last
426
- assert_equal 1, total
427
- end
428
-
429
- test "hooks" do
430
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
431
- f.write <<-RUBY
432
- metric "Sky is limit" do
433
- model Sky, :sum=>:height
434
- end
435
- RUBY
436
- end
437
- Vanity.playground.metrics
438
- total = 0
439
- metric(:sky_is_limit).hook do |metric_id, timestamp, count|
440
- assert_equal :sky_is_limit, metric_id
441
- assert_in_delta Time.now.to_i, timestamp.to_i, 1
442
- total += count
443
- end
444
- Sky.create! :height=>4
445
- assert_equal 4, total
446
- end
447
-
448
- test "after_create not after_save" do
449
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
450
- f.write <<-RUBY
451
- metric "Sky is limit" do
452
- model Sky
453
- end
454
- RUBY
455
- end
456
- Vanity.playground.metrics
457
- once = nil
458
- metric(:sky_is_limit).hook do
459
- fail "Metric tracked twice" if once
460
- once = true
461
- end
462
- Sky.create!
463
- Sky.last.update_attributes :height=>4
464
- end
465
-
466
- test "with after_save" do
467
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
468
- f.write <<-RUBY
469
- metric "Sky is limit" do
470
- model Sky, :conditions=>["height > 3"]
471
- Sky.after_save { |sky| track! if sky.height_changed? && sky.height > 3 }
472
- end
473
- RUBY
474
- end
475
- Vanity.playground.metrics
476
- times = 0
477
- metric(:sky_is_limit).hook do
478
- times += 1
479
- end
480
- Sky.create!
481
- (1..5).each do |height|
482
- Sky.last.update_attributes! :height=>height
483
- end
484
- assert_equal 2, times
485
- end
486
-
487
- test "do it youself" do
488
- File.open "tmp/experiments/metrics/sky_is_limit.rb", "w" do |f|
489
- f.write <<-RUBY
490
- metric "Sky is limit" do
491
- Sky.after_save { |sky| track! if sky.height_changed? && sky.height > 3 }
492
- end
493
- RUBY
494
- end
495
- Vanity.playground.metrics
496
- (1..5).each do |height|
497
- Sky.create! :height=>height
498
- end
499
- Sky.first.update_attributes! :height=>4
500
- assert_equal 3, Vanity::Metric.data(metric(:sky_is_limit)).last.last
501
- end
502
-
503
- end
504
-
505
- # -- Google Analytics --
506
-
507
- context "Google Analytics" do
508
-
509
- setup do
510
- File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
511
- f.write <<-RUBY
512
- metric "GA" do
513
- google_analytics "UA2"
514
- end
515
- RUBY
516
- end
517
- end
518
-
519
- GA_RESULT = Struct.new(:date, :pageviews, :visits)
520
- GA_PROFILE = Struct.new(:web_property_id)
521
-
522
- test "fail if Garb not available" do
523
- File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
524
- f.write <<-RUBY
525
- metric "GA" do
526
- expects(:require).raises LoadError
527
- google_analytics "UA2"
528
- end
529
- RUBY
530
- end
531
- assert_raise LoadError do
532
- Vanity.playground.metrics
533
- end
534
- end
535
-
536
- test "constructs a report" do
537
- Vanity.playground.metrics
538
- assert metric(:ga).report
539
- end
540
-
541
- test "default to pageviews metric" do
542
- Vanity.playground.metrics
543
- assert_equal [:pageviews], metric(:ga).report.metrics.elements
544
- end
545
-
546
- test "apply data dimension and sort" do
547
- Vanity.playground.metrics
548
- assert_equal [:date], metric(:ga).report.dimensions.elements
549
- assert_equal [:date], metric(:ga).report.sort.elements
550
- end
551
-
552
- test "accept other metrics" do
553
- File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
554
- f.write <<-RUBY
555
- metric "GA" do
556
- google_analytics "UA2", :visitors
557
- end
558
- RUBY
559
- end
560
- Vanity.playground.metrics
561
- assert_equal [:visitors], metric(:ga).report.metrics.elements
562
- end
563
-
564
- test "does not support hooks" do
565
- Vanity.playground.metrics
566
- assert_raises RuntimeError do
567
- metric(:ga).hook
568
- end
569
- end
570
-
571
- test "should find matching profile" do
572
- Vanity.playground.metrics
573
- Garb::Profile.expects(:all).returns(Array.new(3) { |i| GA_PROFILE.new("UA#{i + 1}") })
574
- metric(:ga).report.stubs(:send_request_for_body).returns(nil)
575
- Garb::ReportResponse.stubs(:new).returns(mock(:results=>[]))
576
- metric(:ga).values(Date.parse("2010-02-10"), Date.parse("2010-02-12"))
577
- assert_equal "UA2", metric(:ga).report.profile.web_property_id
578
- end
579
-
580
- test "should map results from report" do
581
- Vanity.playground.metrics
582
- today = Date.today
583
- response = mock(:results=>Array.new(3) { |i| GA_RESULT.new("2010021#{i}", i + 1) })
584
- Garb::Profile.stubs(:all).returns([])
585
- Garb::ReportResponse.expects(:new).returns(response)
586
- metric(:ga).report.stubs(:send_request_for_body).returns(nil)
587
- assert_equal [1,2,3], metric(:ga).values(Date.parse("2010-02-10"), Date.parse("2010-02-12"))
588
- end
589
-
590
- test "mapping GA metrics to single value" do
591
- File.open "tmp/experiments/metrics/ga.rb", "w" do |f|
592
- f.write <<-RUBY
593
- metric "GA" do
594
- google_analytics "UA2", :mapper=>lambda { |e| e.pageviews * e.visits }
595
- end
596
- RUBY
597
- end
598
- Vanity.playground.metrics
599
- today = Date.today
600
- response = mock(:results=>Array.new(3) { |i| GA_RESULT.new("2010021#{i}", i + 1, i + 1) })
601
- Garb::Profile.stubs(:all).returns([])
602
- Garb::ReportResponse.expects(:new).returns(response)
603
- metric(:ga).report.stubs(:send_request_for_body).returns(nil)
604
- assert_equal [1,4,9], metric(:ga).values(Date.parse("2010-02-10"), Date.parse("2010-02-12"))
605
- end
606
-
607
- end
608
-
609
-
610
- # -- Helper methods --
611
-
612
- def today
613
- @today ||= Date.today
614
- end
615
-
616
- teardown do
617
- Sky.delete_all
618
- Sky.after_create.clear
619
- Sky.after_save.clear
620
- end
621
-
622
- end