stacked 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.document +5 -0
  2. data/.gitignore +6 -0
  3. data/Gemfile +1 -0
  4. data/LICENSE +20 -0
  5. data/README.markdown +37 -0
  6. data/README.rdoc +18 -0
  7. data/Rakefile +51 -0
  8. data/VERSION +1 -0
  9. data/cleaner.rb +29 -0
  10. data/doc/Stacked.html +155 -0
  11. data/doc/Stacked/Answer.html +1394 -0
  12. data/doc/Stacked/Badge.html +480 -0
  13. data/doc/Stacked/Base.html +1124 -0
  14. data/doc/Stacked/Comment.html +1037 -0
  15. data/doc/Stacked/NotImplemented.html +162 -0
  16. data/doc/Stacked/Posttimeline.html +543 -0
  17. data/doc/Stacked/Question.html +1763 -0
  18. data/doc/Stacked/Reputation.html +606 -0
  19. data/doc/Stacked/Tag.html +267 -0
  20. data/doc/Stacked/User.html +2787 -0
  21. data/doc/Stacked/Usertimeline.html +630 -0
  22. data/doc/_index.html +246 -0
  23. data/doc/file.README.html +54 -0
  24. data/doc/index.html +54 -0
  25. data/doc/method_list.html +1203 -0
  26. data/doc/top-level-namespace.html +87 -0
  27. data/genddoc.sh +12 -0
  28. data/lib/stacked.rb +46 -0
  29. data/lib/stacked/answer.rb +43 -0
  30. data/lib/stacked/badge.rb +18 -0
  31. data/lib/stacked/base.rb +159 -0
  32. data/lib/stacked/comment.rb +37 -0
  33. data/lib/stacked/posttimeline.rb +10 -0
  34. data/lib/stacked/question.rb +85 -0
  35. data/lib/stacked/reputation.rb +15 -0
  36. data/lib/stacked/tag.rb +9 -0
  37. data/lib/stacked/user.rb +195 -0
  38. data/lib/stacked/usertimeline.rb +14 -0
  39. data/spec/sorted_by_spec.rb +24 -0
  40. data/spec/spec_helper.rb +16 -0
  41. data/spec/stacked/answer_spec.rb +31 -0
  42. data/spec/stacked/badge_spec.rb +17 -0
  43. data/spec/stacked/base_spec.rb +27 -0
  44. data/spec/stacked/comment_spec.rb +41 -0
  45. data/spec/stacked/question_spec.rb +110 -0
  46. data/spec/stacked/reputation_spec.rb +18 -0
  47. data/spec/stacked/tag_spec.rb +21 -0
  48. data/spec/stacked/user_spec.rb +187 -0
  49. data/spec/stacked/usertimeline_spec.rb +5 -0
  50. data/spec/support/aliases.rb +7 -0
  51. data/spec/support/sorted_by.rb +31 -0
  52. data/spec/support/within.rb +24 -0
  53. data/spec/within_spec.rb +19 -0
  54. data/stacked.gemspec +115 -0
  55. data/stylesheet.css +41 -0
  56. metadata +157 -0
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Stacked::Reputation do
4
+ # Being very particular about what Reputation we mean...
5
+ subject { Stacked::User.find(22656).reputations(:fromdate => 1270132345, :todate => 1270132348).first }
6
+
7
+ it "should be able to find the related post" do
8
+ subject.post.should be_is_a(Stacked::Answer)
9
+ end
10
+
11
+ it "should be able to work out the score of a reputation" do
12
+ # Yeah right, like anyone would ever vote down a Jon Skeet answer and live.
13
+ subject.stub!(:negative_rep => 15)
14
+ subject.score.should eql(0)
15
+ end
16
+
17
+
18
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Stacked::Tag do
4
+ subject { Stacked::Tag }
5
+ it "finds all the tags" do
6
+ subject.all(:pagesize => 1).first.name.should eql("c#")
7
+ end
8
+
9
+ it "finds the popular tags" do
10
+ subject.popular(:pagesize => 2).should be_sorted_by(:count, :desc)
11
+ end
12
+
13
+ it "finds the tags ordered by name" do
14
+ subject.name(:pagesize => 2).should be_sorted_by(:name, :asc)
15
+ end
16
+
17
+ it "finds the tags used recently" do
18
+ subject.recent(:pagesize => 2).size.should eql(2)
19
+ end
20
+
21
+ end
@@ -0,0 +1,187 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Stacked::User do
4
+ subject { Stacked::User }
5
+ context "class methods" do
6
+
7
+ it "gathers the newest user" do
8
+ subject.newest(:pagesize => 1).first.creation_date.should be_within(1.day)
9
+ end
10
+
11
+ it "gathers the oldest user" do
12
+ subject.oldest(:pagesize => 1).first.name.should eql("Community")
13
+ end
14
+
15
+ it "gathers the users by name" do
16
+ subject.name(:pagesize => 1).first.name.should eql("[ebarrera]")
17
+ end
18
+
19
+ it "gathers users by reputation" do
20
+ subject.reputation(:pagesize => 1).first.name.should eql("Jon Skeet")
21
+ end
22
+
23
+ it "gathers all the Ryan Bigg users" do
24
+ # Limited to 1 result in case other people want to steal my name.
25
+ subject.filter("Ryan Bigg", :pagesize => 1).first.name.should eql("Ryan Bigg")
26
+ end
27
+ end
28
+
29
+ context "instance methods" do
30
+ subject { Stacked::User.find(22656) }
31
+
32
+ aliases(
33
+ :created_at => :creation_date,
34
+ :display_name => :name,
35
+ :down_votes => :down_vote_count,
36
+ :gravatar => :email_hash,
37
+ :up_votes => :up_vote_count,
38
+ :user_id => :id,
39
+ :user_type => :type,
40
+ :views => :view_count
41
+ )
42
+
43
+ context "answers" do
44
+ it "finds the user's answers" do
45
+ subject.answers.should_not be_empty
46
+ subject.answers.first.should be_is_a(Stacked::Answer)
47
+ end
48
+
49
+ it "finds the user's most recent answers" do
50
+ pending("Waiting for last_activity_date to be implemented.")
51
+ subject.recent_answers(:pagesize => 2).should be_sorted_by(:last_edit_date, :desc)
52
+ end
53
+
54
+ it "finds the user's newest answers" do
55
+ subject.newest_answers(:pagesize => 2).should be_sorted_by(:creation_date, :desc)
56
+ end
57
+
58
+ it "finds the user's most popular answers" do
59
+ subject.answers_by_votes(:pagesize => 2).should be_sorted_by(:score, :desc)
60
+ end
61
+
62
+ it "finds the user's most viewed answers" do
63
+ subject.answers_by_views(:pagesize => 2).should be_sorted_by(:views, :desc)
64
+ end
65
+ end
66
+
67
+ context "comments" do
68
+ it "finds some of the user's comments" do
69
+ subject.comments.should_not be_empty
70
+ subject.comments.first.should be_is_a(Stacked::Comment)
71
+ end
72
+
73
+ it "finds the user's recent comments" do
74
+ subject.recent_comments.should be_sorted_by(:creation_date, :desc)
75
+ end
76
+
77
+ it "finds the user's most awesome comments" do
78
+ subject.popular_comments.should be_sorted_by(:score, :desc)
79
+ end
80
+
81
+ it "finds all comments directed at a user" do
82
+ # The "magic" numbers for the date range are "around" comment #2561833.
83
+ # This method is a bit funny, why would you want this time-boxed?
84
+ subject.directed_at(133566, :fromdate => 1270107600, :todate => 1270107700).first.should be_is_a(Stacked::Comment)
85
+ end
86
+
87
+ it "finds all comments directed at a user recently" do
88
+ subject.directed_at_by_date(133566, :fromdate => 1270107600, :todate => 1270107700).first.should be_is_a(Stacked::Comment)
89
+ end
90
+
91
+ it "finds all comments directed at a user by score" do
92
+ subject.directed_at_by_score(133566, :fromdate => 1270107600, :todate => 1270107700).first.should be_is_a(Stacked::Comment)
93
+ end
94
+ end
95
+
96
+ context "favourites" do
97
+
98
+ # Yes I'm using "favourites" and not "favorites"
99
+ # This has the intended side-effect of testing the existance of
100
+ # the alias as well as the real method
101
+ it "finds the user's favourite questions" do
102
+ subject.favourites.should_not be_empty
103
+ subject.favourites.first.should be_is_a(Stacked::Question)
104
+ end
105
+
106
+ it "can pass options to favourites" do
107
+ subject.favourites.size.should eql(19)
108
+ subject.favourites(:pagesize => 1).size.should eql(1)
109
+ end
110
+
111
+ it "finds the most recent favourites" do
112
+ subject.recent_favourites(:pagesize => 2).should be_sorted_by(:last_activity_date, :desc)
113
+ end
114
+
115
+ it "finds the most viewed favourites" do
116
+ subject.favourites_by_views(:pagesize => 2).should be_sorted_by(:view_count, :desc)
117
+ end
118
+
119
+ it "finds the newest favourites" do
120
+ subject.newest_favourites(:pagesize => 2).should be_sorted_by(:creation_date, :desc)
121
+ end
122
+
123
+ it "finds the favourites in the order they were made favourite" do
124
+ # How the devil do you test this?
125
+ subject.added_favourites(:pagesize => 1).first.should be_is_a(Stacked::Question)
126
+ end
127
+
128
+ end
129
+
130
+ context "questions" do
131
+
132
+ it "finds the user's questions" do
133
+ question = subject.questions.first
134
+ question.should be_is_a(Stacked::Question)
135
+ question.owner_user_id.should eql(subject.id)
136
+ end
137
+
138
+ it "can pass options to questions" do
139
+ subject.questions.size.should eql(22)
140
+ subject.questions(:pagesize => 1).size.should eql(1)
141
+ end
142
+
143
+ it "finds the user's recent questions" do
144
+ questions = subject.recent_questions(:pagesize => 2)
145
+ questions.should be_sorted_by(:last_activity_date, :desc)
146
+ end
147
+
148
+ it "finds the user's most viewed questions" do
149
+ questions = subject.questions_by_views(:pagesize => 2)
150
+ questions.should be_sorted_by(:view_count, :desc)
151
+ end
152
+
153
+ it "finds the user's newest questions" do
154
+ questions = subject.newest_questions(:pagesize => 2)
155
+ questions.should be_sorted_by(:creation_date, :desc)
156
+ end
157
+
158
+ it "finds the user's most popular questions" do
159
+ questions = subject.popular_questions(:pagesize => 2)
160
+ questions.should be_sorted_by(:score, :desc)
161
+ end
162
+ end
163
+
164
+ it "reputations" do
165
+ reputation = subject.reputations(:pagesize => 1).first
166
+ reputation.should be_is_a(Stacked::Reputation)
167
+ end
168
+
169
+ it "mentioned / mentions" do
170
+ # Testing the mentioned method by way of aliases.
171
+ subject.mentions(:pagesize => 1).first.should be_is_a(Stacked::Comment)
172
+ end
173
+
174
+ it "timeline" do
175
+ subject.timeline(:pagesize => 1).first.should be_is_a(Stacked::Usertimeline)
176
+ end
177
+
178
+ it "tags" do
179
+ subject.tags(:pagesize => 1).first.should be_is_a(Stacked::Tag)
180
+ end
181
+
182
+ it "badges" do
183
+ subject.badges(:pagesize => 1).first.name.should eql(".net")
184
+ end
185
+
186
+ end
187
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Stacked::Usertimeline do
4
+
5
+ end
@@ -0,0 +1,7 @@
1
+ def aliases(methods)
2
+ methods.each do |original, new|
3
+ it "#{original} is available as #{new}" do
4
+ subject.send(original).should eql(subject.send(new))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ module Spec
2
+ module Matchers
3
+ class Sortedby #:nodoc:
4
+ def initialize(field=nil, direction=:asc)
5
+ @field = field
6
+ @direction = direction
7
+ @pretty_direction = direction == :desc ? "descending" : "ascending"
8
+ # Placeholder
9
+ end
10
+
11
+ def matches?(receiver)
12
+ if @direction.to_sym == :desc
13
+ receiver[0].send(@field) > receiver[1].send(@field)
14
+ elsif @direction.to_sym == :asc
15
+ receiver[0].send(@field) < receiver[1].send(@field)
16
+ else
17
+ raise "direction must be either :desc or :asc or their String counterparts"
18
+ end
19
+ end
20
+
21
+ def failure_message
22
+ "Expected result set to be sorted by #{@field} in #{@pretty_direction} order, but was not."
23
+ end
24
+
25
+ end
26
+
27
+ def be_sorted_by(field=nil, direction=:asc)
28
+ Spec::Matchers::Sortedby.new(field, direction)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ module Spec
2
+ module Matchers
3
+ class Within #:nodoc:
4
+ def initialize(receiver=nil, &block)
5
+ @receiver = receiver
6
+ # Placeholder
7
+ end
8
+
9
+ def matches?(time)
10
+ time = Time.at(time) if time.is_a?(Numeric)
11
+ @receiver.ago < time
12
+ end
13
+
14
+ def failure_message
15
+ "Expected time to be within #{@receiver.inspect}, but was not."
16
+ end
17
+
18
+ end
19
+
20
+ def be_within(receiver=nil)
21
+ Spec::Matchers::Within.new(receiver)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Spec::Matchers::Within do
4
+ it "is within one day" do
5
+ time = Time.now - 5.minutes
6
+ time.should be_within(1.day)
7
+ end
8
+
9
+ it "is fine with integers" do
10
+ time = Time.now.to_i
11
+ time.should be_within(1.day)
12
+ end
13
+
14
+ it "fails with an understandable error message" do
15
+ time = Time.now - 5.days
16
+ lambda { time.should be_within(5.seconds) }.should raise_error("Expected time to be within 5 seconds, but was not.")
17
+ end
18
+
19
+ end
@@ -0,0 +1,115 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{stacked}
8
+ s.version = "0.5.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ryan Bigg"]
12
+ s.date = %q{2010-04-04}
13
+ s.description = %q{Ruby wrapper for the Stack Overflow API}
14
+ s.email = %q{ryan@getup.org.au}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".gitignore",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "README.markdown",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "cleaner.rb",
30
+ "doc/Stacked.html",
31
+ "doc/Stacked/Answer.html",
32
+ "doc/Stacked/Badge.html",
33
+ "doc/Stacked/Base.html",
34
+ "doc/Stacked/Comment.html",
35
+ "doc/Stacked/NotImplemented.html",
36
+ "doc/Stacked/Posttimeline.html",
37
+ "doc/Stacked/Question.html",
38
+ "doc/Stacked/Reputation.html",
39
+ "doc/Stacked/Tag.html",
40
+ "doc/Stacked/User.html",
41
+ "doc/Stacked/Usertimeline.html",
42
+ "doc/_index.html",
43
+ "doc/file.README.html",
44
+ "doc/index.html",
45
+ "doc/method_list.html",
46
+ "doc/top-level-namespace.html",
47
+ "genddoc.sh",
48
+ "lib/stacked.rb",
49
+ "lib/stacked/answer.rb",
50
+ "lib/stacked/badge.rb",
51
+ "lib/stacked/base.rb",
52
+ "lib/stacked/comment.rb",
53
+ "lib/stacked/posttimeline.rb",
54
+ "lib/stacked/question.rb",
55
+ "lib/stacked/reputation.rb",
56
+ "lib/stacked/tag.rb",
57
+ "lib/stacked/user.rb",
58
+ "lib/stacked/usertimeline.rb",
59
+ "spec/sorted_by_spec.rb",
60
+ "spec/spec_helper.rb",
61
+ "spec/stacked/answer_spec.rb",
62
+ "spec/stacked/badge_spec.rb",
63
+ "spec/stacked/base_spec.rb",
64
+ "spec/stacked/comment_spec.rb",
65
+ "spec/stacked/question_spec.rb",
66
+ "spec/stacked/reputation_spec.rb",
67
+ "spec/stacked/tag_spec.rb",
68
+ "spec/stacked/user_spec.rb",
69
+ "spec/stacked/usertimeline_spec.rb",
70
+ "spec/support/aliases.rb",
71
+ "spec/support/sorted_by.rb",
72
+ "spec/support/within.rb",
73
+ "spec/within_spec.rb",
74
+ "stacked.gemspec",
75
+ "stylesheet.css"
76
+ ]
77
+ s.homepage = %q{http://github.com/radar/stacked}
78
+ s.rdoc_options = ["--charset=UTF-8"]
79
+ s.require_paths = ["lib"]
80
+ s.rubygems_version = %q{1.3.6}
81
+ s.summary = %q{Ruby wrapper for the Stack Overflow API}
82
+ s.test_files = [
83
+ "spec/sorted_by_spec.rb",
84
+ "spec/spec_helper.rb",
85
+ "spec/stacked/answer_spec.rb",
86
+ "spec/stacked/badge_spec.rb",
87
+ "spec/stacked/base_spec.rb",
88
+ "spec/stacked/comment_spec.rb",
89
+ "spec/stacked/question_spec.rb",
90
+ "spec/stacked/reputation_spec.rb",
91
+ "spec/stacked/tag_spec.rb",
92
+ "spec/stacked/user_spec.rb",
93
+ "spec/stacked/usertimeline_spec.rb",
94
+ "spec/support/aliases.rb",
95
+ "spec/support/sorted_by.rb",
96
+ "spec/support/within.rb",
97
+ "spec/within_spec.rb"
98
+ ]
99
+
100
+ if s.respond_to? :specification_version then
101
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
102
+ s.specification_version = 3
103
+
104
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
105
+ s.add_development_dependency(%q<rspec>, [">= 0"])
106
+ s.add_runtime_dependency(%q<httparty>, ["~> 0.4.5"])
107
+ else
108
+ s.add_dependency(%q<rspec>, [">= 0"])
109
+ s.add_dependency(%q<httparty>, ["~> 0.4.5"])
110
+ end
111
+ else
112
+ s.add_dependency(%q<rspec>, [">= 0"])
113
+ s.add_dependency(%q<httparty>, ["~> 0.4.5"])
114
+ end
115
+ end
@@ -0,0 +1,41 @@
1
+ body {
2
+ font:12pt "Myriad Pro";
3
+ margin: 5;
4
+ }
5
+
6
+ a {
7
+ color: white;
8
+ }
9
+
10
+ h1 a {
11
+ color: black;
12
+ }
13
+
14
+ h3 {
15
+ background: #DB9C39;
16
+ color: white;
17
+ padding: 20px;
18
+ margin: 0;
19
+ border-bottom: 3px solid #343434;
20
+ }
21
+
22
+ section {
23
+ display: block;
24
+ border: 3px solid #343434;
25
+ margin-bottom: 10px;
26
+ -moz-border-radius: 10px;
27
+ }
28
+
29
+ section div {
30
+ margin-top: 10px;
31
+ padding: 20px;
32
+ }
33
+
34
+ pre, code {
35
+ background: #DECAAB;
36
+ padding: 3px;
37
+ }
38
+ /*
39
+ .hidden {
40
+ display: none;
41
+ }*/