vanity-source 0.6 → 0.7

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/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: