vanity-source 0.6 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
data/test/test.log ADDED
@@ -0,0 +1,246 @@
1
+ # Logfile created on Sun Aug 22 17:23:39 -0700 2010 by logger.rb/22285
2
+ RubyGems: 200 OK
3
+ RubyGems: 500 Server error
4
+ RubyGems: 200 OK
5
+ RubyGems: 500 Server error
6
+ Backtweets: 500 Server error
7
+ Backtweets: 200 OK
8
+ RubyGems: 200 OK
9
+ RubyGems: 500 Server error
10
+ Backtweets: 500 Server error
11
+ Backtweets: 200 OK
12
+ Backtweets: 500 Server error
13
+ Backtweets: 200 OK
14
+ Backtweets: 500 Server error
15
+ Backtweets: 200 OK
16
+ Backtweets: 500 Server error
17
+ Backtweets: 200 OK
18
+ RubyGems: 200 OK
19
+ RubyGems: 500 Server error
20
+ Backtweets: 500 Server Error
21
+ Backtweets: 500 Server Error
22
+ Backtweets: 500 Server Error
23
+ Backtweets: 200 OK
24
+ Backtweets: 500 Server Error
25
+ Backtweets: 200 OK
26
+ Backtweets: 500 Server Error
27
+ Backtweets: 200 OK
28
+ Backtweets: 500 Server Error
29
+ Backtweets: 200 OK
30
+ Backtweets: 500 Server Error
31
+ Backtweets: 200 OK
32
+ Backtweets: 500 Server Error
33
+ Backtweets: 200 OK
34
+ Backtweets: 500 Server Error
35
+ Backtweets: 200 OK
36
+ Backtweets: 500 Server Error
37
+ Backtweets: 200 OK
38
+ Backtweets: 500 Server Error
39
+ Backtweets: 200 OK
40
+ Backtweets: 500 Server Error
41
+ Backtweets: 200 OK
42
+ Backtweets: 500 Server Error
43
+ Backtweets: 200 OK
44
+ Backtweets: 500 Server Error
45
+ Backtweets: 500 Server Error
46
+ Backtweets: 200 OK
47
+ Backtweets: 200 OK
48
+ Backtweets: 500 Server Error
49
+ Backtweets: 500 Server Error
50
+ Backtweets: 200 OK
51
+ Backtweets: 200 OK
52
+ Backtweets: 500 Server Error
53
+ Backtweets: 500 Server Error
54
+ Backtweets: 200 OK
55
+ Backtweets: 200 OK
56
+ Backtweets: 500 Server Error
57
+ Backtweets: 500 Server Error
58
+ Backtweets: 200 OK
59
+ Backtweets: 200 OK
60
+ Backtweets: 500 Server Error
61
+ Backtweets: 500 Server Error
62
+ Backtweets: 200 OK
63
+ Backtweets: 200 OK
64
+ Backtweets: 500 Server Error
65
+ Backtweets: 500 Server Error
66
+ Backtweets: 200 OK
67
+ Backtweets: 200 OK
68
+ Backtweets: 500 Server Error
69
+ Backtweets: 500 Server Error
70
+ Backtweets: 200
71
+ Backtweets: 200
72
+ Backtweets: 500 Server Error
73
+ Backtweets: 500
74
+ Backtweets: 200
75
+ Backtweets: 200
76
+ Backtweets: 500
77
+ Backtweets: 500
78
+ Backtweets: 200
79
+ Backtweets: 200
80
+ Backtweets: 500
81
+ Backtweets: 500
82
+ Backtweets: 200
83
+ Backtweets: 200
84
+ Backtweets: 500
85
+ Backtweets: 500
86
+ Backtweets: 200
87
+ Backtweets: 200
88
+ Backtweets: 500
89
+ Backtweets: 500
90
+ Backtweets: 200
91
+ Backtweets: 200
92
+ Backtweets: 500
93
+ Backtweets: 500
94
+ Backtweets: 200
95
+ Backtweets: 200
96
+ Backtweets: 500
97
+ Backtweets: 500
98
+ Backtweets: 200
99
+ Backtweets: 200
100
+ Backtweets: 500
101
+ Backtweets: 500
102
+ Backtweets: 200
103
+ Backtweets: 200
104
+ Backtweets: 500
105
+ Backtweets: 500
106
+ Backtweets: 200
107
+ Backtweets: 200
108
+ Backtweets: 500
109
+ Backtweets: 500
110
+ Backtweets: 200
111
+ Backtweets: 200
112
+ Backtweets: 500
113
+ Backtweets: 500
114
+ Backtweets: 200
115
+ Backtweets: 200
116
+ Backtweets: 500
117
+ Backtweets: 200
118
+ Backtweets: 500
119
+ Backtweets: 200
120
+ Backtweets: 500
121
+ Backtweets: 200
122
+ Backtweets: 500
123
+ Backtweets: 200
124
+ Backtweets: 500
125
+ Backtweets: 200
126
+ Backtweets: 500
127
+ Backtweets: 200
128
+ Backtweets: 500
129
+ Backtweets: 200
130
+ Backtweets: 500
131
+ Backtweets: 200
132
+ Backtweets: 500
133
+ Backtweets: 200
134
+ Backtweets: 500
135
+ Backtweets: 200
136
+ Backtweets: 500
137
+ Backtweets: 200
138
+ Backtweets: 500
139
+ Backtweets: 200
140
+ Backtweets: 500
141
+ Backtweets: 200
142
+ Backtweets: 500
143
+ Backtweets: 200
144
+ Backtweets: 500
145
+ Backtweets: 500
146
+ Backtweets: 200
147
+ Backtweets: 500
148
+ Backtweets: 200
149
+ RubyGems: 200
150
+ RubyGems: 500
151
+ RubyGems: 200
152
+ RubyGems: 500
153
+ RubyGems: 200
154
+ RubyGems: 500
155
+ RubyGems: 200
156
+ RubyGems: 500
157
+ RubyGems: 200
158
+ RubyGems: 500
159
+ RubyGems: 200
160
+ RubyGems: 500
161
+ Backtweets: 500
162
+ Backtweets: 200
163
+ Backtweets: 500
164
+ Backtweets: 200
165
+ Backtweets: 500
166
+ Backtweets: 200
167
+ Backtweets: 500
168
+ Backtweets: 200
169
+ Backtweets: 500
170
+ Backtweets: 200
171
+ Backtweets: 500
172
+ Backtweets: 200
173
+ Backtweets: 200
174
+ Backtweets: 500
175
+ Backtweets: 200
176
+ Backtweets: 500
177
+ Backtweets: 200
178
+ Backtweets: 500
179
+ Backtweets: 200
180
+ Backtweets: 500
181
+ Backtweets: 200
182
+ Backtweets: 500
183
+ Backtweets: 200
184
+ Backtweets: 500
185
+ Backtweets: 200
186
+ Backtweets: 500
187
+ Backtweets: 200
188
+ Backtweets: 500
189
+ Backtweets: 200
190
+ Backtweets: 500
191
+ Backtweets: 200
192
+ Backtweets: 500
193
+ Backtweets: 200
194
+ Backtweets: 500
195
+ Backtweets: 200
196
+ Backtweets: 500
197
+ Backtweets: 200
198
+ Backtweets: 500
199
+ Backtweets: 200
200
+ Backtweets: 500
201
+ Backtweets: 200
202
+ Backtweets: 500
203
+ Backtweets: 200
204
+ Backtweets: 500
205
+ Backtweets: 200
206
+ Backtweets: 500
207
+ Backtweets: 200
208
+ Backtweets: 500
209
+ Backtweets: 200
210
+ Backtweets: 500
211
+ Backtweets: 200
212
+ Backtweets: 500
213
+ Backtweets: 200
214
+ Backtweets: 500
215
+ Backtweets: 500
216
+ Backtweets: 200
217
+ RubyGems: 200
218
+ RubyGems: 500
219
+ RubyGems: 200
220
+ RubyGems: 500
221
+ RubyGems: 200
222
+ RubyGems: 500
223
+ Backtweets: 500
224
+ Backtweets: 200
225
+ Backtweets: 200
226
+ Backtweets: 500
227
+ RubyGems: 200
228
+ RubyGems: 500
229
+ Backtweets: 500
230
+ Backtweets: 200
231
+ Backtweets: 200
232
+ Backtweets: 500
233
+ RubyGems: 200
234
+ RubyGems: 500
235
+ Backtweets: 500
236
+ Backtweets: 200
237
+ Backtweets: 200
238
+ Backtweets: 500
239
+ RubyGems: 200
240
+ RubyGems: 500
241
+ Backtweets: 500
242
+ Backtweets: 200
243
+ Backtweets: 200
244
+ Backtweets: 500
245
+ RubyGems: 200
246
+ RubyGems: 500
@@ -0,0 +1,202 @@
1
+ require "test/unit"
2
+ require "shoulda"
3
+ require "webmock/test_unit"
4
+ require "vcr"
5
+
6
+
7
+ require File.dirname(__FILE__) + "/../lib/vanity/source"
8
+ Dir[File.dirname(__FILE__) + "/../lib/vanity/sources/*.rb"].each do |file|
9
+ require file
10
+ end
11
+
12
+ # Use this to define test suite for a source class. Creates a new TestCase
13
+ # class, includes the modules Vanity::Source::TestHelpers and Webmock, sets the
14
+ # source class, and other nicities.
15
+ #
16
+ # @example
17
+ # test Vanity::Source::RubyGems do
18
+ # . . .
19
+ # end
20
+ def test(klass, &block)
21
+ returning Class.new(Test::Unit::TestCase) do |test_case|
22
+ test_case.class_eval do
23
+ include WebMock
24
+ include Vanity::Source::TestHelpers
25
+ end
26
+ test_case.instance_variable_set :@source_class, klass
27
+ test_case.class_eval &block
28
+ Object.const_set "#{klass.name.demodulize}Test", test_case
29
+ end
30
+ end
31
+
32
+ Vanity::Source.logger = Logger.new("test/test.log")
33
+ Vanity::Source.api_keys = YAML.load_file("test/api_keys.yml")
34
+
35
+
36
+ WebMock.disable_net_connect!
37
+ VCR.config do |vcr|
38
+ vcr.cassette_library_dir = File.dirname(__FILE__) + "/cassettes"
39
+ vcr.http_stubbing_library = :webmock
40
+ vcr.default_cassette_options = { :record=>ENV["RECORD"] ? :new_episodes : :none }
41
+ end
42
+
43
+ module Vanity
44
+ module Source
45
+ module TestHelpers
46
+ # Represents an activity.
47
+ Activity = Struct.new(:id, :body, :url, :timestamp, :person)
48
+
49
+ # Represents person associated with activity.
50
+ Person = Struct.new(:name, :email, :url, :photo)
51
+
52
+ # Represents a metric.
53
+ Metric = Struct.new(:name, :columns, :totals)
54
+
55
+ # Default setup. If you override setup, remember to call super.
56
+ def setup
57
+ WebMock.reset_webmock
58
+ VCR.insert_cassette(source_id)
59
+ end
60
+
61
+ # Default teardown. If you override teardown, remember to call super.
62
+ def teardown
63
+ VCR.eject_cassette
64
+ end
65
+
66
+ # Returns the source. New source instance for each test.
67
+ def source
68
+ @source ||= source_class.new
69
+ end
70
+
71
+ # Sets up source using supplied parameters, also calls validate.
72
+ #
73
+ # @example
74
+ # assert_raise RuntimeError do
75
+ # setup_source "gem_name"=>""
76
+ # end
77
+ # @example
78
+ # setup { setup_source "gem_name"=>"vanity" }
79
+ def setup_source(params)
80
+ source.setup context, params
81
+ source.validate context
82
+ end
83
+
84
+ # Returns the context. New context for each test.
85
+ def context
86
+ @context ||= {}
87
+ end
88
+
89
+ # Updates the source. If an error occurs, raises an exception. You can get
90
+ # the last error message by calling #last_error.
91
+ def update_source(request = nil)
92
+ @last_error = nil
93
+ source.update context, request, &collector
94
+ rescue
95
+ @last_error = $!.message
96
+ raise
97
+ end
98
+
99
+ # Last error after calling #update_source.
100
+ attr_reader :last_error
101
+
102
+ # Returns a new metric. See Metric.
103
+ #
104
+ # @example
105
+ # assert_equal "My metric", metric.name
106
+ def metric
107
+ Metric.new(*context.values_at("metric.name", "metric.columns", "metric.totals"))
108
+ end
109
+
110
+ def collector
111
+ lambda do |args|
112
+ if args[:set]
113
+ totals.update args[:set]
114
+ elsif args[:inc]
115
+ args[:inc].each do |name, value|
116
+ totals[name] ||= 0
117
+ totals[name] += value
118
+ end
119
+ elsif args[:activity]
120
+ values = args[:activity].values_at(:id, :body, :url, :timestamp)
121
+ if person = args[:activity][:person]
122
+ values << Person.new(*person.values_at(:name, :email, :url, :photo))
123
+ end
124
+ activities.push Activity.new(*values)
125
+ end
126
+ end
127
+ end
128
+
129
+ # Performs an update on the source and returns the meta-data.
130
+ #
131
+ # @example
132
+ # assert meta.include?(:title=>"Version", :text=>"1.4.0")
133
+ def meta
134
+ source.update context, nil, &collector
135
+ source.meta(context)
136
+ end
137
+
138
+ # Returns totals collected by this source.
139
+ #
140
+ # @example
141
+ # assert_equal({ :hits=>54 }, totals)
142
+ def totals
143
+ @totals ||= {}
144
+ end
145
+
146
+ # Returns all activities reported by this source. See Activity.
147
+ def activities
148
+ @activities ||= []
149
+ end
150
+
151
+ # Returns last (most recent) activity.
152
+ #
153
+ # @example
154
+ # assert_equal "Pushed a new release of awesome", activity.body
155
+ def activity
156
+ activities.last
157
+ end
158
+
159
+ # Validates a metric.
160
+ #
161
+ # @example
162
+ # setup_source "gem_name"=>"vanity"
163
+ # assert_valid metric
164
+ def assert_valid(metric)
165
+ assert !metric.name.blank?, "Metric name missing or a blank string"
166
+ assert metric.columns.length > 0, "Metric must have at least one column"
167
+ col_ids = metric.columns.map { |col| col[:id] }
168
+ assert col_ids.all? { |col_id| col_id }, "All metric columns must have an id"
169
+ assert col_ids.uniq == col_ids, "Metric columns must have unique ids"
170
+ end
171
+
172
+ # Returns the named fixture. Fixture looked up in the file
173
+ # test/fixtures/<source_id>.rb
174
+ def fixture(name)
175
+ fixtures = self.class.instance_variable_get(:@fixtures)
176
+ unless fixtures
177
+ fixtures = YAML.load_file(File.dirname(__FILE__) + "/fixtures/#{source_id}.yml")
178
+ self.class.instance_variable_set :@fixtures, fixtures
179
+ end
180
+ fixtures[name]
181
+ end
182
+
183
+ # Returns the VCR interactions.
184
+ def interactions
185
+ VCR.current_cassette.recorded_interactions
186
+ end
187
+
188
+ protected
189
+
190
+ # Source identifier (e.g. RubyGems => ruby_gems).
191
+ def source_id
192
+ @source_id ||= source_class.name.demodulize.underscore
193
+ end
194
+
195
+ # The source class.
196
+ def source_class
197
+ @source_class ||= self.class.instance_variable_get :@source_class
198
+ end
199
+
200
+ end
201
+ end
202
+ end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "vanity-source"
3
- spec.version = "0.6"
3
+ spec.version = "0.7"
4
4
  spec.author = "Assaf Arkin"
