dash-mario 0.15 → 0.16

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/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 2010-09-08 v0.16 To name a source, set source.name
2
+
3
+ During setup, name the source by setting source.name, not metric.name.
4
+
5
+ Revised and improved test suite.
6
+
1
7
  2010-09-07 v0.15 Renamed to DashFu::Mario
2
8
 
3
9
  2010-09-07 v0.14 RubyGems and Github identities
@@ -22,11 +22,13 @@ from the form fields. Since the Mario needs to store state information, it uses
22
22
  the context for that. The context is a Hash that can store basic Ruby values
23
23
  (nil, String, boolean, Numeric, Array and Hash).
24
24
 
25
- Some sources collect metrics. These sources must set three specific values
26
- (during setup):
25
+ At the very least, it should name the source by setting "source.name", typically
26
+ using other values (e.g. a Twitter source could be named "Twitter mentions for
27
+ @dash_fu").
28
+
29
+ Some sources collect metrics. These sources must specify two additional values
30
+ during setup:
27
31
 
28
- * metric.name -- The name of the metric, e.g. Twitter source might use the
29
- name "Twitter mentions of @dash_fu".
30
32
  * metric.columns -- Specifies the columns (at least one) that make up this
31
33
  metric. The value if an array where each item describes a single column, see
32
34
  below for more details.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "dash-mario"
3
- spec.version = "0.15"
3
+ spec.version = "0.16"
4
4
  spec.author = "Assaf Arkin"
5
5
  spec.email = "assaf@labnotes.org"
6
6
  spec.homepage = "http://dash-fu.com"
@@ -5,7 +5,7 @@ module DashFu::Mario
5
5
 
6
6
  def setup(source, params)
7
7
  url = params["url"].strip.downcase.sub(/^http(s?):\/\//, "")
8
- source["metric.name"] = "Tweets for #{url}"
8
+ source["source.name"] = "Tweets for #{url}"
9
9
  source["metric.columns"] = [{ :id=>"tweets", :label=>"Tweets" }]
10
10
  source["metric.totals"] = true
11
11
  source["url"] = url
@@ -5,7 +5,7 @@ module DashFu::Mario
5
5
 
6
6
  def setup(source, params)
7
7
  repo = params["repo"].strip
8
- source["metric.name"] = "Github: #{repo}"
8
+ source["source.name"] = "Github: #{repo}"
9
9
  source["metric.columns"] = [{ :id=>"commits", :label=>"Commits" }, { :id=>"watchers", :label=>"Watchers" }, { :id=>"forks", :label=>"Forks" }]
10
10
  source["metric.totals"] = true
11
11
  source["repo"] = repo
@@ -5,7 +5,7 @@ module DashFu::Mario
5
5
 
6
6
  def setup(source, params)
7
7
  repo = params["repo"].to_s.strip
8
- source["metric.name"] = "Github Issues for #{repo}"
8
+ source["source.name"] = "Github Issues for #{repo}"
9
9
  source["metric.columns"] = [{ :id=>"open", :label=>"Open issues" }, { :id=>"closed", :label=>"Closed issues" }]
10
10
  source["metric.totals"] = true
11
11
  source["repo"] = repo
@@ -5,7 +5,7 @@ module DashFu::Mario
5
5
 
6
6
  def setup(source, params)
7
7
  gem_name = params["gem_name"].to_s.strip
8
- source["metric.name"] = "RubyGems: #{gem_name}"
8
+ source["source.name"] = "RubyGems: #{gem_name}"
9
9
  source["metric.columns"] = [{ :id=>"downloads", :label=>"Downloads" }]
10
10
  source["metric.totals"] = true
11
11
  source["gem_name"] = gem_name
@@ -2,15 +2,15 @@ require_relative "setup"
2
2
 
3
3
  test DashFu::Mario::Backtweets do
4
4
  context "setup" do
5
- setup { setup_source "url"=>"vanity.labnotes.org" }
5
+ setup { source.setup "url"=>"vanity.labnotes.org" }
6
6
 
7
7
  should "use normalize URL and remove scheme" do
8
- setup_source "url"=>"http://Vanity.Labnotes.Org"
9
- assert_equal "Tweets for vanity.labnotes.org", metric.name
8
+ source.setup "url"=>"http://Vanity.Labnotes.Org"
9
+ assert_equal "Tweets for vanity.labnotes.org", source.name
10
10
  end
11
11
 
12
12
  context "metric" do
13
- subject { metric }
13
+ subject { source.metric }
14
14
 
15
15
  should "use URL" do
16
16
  assert_equal "Tweets for vanity.labnotes.org", subject.name
@@ -29,66 +29,67 @@ test DashFu::Mario::Backtweets do
29
29
 
30
30
  context "validation" do
31
31
  should "raise error if URL missing" do
32
- assert_raise(RuntimeError) { setup_source "url"=>" " }
32
+ assert_raise(RuntimeError) { source.setup "url"=>" " }
33
33
  end
34
34
 
35
35
  should "create valid metric" do
36
- setup_source "url"=>"vanity.labnotes.org"
37
- assert metric.valid?
36
+ source.setup "url"=>"vanity.labnotes.org"
37
+ assert source.valid?
38
38
  end
39
39
  end
40
40
 
41
41
 
42
42
  context "update" do
43
- setup { setup_source "url"=>"vanity.labnotes.org" }
43
+ setup { source.setup "url"=>"vanity.labnotes.org" }
44
44
 
45
45
  should "include API key" do
46
- update_source
46
+ source.update
47
47
  assert_requested :get, "http://backtweets.com/search.json?key=4554feeeeeeeeeeeeeee&q=vanity.labnotes.org"
48
48
  end
49
49
 
50
50
  should "properly encode URL" do
51
- setup_source "url"=>"need&this=encoded"
52
- update_source rescue nil
51
+ stub_request(:get, /backtweets.com/).to_return :body=>interactions.first.response.body
52
+ source.setup "url"=>"need&this=encoded"
53
+ source.update
53
54
  assert_requested :get, "http://backtweets.com/search.json?key=#{mario.send :api_key}&q=need%26this%3Dencoded"
54
55
  end
55
56
 
56
57
  should "handle errors" do
57
58
  stub_request(:get, interactions.first.uri).to_return :status=>500
58
- assert_raise(RuntimeError) { update_source }
59
- assert_equal "Last request didn't go as expected, trying again later", last_error
59
+ assert_raise(RuntimeError) { source.update }
60
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
60
61
  end
61
62
 
62
63
  should "handle invlid document entity" do
63
64
  stub_request(:get, interactions.first.uri).to_return :body=>"Not JSON"
64
- assert_raise(RuntimeError) { update_source }
65
- assert_equal "Last request didn't go as expected, trying again later", last_error
65
+ assert_raise(RuntimeError) { source.update }
66
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
66
67
  end
67
68
 
68
69
  should "capture number of tweets" do
69
- update_source
70
- assert_equal({ :tweets=>11 }, totals)
70
+ source.update
71
+ assert_equal({ :tweets=>11 }, source.metric.values)
71
72
  end
72
73
 
73
74
  should "ignore previous tweets" do
74
- update_source
75
- assert activities.empty?
75
+ source.update
76
+ assert source.activities.empty?
76
77
  end
77
78
 
78
79
  context "repeating" do
79
80
  setup do
80
- update_source
81
+ source.update
81
82
  second = interactions.last
82
83
  stub_request(:get, second.uri).to_return :body=>second.response.body
83
- update_source
84
+ source.update
84
85
  end
85
86
 
86
87
  should "capture new tweets" do
87
- assert_equal 2, activities.count
88
+ assert_equal 2, source.activities.count
88
89
  end
89
90
 
90
91
  context "activity" do
91
- subject { activity }
92
+ subject { source.activity }
92
93
 
93
94
  should "capture tweet identifier" do
94
95
  assert_equal "20959239300", subject.uid
@@ -119,7 +120,7 @@ test DashFu::Mario::Backtweets do
119
120
  end
120
121
 
121
122
  context "author" do
122
- subject { activity.person }
123
+ subject { source.activity.person }
123
124
 
124
125
  should "capture full name" do
125
126
  assert_equal "assaf", subject.fullname
@@ -141,8 +142,8 @@ test DashFu::Mario::Backtweets do
141
142
 
142
143
 
143
144
  context "meta" do
144
- setup { setup_source "url"=>"vanity.labnotes.org" }
145
- subject { meta }
145
+ setup { source.setup "url"=>"vanity.labnotes.org" }
146
+ subject { source.meta }
146
147
 
147
148
  should "link to search results" do
148
149
  assert subject.include?(:text=>"Search yourself", :url=>"http://backtweets.com/search?q=vanity.labnotes.org")
@@ -2,10 +2,10 @@ require_relative "setup"
2
2
 
3
3
  test DashFu::Mario::GithubIssues do
4
4
  context "setup" do
5
- setup { setup_source "repo"=>"assaf/vanity" }
5
+ setup { source.setup "repo"=>"assaf/vanity" }
6
6
 
7
7
  context "metric" do
8
- subject { metric }
8
+ subject { source.metric }
9
9
 
10
10
  should "use repository name" do
11
11
  assert_equal "Github Issues for assaf/vanity", subject.name
@@ -28,95 +28,95 @@ test DashFu::Mario::GithubIssues do
28
28
 
29
29
  context "validation" do
30
30
  should "raise error if repository name missing" do
31
- assert_raise(RuntimeError) { setup_source "repo"=>" " }
31
+ assert_raise(RuntimeError) { source.setup "repo"=>" " }
32
32
  end
33
33
 
34
34
  should "raise error if repository name not user/repo" do
35
- assert_raise(RuntimeError) { setup_source "repo"=>"vanity" }
35
+ assert_raise(RuntimeError) { source.setup "repo"=>"vanity" }
36
36
  end
37
37
 
38
38
  should "allow alphanumeric, minus and underscore" do
39
- setup_source "repo"=>"assaf/the-vanity_0"
40
- assert metric.valid?
39
+ source.setup "repo"=>"assaf/the-vanity_0"
40
+ assert source.valid?
41
41
  end
42
42
 
43
- should "create valid metric" do
44
- setup_source "repo"=>"assaf/vanity"
45
- assert metric.valid?
43
+ should "create valid source" do
44
+ source.setup "repo"=>"assaf/vanity"
45
+ assert source.valid?
46
46
  end
47
47
  end
48
48
 
49
49
 
50
50
  context "update" do
51
- setup { setup_source "repo"=>"assaf/vanity" }
51
+ setup { source.setup "repo"=>"assaf/vanity" }
52
52
 
53
53
  should "handle 404" do
54
54
  stub_request(:get, interactions.first.uri).to_return :status=>404
55
55
  stub_request(:get, interactions.second.uri).to_return :status=>404
56
- assert_raise(RuntimeError) { update_source }
57
- assert_equal "Could not find the repository assaf/vanity", last_error
56
+ assert_raise(RuntimeError) { source.update }
57
+ assert_equal "Could not find the repository assaf/vanity", source.last_error
58
58
  end
59
59
 
60
60
  should "handle 401" do
61
61
  stub_request(:get, interactions.first.uri).to_return :status=>401
62
62
  stub_request(:get, interactions.second.uri).to_return :status=>401
63
- assert_raise(RuntimeError) { update_source }
64
- assert_equal "You are not authorized to access this repository, or invalid username/password", last_error
63
+ assert_raise(RuntimeError) { source.update }
64
+ assert_equal "You are not authorized to access this repository, or invalid username/password", source.last_error
65
65
  end
66
66
 
67
67
  should "handle other error" do
68
68
  stub_request(:get, interactions.first.uri).to_return :status=>500
69
69
  stub_request(:get, interactions.second.uri).to_return :status=>500
70
- assert_raise(RuntimeError) { update_source }
71
- assert_equal "Last request didn't go as expected, trying again later", last_error
70
+ assert_raise(RuntimeError) { source.update }
71
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
72
72
  end
73
73
 
74
74
  should "handle invlid document entity" do
75
75
  stub_request(:get, interactions.first.uri).to_return :body=>"Not JSON"
76
76
  stub_request(:get, interactions.last.uri).to_return :body=>"Not JSON"
77
- assert_raise(RuntimeError) { update_source }
78
- assert_equal "Last request didn't go as expected, trying again later", last_error
77
+ assert_raise(RuntimeError) { source.update }
78
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
79
79
  end
80
80
 
81
81
  should "capture number of open issues" do
82
- update_source
83
- assert_equal 9, totals[:open]
82
+ source.update
83
+ assert_equal 9, source.metric.values[:open]
84
84
  end
85
85
 
86
86
  should "capture number of closed issues" do
87
- update_source
88
- assert_equal 12, totals[:closed]
87
+ source.update
88
+ assert_equal 12, source.metric.values[:closed]
89
89
  end
90
90
 
91
91
  should "not create any activity" do
92
- update_source
93
- assert activities.empty?
92
+ source.update
93
+ assert source.activities.empty?
94
94
  end
95
95
 
96
96
  context "repeating" do
97
97
  setup do
98
- update_source
98
+ source.update
99
99
  open = interactions.select { |i| i.uri =~ /open/ }
100
100
  stub_request(:get, open.first.uri).to_return :body=>open.last.response.body
101
101
  closed = interactions.select { |i| i.uri =~ /closed/ }
102
102
  stub_request(:get, closed.first.uri).to_return :body=>closed.last.response.body
103
- update_source
103
+ source.update
104
104
  end
105
105
 
106
106
  should "update open count" do
107
- assert_equal 2, totals[:open]
107
+ assert_equal 2, source.metric.values[:open]
108
108
  end
109
109
 
110
110
  should "update closed count" do
111
- assert_equal 2, totals[:closed]
111
+ assert_equal 2, source.metric.values[:closed]
112
112
  end
113
113
 
114
114
  should "create activity for each issue opened or closed" do
115
- assert_equal 2, activities.count
115
+ assert_equal 2, source.activities.count
116
116
  end
117
117
 
118
118
  context "activity for open issue" do
119
- subject { activities.first }
119
+ subject { source.activities.first }
120
120
 
121
121
  should "capture issue URL" do
122
122
  assert_equal "http://github.com/assaf/vanity/issues#issue/22", subject.url
@@ -148,7 +148,7 @@ opened <a href="http://github.com/assaf/vanity/issues#issue/22">issue 22</a> on
148
148
  end
149
149
 
150
150
  context "activity for closed issue" do
151
- subject { activities.last }
151
+ subject { source.activities.last }
152
152
 
153
153
  should "capture issue URL" do
154
154
  assert_equal "http://github.com/assaf/vanity/issues#issue/19", subject.url
@@ -184,8 +184,8 @@ closed <a href="http://github.com/assaf/vanity/issues#issue/19">issue 19</a> on
184
184
 
185
185
 
186
186
  context "meta" do
187
- setup { setup_source "repo"=>"assaf/vanity" }
188
- subject { meta }
187
+ setup { source.setup "repo"=>"assaf/vanity" }
188
+ subject { source.meta }
189
189
 
190
190
  should "link to repository" do
191
191
  assert_contains subject, :title=>"On Github", :url=>"http://github.com/assaf/vanity/issues"
@@ -2,15 +2,15 @@ require_relative "setup"
2
2
 
3
3
  test DashFu::Mario::Github do
4
4
  context "setup" do
5
- setup { setup_source "repo"=>"assaf/vanity", "branch"=>"master" }
5
+ setup { source.setup "repo"=>"assaf/vanity", "branch"=>"master" }
6
6
 
7
7
  should "default branch to master" do
8
- setup_source "repo"=>"assaf/vanity", "branch"=>" "
9
- assert_equal "master", source["branch"]
8
+ source.setup "repo"=>"assaf/vanity", "branch"=>" "
9
+ assert_equal "master", source.state["branch"]
10
10
  end
11
11
 
12
12
  context "metric" do
13
- subject { metric }
13
+ subject { source.metric }
14
14
 
15
15
  should "use repository name" do
16
16
  assert_equal "Github: assaf/vanity", subject.name
@@ -37,96 +37,96 @@ test DashFu::Mario::Github do
37
37
 
38
38
  context "validation" do
39
39
  should "raise error if repository name missing" do
40
- assert_raise(RuntimeError) { setup_source "repo"=>" ", "branch"=>"master" }
40
+ assert_raise(RuntimeError) { source.setup "repo"=>" ", "branch"=>"master" }
41
41
  end
42
42
 
43
43
  should "raise error if repository name not user/repo" do
44
- assert_raise(RuntimeError) { setup_source "repo"=>"vanity", "branch"=>"master" }
44
+ assert_raise(RuntimeError) { source.setup "repo"=>"vanity", "branch"=>"master" }
45
45
  end
46
46
 
47
47
  should "allow alphanumeric, minus and underscore" do
48
- setup_source "repo"=>"assaf/the-vanity_0", "branch"=>"master"
49
- assert metric.valid?
48
+ source.setup "repo"=>"assaf/the-vanity_0", "branch"=>"master"
49
+ assert source.valid?
50
50
  end
51
51
 
52
- should "create valid metric" do
53
- setup_source "repo"=>"assaf/vanity", "branch"=>"master"
54
- assert metric.valid?
52
+ should "create valid source" do
53
+ source.setup "repo"=>"assaf/vanity", "branch"=>"master"
54
+ assert source.valid?
55
55
  end
56
56
  end
57
57
 
58
58
 
59
59
  context "update" do
60
- setup { setup_source "repo"=>"assaf/vanity", "branch"=>"master" }
60
+ setup { source.setup "repo"=>"assaf/vanity", "branch"=>"master" }
61
61
 
62
62
  should "handle 404" do
63
63
  stub_request(:get, interactions.first.uri).to_return :status=>404
64
- assert_raise(RuntimeError) { update_source }
65
- assert_equal "Could not find the repository assaf/vanity", last_error
64
+ assert_raise(RuntimeError) { source.update }
65
+ assert_equal "Could not find the repository assaf/vanity", source.last_error
66
66
  end
67
67
 
68
68
  should "handle 401" do
69
69
  stub_request(:get, interactions.first.uri).to_return :status=>401
70
- assert_raise(RuntimeError) { update_source }
71
- assert_equal "You are not authorized to access this repository, or invalid username/password", last_error
70
+ assert_raise(RuntimeError) { source.update }
71
+ assert_equal "You are not authorized to access this repository, or invalid username/password", source.last_error
72
72
  end
73
73
 
74
74
  should "handle other error" do
75
75
  stub_request(:get, interactions.first.uri).to_return :status=>500
76
- assert_raise(RuntimeError) { update_source }
77
- assert_equal "Last request didn't go as expected, trying again later", last_error
76
+ assert_raise(RuntimeError) { source.update }
77
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
78
78
  end
79
79
 
80
80
  should "handle invlid document entity" do
81
81
  stub_request(:get, interactions.first.uri).to_return :body=>"Not JSON"
82
- assert_raise(RuntimeError) { update_source }
83
- assert_equal "Last request didn't go as expected, trying again later", last_error
82
+ assert_raise(RuntimeError) { source.update }
83
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
84
84
  end
85
85
 
86
86
  should "capture number of commits" do
87
- update_source
88
- assert_equal 35, totals[:commits]
87
+ source.update
88
+ assert_equal 35, source.metric.values[:commits]
89
89
  end
90
90
 
91
91
  should "capture number of wacthers" do
92
- update_source
93
- assert_equal 534, totals[:watchers]
92
+ source.update
93
+ assert_equal 534, source.metric.values[:watchers]
94
94
  end
95
95
 
96
96
  should "capture number of forks" do
97
- update_source
98
- assert_equal 36, totals[:forks]
97
+ source.update
98
+ assert_equal 36, source.metric.values[:forks]
99
99
  end
100
100
 
101
101
  should "not create any activity" do
102
- update_source
103
- assert activities.empty?
102
+ source.update
103
+ assert source.activities.empty?
104
104
  end
105
105
 
106
106
  context "repeating" do
107
107
  setup do
108
- update_source
108
+ source.update
109
109
  repo = interactions.select { |i| i.uri =~ /repos\/show/ }
110
110
  stub_request(:get, repo.first.uri).to_return :body=>repo.last.response.body
111
111
  commits = interactions.select { |i| i.uri =~ /commits\/list/ }
112
112
  stub_request(:get, commits.first.uri).to_return :body=>commits.last.response.body
113
- update_source
113
+ source.update
114
114
  end
115
115
 
116
116
  should "update watchers" do
117
- assert_equal 555, totals[:watchers]
117
+ assert_equal 555, source.metric.values[:watchers]
118
118
  end
119
119
 
120
120
  should "update forks" do
121
- assert_equal 38, totals[:forks]
121
+ assert_equal 38, source.metric.values[:forks]
122
122
  end
123
123
 
124
124
  should "capture new number of commits" do
125
- assert_equal 39, totals[:commits]
125
+ assert_equal 39, source.metric.values[:commits]
126
126
  end
127
127
 
128
128
  context "activity" do
129
- subject { activity }
129
+ subject { source.activity }
130
130
 
131
131
  should "capture commit URL" do
132
132
  assert_equal "http://github.com/assaf/vanity/commit/dd154a9fdd2ac534b62b55b8acac2fd092d65439", subject.url
@@ -154,7 +154,7 @@ test DashFu::Mario::Github do
154
154
  end
155
155
 
156
156
  context "person" do
157
- subject { activity.person }
157
+ subject { source.activity.person }
158
158
 
159
159
  should "capture full name" do
160
160
  assert_equal "Assaf Arkin", subject.fullname
@@ -170,7 +170,7 @@ test DashFu::Mario::Github do
170
170
  end
171
171
 
172
172
  context "commit message" do
173
- subject { (Nokogiri::HTML(activity.html)/"blockquote").inner_text.strip }
173
+ subject { (Nokogiri::HTML(source.activity.html)/"blockquote").inner_text.strip }
174
174
 
175
175
  should "start with commit SHA" do
176
176
  assert_match /^cc156a9 /, subject
@@ -191,7 +191,7 @@ test DashFu::Mario::Github do
191
191
  commit = JSON.parse(commits.first.response.body)["commits"].first
192
192
  commit["message"] = message
193
193
  stub_request(:get, commits.first.uri).to_return :body=>{ :commits=>[commit] }.to_json
194
- update_source
194
+ source.update
195
195
  end
196
196
  end
197
197
 
@@ -199,12 +199,12 @@ test DashFu::Mario::Github do
199
199
  setup do
200
200
  interaction = interactions.select { |i| i.uri =~ /commits\/list/ }.last
201
201
  stub_request(:get, interaction.uri).to_return :body=>interaction.response.body
202
- update_source
202
+ source.update
203
203
  end
204
- subject { (Nokogiri::HTML(activity.html)/"blockquote") }
204
+ subject { (Nokogiri::HTML(source.activity.html)/"blockquote") }
205
205
 
206
206
  should "show as multiple activities" do
207
- assert_equal 3, activities.count # 4 commits -> 3 activities
207
+ assert_equal 3, source.activities.count # 4 commits -> 3 activities
208
208
  end
209
209
 
210
210
  should "merge related commits into single activity" do
@@ -224,8 +224,8 @@ test DashFu::Mario::Github do
224
224
 
225
225
 
226
226
  context "meta" do
227
- setup { setup_source "repo"=>"assaf/vanity", "branch"=>"master" }
228
- subject { meta }
227
+ setup { source.setup "repo"=>"assaf/vanity", "branch"=>"master" }
228
+ subject { source.meta }
229
229
 
230
230
  should "link to repository" do
231
231
  assert_contains subject, :title=>"Repository", :text=>"assaf/vanity", :url=>"http://github.com/assaf/vanity"
@@ -3,9 +3,11 @@ class Metric
3
3
  args.each do |name, value|
4
4
  send "#{name}=", value
5
5
  end
6
+ @values = {}
6
7
  end
7
8
 
8
9
  attr_accessor :name, :columns, :totals
10
+ attr_reader :values
9
11
 
10
12
  def valid?
11
13
  validate rescue return false
@@ -19,4 +21,5 @@ class Metric
19
21
  fail "All metric columns must have an id" unless col_ids.all? { |col_id| col_id }
20
22
  fail "Metric columns must have unique ids" unless col_ids.uniq == col_ids
21
23
  end
24
+
22
25
  end
@@ -0,0 +1,91 @@
1
+ class Source
2
+ def initialize(args)
3
+ @mario = args[:mario]
4
+ @state = {}
5
+ end
6
+
7
+ attr_accessor :name, :mario, :state, :last_error, :metric
8
+
9
+ # Sets up source using supplied parameters, also validates.
10
+ #
11
+ # @example
12
+ # assert_raise RuntimeError do
13
+ # setup_source "gem_name"=>""
14
+ # end
15
+ # @example
16
+ # setup { source.setup "gem_name"=>"vanity" }
17
+ def setup(params = {})
18
+ mario.setup state, params
19
+ self.name = state.delete("source.name")
20
+ @metric = Metric.new(:name=>name, :columns=>state["metric.columns"], :totals=>!!state["metric.totals"]) if state["metric.columns"]
21
+ validate
22
+ end
23
+
24
+ def validate
25
+ raise "Must be named" if name.blank?
26
+ raise "Name must be 3 characters of longer" if name.length < 3
27
+ mario.validate state
28
+ metric.validate if metric
29
+ end
30
+
31
+ def valid?
32
+ validate rescue return false
33
+ return true
34
+ end
35
+
36
+ # Performs an update on the source.
37
+ #
38
+ # @example
39
+ # assert source.update
40
+ def update(request = nil)
41
+ @last_error = nil
42
+ mario.update state, request, &callback
43
+ rescue
44
+ @last_error = $!.message
45
+ raise
46
+ end
47
+
48
+ # Performs an update on the source and returns the meta-data.
49
+ #
50
+ # @example
51
+ # assert source.meta.include?(:title=>"Version", :text=>"1.4.0")
52
+ def meta
53
+ mario.update state, nil, &callback
54
+ mario.meta(state)
55
+ end
56
+
57
+ # Returns all activities reported by this source. See Activity.
58
+ def activities
59
+ @activities ||= []
60
+ end
61
+
62
+ # Returns last (most recent) activity.
63
+ #
64
+ # @example
65
+ # assert_equal "Pushed a new release of awesome", source.activity.body
66
+ def activity
67
+ activities.last
68
+ end
69
+
70
+ protected
71
+
72
+ def callback
73
+ lambda do |args|
74
+ if args[:set]
75
+ metric.values.update args[:set]
76
+ elsif args[:inc]
77
+ args[:inc].each do |name, value|
78
+ metric.values[name] ||= 0
79
+ metric.values[name] += value
80
+ end
81
+ elsif args[:activity]
82
+ values = args[:activity].clone
83
+ if person = values.delete(:person)
84
+ values[:person] = Person.new(person)
85
+ end
86
+ activities.push Activity.new(values)
87
+ end
88
+ end
89
+ end
90
+
91
+ end
@@ -38,74 +38,9 @@ module DashFu
38
38
  @mario ||= mario_class.new
39
39
  end
40
40
 
41
- # Sets up source using supplied parameters, also calls validate.
42
- #
43
- # @example
44
- # assert_raise RuntimeError do
45
- # setup_source "gem_name"=>""
46
- # end
47
- # @example
48
- # setup { setup_source "gem_name"=>"vanity" }
49
- def setup_source(params)
50
- mario.setup source, params
51
- mario.validate source
52
- end
53
-
54
41
  # Returns the source. New source for each test.
55
42
  def source
56
- @source ||= {}
57
- end
58
-
59
- # Updates the source. If an error occurs, raises an exception. You can get
60
- # the last error message by calling #last_error.
61
- def update_source(request = nil)
62
- @last_error = nil
63
- mario.update source, request, &updator
64
- rescue
65
- @last_error = $!.message
66
- raise
67
- end
68
-
69
- # Last error after calling #update_source.
70
- attr_reader :last_error
71
-
72
- # Returns a new metric. See Metric.
73
- #
74
- # @example
75
- # assert_equal "My metric", metric.name
76
- def metric
77
- values = { :name=>source["metric.name"], :columns=>source["metric.columns"], :totals=>!!source["metric.totals"] }
78
- Metric.new(values)
79
- end
80
-
81
- # Performs an update on the source and returns the meta-data.
82
- #
83
- # @example
84
- # assert meta.include?(:title=>"Version", :text=>"1.4.0")
85
- def meta
86
- mario.update source, nil, &updator
87
- mario.meta(source)
88
- end
89
-
90
- # Returns totals collected by this source.
91
- #
92
- # @example
93
- # assert_equal({ :hits=>54 }, totals)
94
- def totals
95
- @totals ||= {}
96
- end
97
-
98
- # Returns all activities reported by this source. See Activity.
99
- def activities
100
- @activities ||= []
101
- end
102
-
103
- # Returns last (most recent) activity.
104
- #
105
- # @example
106
- # assert_equal "Pushed a new release of awesome", activity.body
107
- def activity
108
- activities.last
43
+ @source ||= Source.new(mario: mario)
109
44
  end
110
45
 
111
46
  # Returns the named fixture. Fixture looked up in the file
@@ -136,26 +71,6 @@ module DashFu
136
71
  @mario_class ||= self.class.instance_variable_get :@mario_class
137
72
  end
138
73
 
139
- # Source update block.
140
- def updator
141
- lambda do |args|
142
- if args[:set]
143
- totals.update args[:set]
144
- elsif args[:inc]
145
- args[:inc].each do |name, value|
146
- totals[name] ||= 0
147
- totals[name] += value
148
- end
149
- elsif args[:activity]
150
- values = args[:activity].clone
151
- if person = values.delete(:person)
152
- values[:person] = Person.new(person)
153
- end
154
- activities.push Activity.new(values)
155
- end
156
- end
157
- end
158
-
159
74
  end
160
75
  end
161
76
  end
@@ -2,10 +2,10 @@ require_relative "setup"
2
2
 
3
3
  test DashFu::Mario::RubyGems do
4
4
  context "setup" do
5
- setup { setup_source "gem_name"=>"vanity" }
5
+ setup { source.setup "gem_name"=>"vanity" }
6
6
 
7
7
  context "metric" do
8
- subject { metric }
8
+ subject { source.metric }
9
9
 
10
10
  should "use gem name" do
11
11
  assert_equal "RubyGems: vanity", subject.name
@@ -24,75 +24,75 @@ test DashFu::Mario::RubyGems do
24
24
 
25
25
  context "validation" do
26
26
  should "raise error if gem name missing" do
27
- assert_raise(RuntimeError) { setup_source "gem_name"=>" " }
27
+ assert_raise(RuntimeError) { source.setup "gem_name"=>" " }
28
28
  end
29
29
 
30
- should "create valid metric" do
31
- setup_source "gem_name"=>"vanity"
32
- assert metric.valid?
30
+ should "create valid source" do
31
+ source.setup "gem_name"=>"vanity"
32
+ assert source.valid?
33
33
  end
34
34
  end
35
35
 
36
36
 
37
37
  context "update" do
38
- setup { setup_source "gem_name"=>"vanity" }
38
+ setup { source.setup "gem_name"=>"vanity" }
39
39
 
40
40
  should "properly encode gem name" do
41
- setup_source "gem_name"=>"need&this=encoded"
42
- update_source rescue nil
41
+ source.setup "gem_name"=>"need&this=encoded"
42
+ source.update rescue nil
43
43
  assert_requested :get, "http://rubygems.org/api/v1/gems/need%26this%3Dencoded.json"
44
44
  end
45
45
 
46
46
  should "handle 404" do
47
47
  stub_request(:get, interactions.first.uri).to_return :status=>404
48
- assert_raise(RuntimeError) { update_source }
49
- assert_equal "Could not find the Gem vanity", last_error
48
+ assert_raise(RuntimeError) { source.update }
49
+ assert_equal "Could not find the Gem vanity", source.last_error
50
50
  end
51
51
 
52
52
  should "handle other error" do
53
53
  stub_request(:get, interactions.first.uri).to_return :status=>500
54
- assert_raise(RuntimeError) { update_source }
55
- assert_equal "Last request didn't go as expected, trying again later", last_error
54
+ assert_raise(RuntimeError) { source.update }
55
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
56
56
  end
57
57
 
58
58
  should "handle invlid document entity" do
59
59
  stub_request(:get, interactions.first.uri).to_return :body=>"Not JSON"
60
- assert_raise(RuntimeError) { update_source }
61
- assert_equal "Last request didn't go as expected, trying again later", last_error
60
+ assert_raise(RuntimeError) { source.update }
61
+ assert_equal "Last request didn't go as expected, trying again later", source.last_error
62
62
  end
63
63
 
64
64
  should "capture number of downloads" do
65
- update_source
66
- assert_equal({ :downloads=>3492 }, totals)
65
+ source.update
66
+ assert_equal({ :downloads=>3492 }, source.metric.values)
67
67
  end
68
68
 
69
69
  should "not create any activity" do
70
- update_source
71
- assert activities.empty?
70
+ source.update
71
+ assert source.activities.empty?
72
72
  end
73
73
 
74
74
  context "repeating" do
75
75
  setup do
76
- update_source
76
+ source.update
77
77
  data = JSON.parse(interactions.first.response.body).merge("downloads"=>9040, "version"=>"2.1.0")
78
78
  stub_request(:get, interactions.first.uri).to_return :body=>data.to_json
79
- update_source
79
+ source.update
80
80
  end
81
81
 
82
82
  should "update version number" do
83
- assert meta.include?(:title=>"Version", :text=>"2.1.0")
83
+ assert source.meta.include?(:title=>"Version", :text=>"2.1.0")
84
84
  end
85
85
 
86
86
  should "capture new number of downloads" do
87
- assert_equal({ :downloads=>9040 }, totals)
87
+ assert_equal({ :downloads=>9040 }, source.metric.values)
88
88
  end
89
89
 
90
90
  should "create activity for new release" do
91
- assert activity
91
+ assert source.activity
92
92
  end
93
93
 
94
94
  context "activity" do
95
- subject { activity }
95
+ subject { source.activity }
96
96
 
97
97
  should "should have unique identifier" do
98
98
  assert_equal "vanity-2.1.0", subject.uid
@@ -118,7 +118,7 @@ released <a href=\"http://rubygems.org/gems/vanity/versions/2.1.0\">vanity versi
118
118
  end
119
119
 
120
120
  context "person" do
121
- subject { activity.person }
121
+ subject { source.activity.person }
122
122
 
123
123
  should "be named Ruby Gems" do
124
124
  assert_equal "RubyGems", subject.fullname
@@ -138,8 +138,8 @@ released <a href=\"http://rubygems.org/gems/vanity/versions/2.1.0\">vanity versi
138
138
 
139
139
 
140
140
  context "meta" do
141
- setup { setup_source "gem_name"=>"vanity" }
142
- subject { meta }
141
+ setup { source.setup "gem_name"=>"vanity" }
142
+ subject { source.meta }
143
143
 
144
144
  should "link to project page" do
145
145
  assert_contains subject, :title=>"Project", :text=>"vanity", :url=>"http://vanity.labnotes.org"
@@ -8,6 +8,7 @@ require "nokogiri"
8
8
  require "active_support/all"
9
9
 
10
10
  require_relative "helpers/test"
11
+ require_relative "helpers/source"
11
12
  require_relative "helpers/person"
12
13
  require_relative "helpers/activity"
13
14
  require_relative "helpers/metric"
@@ -850,3 +850,67 @@ Github: 200
850
850
  Github: 500
851
851
  RubyGems: 200
852
852
  RubyGems: 500
853
+ RubyGems: 200
854
+ RubyGems: 500
855
+ RubyGems: 200
856
+ RubyGems: 500
857
+ RubyGems: 200
858
+ RubyGems: 500
859
+ RubyGems: 200
860
+ RubyGems: 500
861
+ RubyGems: 200
862
+ RubyGems: 500
863
+ RubyGems: 200
864
+ RubyGems: 500
865
+ RubyGems: 200
866
+ RubyGems: 500
867
+ RubyGems: 200
868
+ RubyGems: 500
869
+ RubyGems: 200
870
+ RubyGems: 500
871
+ RubyGems: 200
872
+ RubyGems: 500
873
+ RubyGems: 200
874
+ RubyGems: 500
875
+ RubyGems: 200
876
+ RubyGems: 500
877
+ Backtweets: 500
878
+ Backtweets: 200
879
+ Backtweets: 500
880
+ Backtweets: 200
881
+ Backtweets: 500
882
+ Backtweets: 200
883
+ Backtweets: 500
884
+ Backtweets: 200
885
+ Backtweets: 500
886
+ Backtweets: 200
887
+ Backtweets: 500
888
+ Backtweets: 200
889
+ Backtweets: 500
890
+ Backtweets: 200
891
+ Backtweets: 500
892
+ Backtweets: 200
893
+ Backtweets: 200
894
+ Backtweets: 500
895
+ Backtweets: 200
896
+ Backtweets: 200
897
+ Backtweets: 500
898
+ Backtweets: 200
899
+ Backtweets: 500
900
+ Backtweets: 200
901
+ Backtweets: 500
902
+ Backtweets: 200
903
+ Github: 200
904
+ Github: 500
905
+ Backtweets: 500
906
+ Backtweets: 200
907
+ Github: 200
908
+ Github: 500
909
+ RubyGems: 200
910
+ RubyGems: 500
911
+ Backtweets: 500
912
+ Backtweets: 200
913
+ Github: 200
914
+ Github: 500
915
+ RubyGems: 200
916
+ RubyGems: 500
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 15
8
- version: "0.15"
7
+ - 16
8
+ version: "0.16"
9
9
  platform: ruby
10
10
  authors:
11
11
  - Assaf Arkin
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2010-09-07 00:00:00 -07:00
16
+ date: 2010-09-08 00:00:00 -07:00
17
17
  default_executable:
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
@@ -111,6 +111,7 @@ files:
111
111
  - test/helpers/activity.rb
112
112
  - test/helpers/metric.rb
113
113
  - test/helpers/person.rb
114
+ - test/helpers/source.rb
114
115
  - test/helpers/test.rb
115
116
  - test/ruby_gems_test.rb
116
117
  - test/setup.rb
@@ -128,7 +129,7 @@ licenses: []
128
129
  post_install_message:
129
130
  rdoc_options:
130
131
  - --title
131
- - DashFu::Mario 0.15
132
+ - DashFu::Mario 0.16
132
133
  - --main
133
134
  - README.rdoc
134
135
  - --webcvs