vanity 1.3.0 → 1.4.0.beta

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.
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