5
5
  spec.email = "assaf@labnotes.org"
6
6
  spec.homepage = "http://vanitydash.com"
@@ -12,4 +12,9 @@ Gem::Specification.new do |spec|
12
12
  spec.extra_rdoc_files = "README.rdoc", "CHANGELOG"
13
13
  spec.rdoc_options = "--title", "Vanity::Source #{spec.version}", "--main", "README.rdoc",
14
14
  "--webcvs", "http://github.com/assaf/#{spec.name}"
15
+
16
+ spec.required_ruby_version = '>= 1.8.7'
17
+ spec.add_dependency "activesupport", "~>2.3"
18
+ spec.add_dependency "json", "~>1.4"
19
+ spec.add_dependency "rack", "~>1.2"
15
20
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vanity-source
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 6
9
- version: "0.6"
8
+ - 7
9
+ version: "0.7"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Assaf Arkin
@@ -14,10 +14,54 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-20 00:00:00 -07:00
17
+ date: 2010-08-24 00:00:00 -07:00
18
18
  default_executable:
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 5
29
+ segments:
30
+ - 2
31
+ - 3
32
+ version: "2.3"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 7
44
+ segments:
45
+ - 1
46
+ - 4
47
+ version: "1.4"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rack
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ hash: 11
59
+ segments:
60
+ - 1
61
+ - 2
62
+ version: "1.2"
63
+ type: :runtime
64
+ version_requirements: *id003
21
65
  description:
22
66
  email: assaf@labnotes.org
23
67
  executables: []
@@ -30,9 +74,24 @@ extra_rdoc_files:
30
74
  files:
31
75
  - lib/vanity/source.rb
32
76
  - lib/vanity/sources/backtweets.rb
77
+ - lib/vanity/sources/backtweets.yml
33
78
  - lib/vanity/sources/github.rb
79
+ - lib/vanity/sources/github.yml
34
80
  - lib/vanity/sources/github_issues.rb
81
+ - lib/vanity/sources/github_issues.yml
35
82
  - lib/vanity/sources/ruby_gems.rb
83
+ - lib/vanity/sources/ruby_gems.yml
84
+ - test/api_keys.yml
85
+ - test/backtweets_test.rb
86
+ - test/cassettes/backtweets.yml
87
+ - test/cassettes/github.yml
88
+ - test/cassettes/github_issues.yml
89
+ - test/cassettes/ruby_gems.yml
90
+ - test/github_issues_test.rb
91
+ - test/github_test.rb
92
+ - test/ruby_gems_test.rb
93
+ - test/test.log
94
+ - test/test_helper.rb
36
95
  - CHANGELOG
37
96
  - MIT-LICENSE
38
97
  - README.rdoc
@@ -46,7 +105,7 @@ licenses: []
46
105
  post_install_message:
47
106
  rdoc_options:
48
107
  - --title
49
- - Vanity::Source 0.6
108
+ - Vanity::Source 0.7
50
109
  - --main
51
110
  - README.rdoc
52
111
  - --webcvs
@@ -58,10 +117,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
117
  requirements:
59
118
  - - ">="
60
119
  - !ruby/object:Gem::Version
61
- hash: 3
120
+ hash: 57
62
121
  segments:
63
- - 0
64
- version: "0"
122
+ - 1
123
+ - 8
124
+ - 7
125
+ version: 1.8.7
65
126
  required_rubygems_version: !ruby/object:Gem::Requirement
66
127
  none: false
67
128
  requirements: