stacked 0.5.0 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +3 -1
  3. data/Gemfile.lock +43 -0
  4. data/LICENSE +1 -1
  5. data/README.markdown +58 -25
  6. data/Rakefile +6 -45
  7. data/genddoc.sh +4 -1
  8. data/lib/stacked.rb +11 -9
  9. data/lib/stacked/answer.rb +10 -27
  10. data/lib/stacked/badge.rb +15 -11
  11. data/lib/stacked/base.rb +59 -92
  12. data/lib/stacked/client.rb +31 -0
  13. data/lib/stacked/comment.rb +13 -18
  14. data/lib/stacked/parser.rb +47 -0
  15. data/lib/stacked/post_timeline.rb +17 -0
  16. data/lib/stacked/question.rb +52 -51
  17. data/lib/stacked/{reputation.rb → rep_change.rb} +5 -3
  18. data/lib/stacked/tag.rb +10 -2
  19. data/lib/stacked/user.rb +29 -161
  20. data/lib/stacked/{usertimeline.rb → user_timeline.rb} +5 -5
  21. data/lib/stacked/version.rb +4 -0
  22. data/spec/fakes/answers/1237127 +0 -0
  23. data/spec/fakes/answers/2272830 +0 -0
  24. data/spec/fakes/answers/2558700 +0 -0
  25. data/spec/fakes/badges/index +0 -0
  26. data/spec/fakes/badges/name +0 -0
  27. data/spec/fakes/badges/tags +0 -0
  28. data/spec/fakes/comments/1063043 +0 -0
  29. data/spec/fakes/comments/2561833 +0 -0
  30. data/spec/fakes/questions/1236996 +0 -0
  31. data/spec/fakes/questions/1236996-answers +0 -0
  32. data/spec/fakes/questions/1236996-comments +0 -0
  33. data/spec/fakes/questions/1236996-timeline +0 -0
  34. data/spec/fakes/questions/4839321/answers +0 -0
  35. data/spec/fakes/questions/index +0 -0
  36. data/spec/fakes/questions/search +0 -0
  37. data/spec/fakes/questions/tagged +0 -0
  38. data/spec/fakes/questions/unanswered +0 -0
  39. data/spec/fakes/questions/withcomments +0 -0
  40. data/spec/fakes/stats/index +0 -0
  41. data/spec/fakes/tags/activity +0 -0
  42. data/spec/fakes/tags/index +0 -0
  43. data/spec/fakes/tags/name +0 -0
  44. data/spec/fakes/tags/popular +0 -0
  45. data/spec/fakes/users/148722 +0 -0
  46. data/spec/fakes/users/148722-comments +0 -0
  47. data/spec/fakes/users/148722-comments-by-creation +0 -0
  48. data/spec/fakes/users/148722-comments-by-votes +0 -0
  49. data/spec/fakes/users/22656 +0 -0
  50. data/spec/fakes/users/22656-answers +0 -0
  51. data/spec/fakes/users/22656-answers-by-activity +0 -0
  52. data/spec/fakes/users/22656-answers-by-creation +0 -0
  53. data/spec/fakes/users/22656-answers-by-views +0 -0
  54. data/spec/fakes/users/22656-answers-by-votes +0 -0
  55. data/spec/fakes/users/22656-badges +0 -0
  56. data/spec/fakes/users/22656-comments-mentioning-by-creation +0 -0
  57. data/spec/fakes/users/22656-comments-mentioning-by-votes +0 -0
  58. data/spec/fakes/users/22656-favorites +0 -0
  59. data/spec/fakes/users/22656-favorites-by-activity +0 -0
  60. data/spec/fakes/users/22656-favorites-by-added +0 -0
  61. data/spec/fakes/users/22656-favorites-by-creation +0 -0
  62. data/spec/fakes/users/22656-favorites-by-views +0 -0
  63. data/spec/fakes/users/22656-mentioned +0 -0
  64. data/spec/fakes/users/22656-questions +0 -0
  65. data/spec/fakes/users/22656-questions-by-activity +0 -0
  66. data/spec/fakes/users/22656-questions-by-creation +0 -0
  67. data/spec/fakes/users/22656-questions-by-views +0 -0
  68. data/spec/fakes/users/22656-questions-by-votes +0 -0
  69. data/spec/fakes/users/22656-reputation +0 -0
  70. data/spec/fakes/users/22656-reputation-ranged +0 -0
  71. data/spec/fakes/users/22656-tags +0 -0
  72. data/spec/fakes/users/22656-timeline +0 -0
  73. data/spec/fakes/users/filter +0 -0
  74. data/spec/fakes/users/index +0 -0
  75. data/spec/fakes/users/index-page2 +0 -0
  76. data/spec/fakes/users/index-pagesize1 +0 -0
  77. data/spec/fakes/users/name +0 -0
  78. data/spec/fakes/users/newest +0 -0
  79. data/spec/fakes/users/oldest +0 -0
  80. data/spec/sorted_by_spec.rb +2 -2
  81. data/spec/spec_helper.rb +10 -8
  82. data/spec/stacked/answer_spec.rb +9 -8
  83. data/spec/stacked/badge_spec.rb +11 -3
  84. data/spec/stacked/base_spec.rb +24 -2
  85. data/spec/stacked/comment_spec.rb +11 -9
  86. data/spec/stacked/question_spec.rb +49 -61
  87. data/spec/stacked/{reputation_spec.rb → rep_change_spec.rb} +9 -5
  88. data/spec/stacked/tag_spec.rb +13 -6
  89. data/spec/stacked/user_spec.rb +99 -70
  90. data/spec/stacked/{usertimeline_spec.rb → user_timeline_spec.rb} +1 -1
  91. data/spec/support/fakes.rb +28 -0
  92. data/spec/support/{sorted_by.rb → matchers/sorted_by.rb} +7 -6
  93. data/spec/support/{within.rb → matchers/within.rb} +3 -3
  94. data/spec/within_spec.rb +2 -2
  95. data/stacked.gemspec +23 -112
  96. metadata +248 -54
  97. data/README.rdoc +0 -18
  98. data/VERSION +0 -1
  99. data/doc/Stacked.html +0 -155
  100. data/doc/Stacked/Answer.html +0 -1394
  101. data/doc/Stacked/Badge.html +0 -480
  102. data/doc/Stacked/Base.html +0 -1124
  103. data/doc/Stacked/Comment.html +0 -1037
  104. data/doc/Stacked/NotImplemented.html +0 -162
  105. data/doc/Stacked/Posttimeline.html +0 -543
  106. data/doc/Stacked/Question.html +0 -1763
  107. data/doc/Stacked/Reputation.html +0 -606
  108. data/doc/Stacked/Tag.html +0 -267
  109. data/doc/Stacked/User.html +0 -2787
  110. data/doc/Stacked/Usertimeline.html +0 -630
  111. data/doc/_index.html +0 -246
  112. data/doc/file.README.html +0 -54
  113. data/doc/index.html +0 -54
  114. data/doc/method_list.html +0 -1203
  115. data/doc/top-level-namespace.html +0 -87
  116. data/lib/stacked/posttimeline.rb +0 -10
@@ -1,14 +1,14 @@
1
1
  module Stacked
2
- # I would really *love* to call this UserTimeline but alas, the API fails me.
3
- class Usertimeline < Base
2
+ # Stacked::UserTimeline class.
3
+ class UserTimeline < Base
4
4
  attr_accessor :action,
5
5
  :comment_id,
6
6
  :creation_date,
7
7
  :description,
8
8
  :detail,
9
9
  :post_id,
10
- :timeline_type
11
-
12
- alias_method :created_at, :creation_date
10
+ :post_type,
11
+ :timeline_type,
12
+ :user_id
13
13
  end
14
14
  end
@@ -0,0 +1,4 @@
1
+ module Stacked
2
+ # Stacked version number.
3
+ VERSION = '1.0.0.beta1'
4
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,6 +1,6 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
- describe Spec::Matchers::Sortedby do
3
+ describe RSpec::Matchers::SortedBy do
4
4
  before do
5
5
  @questions = []
6
6
  @questions << Stacked::Question.new(:last_edit_date => Time.now.to_i)
@@ -1,16 +1,18 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
1
+ require 'rspec'
3
2
  require 'stacked'
4
- require 'spec'
5
- require 'spec/autorun'
6
- require 'fakeweb'
3
+ require 'webmock'
7
4
 
8
- Dir["spec/support/**/*.rb"].each { |f| require f }
5
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
9
6
 
10
7
  # Uncomment only for debugging as we only ever want to test against the real API.
11
8
  # At least, until it becomes stable.
12
9
  # FakeWeb.allow_net_connect = false
13
10
 
14
- Spec::Runner.configure do |config|
15
-
11
+ RSpec.configure do |c|
12
+ c.include(WebMock::API)
13
+ c.before(:all) do
14
+ Stacked::Client.configure do |config|
15
+ config.api_key = "FAKE"
16
+ end
17
+ end
16
18
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Stacked::Answer do
4
4
  context "class methods" do
@@ -8,21 +8,22 @@ describe Stacked::Answer do
8
8
  end
9
9
 
10
10
  context "instance methods" do
11
+ before(:all) do
12
+ fake "answers/1237127", :query => { :body => true }
13
+ fake "questions/1236996"
14
+ end
15
+
11
16
  subject { Stacked::Answer.find(1237127, :body => true) }
17
+
12
18
  it "finds the user for an answer" do
13
- subject.user.display_name.should eql("Daniel Vandersluis")
19
+ subject.owner.should be_is_a(Stacked::User)
20
+ subject.owner.display_name.should eql("Daniel Vandersluis")
14
21
  end
15
22
 
16
23
  it "finds the question for an answer" do
17
24
  subject.question.should be_is_a(Stacked::Question)
18
25
  end
19
26
 
20
- aliases(:views => :view_count,
21
- :up_votes => :up_vote_count,
22
- :answer_id => :id,
23
- :created_at => :creation_date,
24
- :updated_at => :last_edit_date)
25
-
26
27
  it "has a body" do
27
28
  subject.body.should_not be_blank
28
29
  end
@@ -1,9 +1,17 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Stacked::Badge do
4
4
  subject { Stacked::Badge }
5
+
6
+ before :all do
7
+ fake "badges"
8
+ fake "badges/name"
9
+ fake "badges/tags"
10
+ end
11
+
5
12
  it "finds all badges" do
6
- subject.all.first.should be_is_a(Stacked::Badge)
13
+ badge = subject.all.first
14
+ badge.should be_is_a(Stacked::Badge)
7
15
  end
8
16
 
9
17
  it "finds all badges ordered by name" do
@@ -11,7 +19,7 @@ describe Stacked::Badge do
11
19
  end
12
20
 
13
21
  it "finds all badges based on tags" do
14
- subject.tags.first.name.should eql(".net")
22
+ subject.tags.first.name.should eql(".htaccess")
15
23
  end
16
24
 
17
25
  end
@@ -1,16 +1,25 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Stacked::Base do
4
4
  context "common methods" do
5
5
  # We cannot use Stacked::Base here obviously because SO does not have Bases!
6
6
  # So we use User instead.
7
7
  subject { Stacked::User }
8
+
9
+ before(:all) do
10
+ fake "users"
11
+ fake "users/index-page2", :url_path => 'users', :query => { :page => 2 }
12
+ fake "users/index-pagesize1", :url_path => 'users', :query => { :pagesize => 1 }
13
+ fake "stats"
14
+ end
8
15
 
9
16
  it "retrieves a list of a resource" do
17
+ #pending("Crack::ParseError: Invalid JSON string")
10
18
  subject.all.all? { |u| u.is_a?(subject) }.should be_true
11
19
  end
12
20
 
13
21
  it "paginates through the resource" do
22
+ #pending("Crack::ParseError: Invalid JSON string")
14
23
  subject.all.first.should_not eql(subject.all(:page => 2).first)
15
24
  end
16
25
 
@@ -19,7 +28,20 @@ describe Stacked::Base do
19
28
  end
20
29
 
21
30
  it "stats" do
22
- Stacked::Base.stats.keys.sort.should eql(["answers_per_minute", "api_version", "badges_per_minute", "questions_per_minute", "total_answers", "total_badges", "total_comments", "total_questions", "total_unanswered", "total_users", "total_votes"])
31
+ Stacked::Base.stats.keys.sort.should eql(["answers_per_minute",
32
+ "api_version",
33
+ "badges_per_minute",
34
+ "questions_per_minute",
35
+ "site",
36
+ "total_accepted",
37
+ "total_answers",
38
+ "total_badges",
39
+ "total_comments",
40
+ "total_questions",
41
+ "total_unanswered",
42
+ "total_users",
43
+ "total_votes",
44
+ "views_per_day"])
23
45
  end
