ruby-hackernews 1.3.6 → 1.3.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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzI2MGUxMzBjOWQxN2I1ODExNTU4ZDkxZmE3NTgxMDMwMWZjNDhkNw==
5
- data.tar.gz: !binary |-
6
- Njg3MWZhYjFlODNkY2VlNDZiY2U2NWYxZTkyYTIwOTg4MDdjZTUyYg==
2
+ SHA1:
3
+ metadata.gz: a75ae2b32c9d840dd595bb25dfde7ca86364fecd
4
+ data.tar.gz: 3b125a1e73964ed58d0c1f7c51c105c667f08a2c
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MmU2YWFmYmNlZDEwZGYxMTE2OWJkMTk5MWM3NDRmNTQzZGYwMDgxYTEwNzY1
10
- MzJhYjU4YTUyZjgyMWYxZGFlZDViNjMyOGYzODBkZTE0ZjM4NGNmOGVkODNk
11
- YjI5ZjU2MDJlYjM4YTQzZDhmN2YyMzIyMjdmNGRmNTVlMGFmOTQ=
12
- data.tar.gz: !binary |-
13
- N2RmNmNlNjIwYjNjOTg1MmJlNzE4Y2I4MWUwNWFkZjBiNjQzOTYyODQ5ZTYx
14
- MjYwYzQ0ZDUxYTZjNGExYjM3YmUyZDE4NGZkYTczNWFiNzFiY2VlZmE4MDdl
15
- NWE2NDZiY2Q3ZGNmYzJhYzI1YTVlZTYwOTgyNDg1NmMwZjE5Nzc=
6
+ metadata.gz: e014746411f77467c3f4bd70a82acfab27d93b5e5713c5552029ed3f9df85db1dac81f8a97cb6189501d0ec1053a7b6033bbee2586a59fcf36805003f61fba7d
7
+ data.tar.gz: 8132a51491bf5b966810d5cf7ec00a203f2c54dece9d5dd9b3209ea89426bd6637ab81fe405671e57fe7b4cc8e409707bde1609848fef75801fc21ede64f268d
data/README.rdoc CHANGED
@@ -172,3 +172,5 @@ Will return the HN comment url of the last submitted story of that user
172
172
  - Daniel Da Cunha ( http://github.com/ddacunha ) for a fix on Entry#comments_count
173
173
  - Nathan Campos ( http://github.com/nathanpc) for adding #text to Entry
174
174
  - Girish Sonawane ( https://github.com/girishso) for adding Entry#shows and Entry#new_shows methods
175
+ - Niels Van Aken ( https://github.com/nvaken ) for a bugfix in EntryPageParser
176
+ - Pedro Lambert ( https://github.com/p-lambert ) for fixing bugs and improving structure of CommentInfoParser, TimeInfoParser and UserInfoParser
@@ -65,10 +65,7 @@ module RubyHackernews
65
65
  end
66
66
 
67
67
  def parse_comment(element)
68
- text_html = ""
69
- element.search("span.comment").first.children.each do |ch|
70
- text_html = ch.inner_html
71
- end
68
+ text_html = element.search("span.comment").first.search("font").children.map { |x| x.inner_text }.join("\n")
72
69
  header = element.search("span.comhead").first
73
70
  voting = VotingInfoParser.new(element.search("td/center/a"), header).parse
74
71
  user_info = UserInfoParser.new(header).parse
@@ -2,18 +2,27 @@ module RubyHackernews
2
2
 
3
3
  class CommentsInfoParser
4
4
 
5
- def initialize(comments_element)
6
- @element = comments_element.search("a")[1]
5
+ def initialize(second_line)
6
+ @second_line = second_line
7
7
  end
8
8
 
9
9
  def parse
10
- comments_info = nil
11
- if @element && @element['href'] =~ /id/
12
- comments = @element.inner_html.split[0].to_i
13
- comments_page = @element['href']
14
- comments_info = CommentsInfo.new(comments, comments_page)
15
- end
16
- return comments_info
10
+ return unless comments_link
11
+
12
+ comments = comments_link.text.split[0].to_i
13
+ comments_page = comments_link['href']
14
+
15
+ CommentsInfo.new(comments, comments_page)
16
+ end
17
+
18
+ private
19
+
20
+ def comments_link
21
+ links.find { |link| link.text =~ /comment|discuss/ }
22
+ end
23
+
24
+ def links
25
+ @second_line.css('a')
17
26
  end
18
27
 
19
28
  end
@@ -20,12 +20,12 @@ module RubyHackernews
20
20
  number = number_segment.inner_html.sub(".","").to_i if number_segment
21
21
  link = LinkInfoParser.new(link_segment).parse
22
22
  voting = VotingInfoParser.new(@first_line.search("td/center/a"), @second_line.search("[@class='subtext']")[0]).parse
23
- user = UserInfoParser.new(@second_line.search("[@class='subtext']")[0]).parse
24
- comments = CommentsInfoParser.new(@second_line.search("[@class='subtext']")[0]).parse
25
- time = TimeInfoParser.new(@second_line.search("[@class='subtext']").children[3]).parse
23
+ user = UserInfoParser.new(@second_line).parse
24
+ comments = CommentsInfoParser.new(@second_line).parse
25
+ time = TimeInfoParser.new(@second_line).parse
26
26
  return Entry.new(number, link, voting, user, comments, time)
27
27
  end
28
-
28
+
29
29
  end
30
30
 
31
31
  end
@@ -2,18 +2,28 @@ module RubyHackernews
2
2
 
3
3
  class TimeInfoParser
4
4
 
5
- def initialize(time_element)
6
- @element = time_element
5
+ def initialize(second_line)
6
+ @second_line = second_line
7
7
  end
8
8
 
9
9
  def parse
10
- if @element
11
- value = @element.text.strip.split[0].to_i
12
- unit_of_measure = @element.text.strip.split[1]
13
- end
14
- return TimeInfo.new(value, unit_of_measure)
10
+ return unless time_link
11
+
12
+ value = time_link.text.strip.split[0].to_i
13
+ unit_of_measure = time_link.text.strip.split[1]
14
+
15
+ TimeInfo.new(value, unit_of_measure)
16
+ end
17
+
18
+ private
19
+
20
+ def time_link
21
+ links.find { |link| link.text =~ /\sago/ }
15
22
  end
16
23
 
24
+ def links
25
+ @second_line.css('a')
26
+ end
17
27
  end
18
28
 
19
29
  end
@@ -2,17 +2,27 @@ module RubyHackernews
2
2
 
3
3
  class UserInfoParser
4
4
 
5
- def initialize(user_element)
6
- @element = user_element
5
+ def initialize(second_line)
6
+ @second_line = second_line
7
7
  end
8
8
 
9
9
  def parse
10
- user_element = @element.search("a")[0]
11
- if user_element
12
- user_name = user_element.inner_html
13
- user_page = user_element['href']
14
- end
15
- return UserInfo.new(user_name, user_page)
10
+ return unless user_link
11
+
12
+ user_name = user_link.inner_html
13
+ user_page = user_link['href']
14
+
15
+ UserInfo.new(user_name, user_page)
16
+ end
17
+
18
+ private
19
+
20
+ def user_link
21
+ links.find { |link| link['href'] =~ /user\?id=/ }
22
+ end
23
+
24
+ def links
25
+ @second_line.css('a')
16
26
  end
17
27
 
18
28
  end
@@ -1,3 +1,3 @@
1
1
  module RubyHackernews
2
- VERSION = "1.3.6"
2
+ VERSION = "1.3.7"
3
3
  end
@@ -7,41 +7,39 @@ module RubyHackernews
7
7
  describe :get_entries do
8
8
 
9
9
  it "should always call EntryPageParser with current agent" do
10
- parser = stub()
11
- parser.should_receive(:get_lines).and_return([])
12
- parser.should_receive(:get_next_url).and_return(nil)
13
- agent = stub()
14
- agent.should_receive(:get).any_number_of_times.and_return(:page)
15
- MechanizeContext.create(:default, agent)
10
+ parser = Object.new
11
+ allow(parser).to receive_messages(:get_lines => [], :get_next_url => nil)
12
+ agent = Object.new
13
+ allow(agent).to receive_messages(:get => :page)
14
+ MechanizeContext.send(:class_variable_set, :@@contexts, {:default => agent})
16
15
  service = EntryService.new
17
- EntryPageParser.should_receive(:new).any_number_of_times.with(:page).and_return(parser)
16
+ expect(EntryPageParser).to receive(:new).at_least(1).with(:page).and_return(parser)
18
17
  service.get_entries
19
18
  end
20
19
 
21
20
  it "should always call get_lines 'pages' number of times" do
22
21
  pages = 5
23
- parser = stub()
24
- parser.should_receive(:get_lines).exactly(pages).times.and_return([])
25
- parser.should_receive(:get_next_url).any_number_of_times.and_return(nil)
26
- agent = stub()
27
- agent.should_receive(:get).any_number_of_times.and_return(:page)
28
- MechanizeContext.create(:default, agent)
22
+ parser = Object.new
23
+ expect(parser).to receive(:get_lines).and_return([])
24
+ allow(parser).to receive(:get_next_url).and_return(nil)
25
+ agent = Object.new
26
+ allow(agent).to receive_messages(:get => :page)
27
+ MechanizeContext.send(:class_variable_set, :@@contexts, {:default => agent})
29
28
  service = EntryService.new
30
- EntryPageParser.should_receive(:new).any_number_of_times.with(:page).and_return(parser)
31
- service.get_entries(pages)
29
+ allow(EntryPageParser).to receive(:new).with(:page).and_return(parser)
30
+ service.get_entries
32
31
  end
33
32
 
34
33
  it "should always call get_next_url 'pages' number of times" do
35
- pages = 5
36
- parser = stub()
37
- parser.should_receive(:get_lines).any_number_of_times.and_return([])
38
- parser.should_receive(:get_next_url).exactly(pages).times.and_return(nil)
39
- agent = stub()
40
- agent.should_receive(:get).any_number_of_times.and_return(:page)
41
- MechanizeContext.create(:default, agent)
34
+ parser = Object.new
35
+ allow(parser).to receive(:get_lines).and_return([])
36
+ expect(parser).to receive(:get_next_url).and_return(nil)
37
+ agent = Object.new
38
+ allow(agent).to receive_messages(:get => :page)
39
+ MechanizeContext.send(:class_variable_set, :@@contexts, {:default => agent})
42
40
  service = EntryService.new
43
- EntryPageParser.should_receive(:new).any_number_of_times.with(:page).and_return(parser)
44
- service.get_entries(pages)
41
+ allow(EntryPageParser).to receive(:new).with(:page).and_return(parser)
42
+ service.get_entries
45
43
  end
46
44
 
47
45
  end
@@ -21,14 +21,14 @@ class ParserHelper
21
21
  return Nokogiri::HTML.fragment('<a id=up_1645686 href="vote?for=1645686&dir=up&whence=%6e%65%77%73"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><a id=down_1645686 href="vote?for=1645686&dir=up&whence=%6e%65%77%73"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a>'
22
22
  ).children
23
23
  end
24
-
24
+
25
25
  #username : johnthedebs
26
26
  #user page : user?id=johnthedebs
27
27
  #score : 17
28
28
  #comments : 2
29
29
  #comment_page : item?id=1645686
30
30
  def self.second_line
31
- return Nokogiri::HTML.fragment('<td class="subtext"><span id=score_1645686>17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> 4 hours ago | <a href="item?id=1645686">2 comments</a></td>')
31
+ return Nokogiri::HTML.fragment('<td class="subtext"><span class="score" id="score_1645686">17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> <a href="item?id=1645686">4 hours ago</a> | <a href="item?id=1645686">2 comments</a></td>')
32
32
  end
33
33
 
34
34
  #username : johnthedebs
@@ -36,7 +36,7 @@ class ParserHelper
36
36
  #score : 17
37
37
  #comment_page : item?id=1645686
38
38
  def self.second_line_no_comments_yet
39
- return Nokogiri::HTML.fragment('<td class="subtext"><span id=score_1645686>17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> 4 hours ago | <a href="item?id=1645686">discuss</a></td>')
39
+ return Nokogiri::HTML.fragment('<td colspan="2"></td><td class="subtext"><span class="score" id="score_1645686">17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> <a href="item?id=1645686">4 hours ago</a> | <a href="item?id=1645686">discuss</a></td>')
40
40
  end
41
41
 
42
42
  #username : johnthedebs
@@ -64,14 +64,14 @@ class ParserHelper
64
64
  end
65
65
 
66
66
  def self.second_line_full
67
- return Nokogiri::HTML('<tr><td colspan=2></td><td class="subtext"><span id=score_1645745>59 points</span> by <a href="user?id=dhotson">dhotson</a> 4 hours ago | <a href="item?id=1645745">5 comments</a></td></tr>')
67
+ Nokogiri::HTML.fragment('<tr><td colspan=2></td><td class="subtext"><span class="score" id="score_1645745">59 points</span> by <a href="user?id=dhotson">dhotson</a> <a href="item?id=1645745">4 hours ago</a> | <a href="item?id=1645745">5 comments</a></td></tr>')
68
68
  end
69
69
 
70
70
  def self.full_page
71
71
  File.open(File.join(File.dirname(__FILE__), 'hn_test_page.html'), 'r') do |file|
72
72
  return Nokogiri::HTML(file)
73
73
  end
74
-
74
+
75
75
  end
76
76
 
77
77
  end
@@ -1,10 +1,11 @@
1
1
  require 'spec_helper'
2
+ require File.join(File.dirname(__FILE__), 'parser_helper')
2
3
 
3
4
  module RubyHackernews
4
5
  describe TimeInfoParser do
5
6
 
6
7
  before :each do
7
- @parser = TimeInfoParser.new(stub(:text => " 4 hours ago | "))
8
+ @parser = TimeInfoParser.new(ParserHelper.second_line)
8
9
  end
9
10
 
10
11
  describe :parse do
@@ -22,4 +23,3 @@ module RubyHackernews
22
23
  end
23
24
  end
24
25
  end
25
-
@@ -8,25 +8,6 @@ module RubyHackernews
8
8
  MechanizeContext.send(:class_variable_set, :@@default, nil)
9
9
  end
10
10
 
11
- describe "create" do
12
-
13
- it "should instantiate class variable on use" do
14
- MechanizeContext.create()
15
- MechanizeContext.send(:class_variable_get, :@@contexts).should_not be_nil
16
- end
17
-
18
- it "should assign new agent to hash[key]" do
19
- MechanizeContext.create(:test_key)
20
- MechanizeContext.send(:class_variable_get, :@@contexts)[:test_key].should be_kind_of Mechanize
21
- end
22
-
23
- it "should assign new agent to default if no key passed" do
24
- MechanizeContext.create
25
- MechanizeContext.send(:class_variable_get, :@@contexts)[:default].should be_kind_of Mechanize
26
- end
27
-
28
- end
29
-
30
11
  describe "agent=" do
31
12
 
32
13
  it "should set @@default as passed key" do
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-hackernews
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.6
4
+ version: 1.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrea Dallera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-16 00:00:00.000000000 Z
11
+ date: 2015-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: require_all
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.1.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.1.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mechanize
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 1.0.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.0.0
69
69
  description: An interface to Hacker News
@@ -73,7 +73,7 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
- - .gitignore
76
+ - ".gitignore"
77
77
  - Gemfile
78
78
  - README.rdoc
79
79
  - Rakefile
@@ -129,17 +129,17 @@ require_paths:
129
129
  - lib
130
130
  required_ruby_version: !ruby/object:Gem::Requirement
131
131
  requirements:
132
- - - ! '>='
132
+ - - ">="
133
133
  - !ruby/object:Gem::Version
134
134
  version: '0'
135
135
  required_rubygems_version: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - ! '>='
137
+ - - ">="
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  requirements: []
141
141
  rubyforge_project:
142
- rubygems_version: 2.2.2
142
+ rubygems_version: 2.0.0
143
143
  signing_key:
144
144
  specification_version: 4
145
145
  summary: An interface to Hacker News