ruby-hackernews 1.3.6 → 1.3.7

Sign up to get free protection for your applications and to get access to all the features.
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