24
46
 
25
47
  end
@@ -1,7 +1,13 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Stacked::Comment do
4
4
  subject { Stacked::Comment }
5
+
6
+ before(:all) do
7
+ fake "comments/2561833"
8
+ fake "comments/1063043"
9
+ fake "answers/2558700" # referenced by subject.post
10
+ end
5
11
 
6
12
  context "class methods" do
7
13
 
@@ -12,25 +18,21 @@ describe Stacked::Comment do
12
18
  it "finds a single comment" do
13
19
  comment = Stacked::Comment.find(2561833)
14
20
  comment.should be_is_a(Stacked::Comment)
15
- comment.owner_user_id.should eql(22656)
21
+ comment.owner.should be_is_a(Stacked::User)
22
+ comment.owner.user_id.should eql(22656)
16
23
  end
17
24
  end
18
25
 
19
26
  context "instance methods" do
20
27
  subject { Stacked::Comment.find(2561833) }
21
28
 
22
- aliases(:comment_id => :id,
23
- :created_at => :creation_date,
24
- :owner => :user,
25
- :edits => :edit_count)
26
-
27
29
  it "finds the related post for this comment" do
28
30
  subject.post.should be_is_a(Stacked::Answer)
29
31
  end
30
32
 
31
33
  it "finds who the comment was directed at, or nobody if nobody" do
32
- Stacked::Comment.find(2561833).reply_to.should be_is_a(Stacked::User)
33
- Stacked::Comment.find(1063043).reply_to.should be_nil
34
+ Stacked::Comment.find(2561833).reply_to_user.should be_is_a(Stacked::User)
35
+ Stacked::Comment.find(1063043).reply_to_user.should be_nil
34
36
  end
35
37
 
36
38
  it "finds the user who wrote the comment" do
@@ -1,108 +1,96 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Stacked::Question do
4
+
4
5
  context "class methods" do
6
+
5
7
  subject { Stacked::Question }
8
+
9
+ before(:all) do
10
+ #fake "questions", :query => { :answers => true, :comments => true, :body => true }
11
+
12
+ fake "questions"
13
+ fake "questions/withcomments", :url_path => 'questions', :query => { :comments => true }
14
+
15
+ fake "questions/search", :url_path => 'search', :query => { :intitle => 'ImageMagick' }
16
+ fake "questions/unanswered"
17
+ fake "questions/4839321/answers"
18
+ fake "questions/tagged", :url_path => 'questions', :query => { :tagged => ["ruby", "ruby-on-rails"].join(';') }
19
+ end
20
+
6
21
  it "gets a list of all questions" do
22
+ #pending("Crack::ParseError: Invalid JSON string")
7
23
  subject.all.all? { |q| q.is_a?(subject) }.should be_true
8
24
  end
9
-
25
+
10
26
  it "gets a list of questions with comments" do
11
- pending("Cannot currently get a list of questions with comments")
12
- subject.all(:comments => true)
13
- end
14
-
15
- it "active" do
16
- subject.active(:pagesize => 1).first.last_activity_date.should be_within(1.day)
17
- end
18
-
19
- it "newest" do
20
- subject.newest(:pagesize => 1).first.creation_date.should be_within(1.day)
21
- end
22
-
23
- it "featured" do
24
- (subject.featured(:pagesize => 1).first.bounty_closes_date > Time.now.to_i).should be_true
25
- end
26
-
27
- it "hot" do
28
- # It was 3555 as of 3rd April 2010.
29
- (subject.hot(:pagesize => 1).first.view_count > 3555).should be_true
27
+ subject.all(:comments => true).first.comments.should_not be_nil
30
28
  end
31
-
32
- it "month" do
33
- subject.month(:pagesize => 1).first.creation_date.should be_within(1.month)
34
- end
35
-
36
- it "week" do
37
- subject.week(:pagesize => 1).first.creation_date.should be_within(1.week)
38
- end
39
-
40
- it "votes" do
41
- subject.votes(:pagesize => 1).first.up_vote_count.should eql(1190)
29
+
30
+ it "search" do
31
+ #pending("Endpoint appears to be broken at the time of testing. Always returning no results.")
32
+ question = subject.search(:intitle => 'ImageMagick').first
33
+ question.title.should =~ /ImageMagick/i
42
34
  end
43
35
 
44
- it "unanswered by votes" do
45
- question = subject.unanswered_by_votes(:pagesize => 1).first
36
+ it "unanswered" do
37
+ question = subject.unanswered.first
46
38
  question.should be_is_a(Stacked::Question)
47
39
  question.answers.should be_blank
48
40
  end
49
41
 
50
42
  it "tagged" do
51
- question = subject.tagged(:tags => ["ruby", "ruby-on-rails"], :pagesize => 1).first
43
+ question = subject.all(:tagged => ["ruby", "ruby-on-rails"].join(';')).first
52
44
  question.tags.map(&:name).should include("ruby")
53
45
  question.tags.map(&:name).should include("ruby-on-rails")
54
46
  end
55
47
  end
56
48
 
57
49
  context "instance methods" do
58
- subject { Stacked::Question.find(1236996, :comments => true, :body => true) }
59
-
60
- aliases(
61
- :created_at => :creation_date,
62
- :down_votes => :down_vote_count,
63
- :favorites => :favorite_count,
64
- :favourites => :favorite_count,
65
- :id => :question_id,
66
- :updated_at => :last_edit_date,
67
- :up_votes => :up_vote_count,
68
- :user => :owner,
69
- :views => :view_count
70
- )
71
-
50
+ before(:all) do
51
+ fake "questions/1236996", :query => { :answers => true, :comments => true, :body => true }
52
+ fake "questions/1236996-comments", :url_path => 'questions/1236996/comments' # question.comments
53
+ fake "questions/1236996-answers", :url_path => 'questions/1236996/answers' # question.answers
54
+ fake "questions/1236996-timeline", :url_path => 'questions/1236996/timeline' # question.timeline
55
+ fake "answers/1237127" # question.accepted_answer
56
+
57
+ # Ensure only one API request per resouce
58
+ @question = Stacked::Question.find(1236996, :answers => true, :comments => true, :body => true)
59
+ end
72
60
 
73
61
  it "is the right question" do
74
- subject.title.should eql("Calculating the distance between two times")
62
+ @question.title.should eql("Calculating the distance between two times")
75
63
  end
76
64
 
77
65
  it "has a body" do
78
- subject.body.should_not be_blank
66
+ @question.body.should_not be_blank
79
67
  end
80
-
68
+
81
69
  it "retreives comments" do
82
- subject.comments.should_not be_empty
83
- subject.comments.first.should be_is_a(Stacked::Comment)
70
+ @question.comments.should_not be_empty
71
+ @question.comments.first.should be_is_a(Stacked::Comment)
84
72
  end
85
73
 
86
74
  it "retreives answers" do
87
- subject.answers.should_not be_empty
88
- subject.answers.first.should be_is_a(Stacked::Answer)
75
+ @question.answers.should_not be_empty
76
+ @question.answers.first.should be_is_a(Stacked::Answer)
89
77
  end
90
78
 
91
79
  it "retreives tags" do
92
- subject.tags.should_not be_empty
93
- subject.tags.first.should be_is_a(Stacked::Tag)
80
+ @question.tags.should_not be_empty
81
+ @question.tags.first.should be_is_a(Stacked::Tag)
94
82
  end
95
83
 
96
84
  it "finds the user for a question" do
97
- subject.user.should be_is_a(Stacked::User)
85
+ @question.owner.should be_is_a(Stacked::User)
98
86
  end
99
87
 
100
88
  it "finds the accepted answer" do
101
- subject.accepted_answer.should be_is_a(Stacked::Answer)
89
+ @question.accepted_answer.should be_is_a(Stacked::Answer)
102
90
  end
103
91
 
104
92
  it "shows the timeline of the question" do
105
- subject.timeline.first.should be_is_a(Stacked::Posttimeline)
93
+ @question.timeline.first.should be_is_a(Stacked::PostTimeline)
106
94
  end
107
95
 
108
96
  end