pavlov_rss 0.0.3 → 0.0.4

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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 124cdf8d9daf80cd1469a706a6c3c910070b3e7b
4
- data.tar.gz: 5e73a02d74061640507c3157eedce1e09067e14d
3
+ metadata.gz: 35a29663a549afb08c61d6f4b88619c588d6c172
4
+ data.tar.gz: 9b74530d53d962b0f2c9d50c9558a73ea15f8b5e
5
5
  SHA512:
6
- metadata.gz: 41318068f97592b7e7ca3a82912c8aee572ae211c77c1be46bd1147dcfc4f00cec03189bd0e3b89b01bb94c6a0bb2280e1ca34218b1f89d8b659915368c57587
7
- data.tar.gz: d2dd2b40e53d911cb9d9887922272545a9e8978cc68c73c56524f5c5d50fb8a9202a71a673e7132d6a806e968f20728581630290707e5ab44913ea4313c875a9
6
+ metadata.gz: ff7e6ae7cf8950adc99ae1efacd8a043dc35a17fcda5b172185c7645fef399204a78fa02f466b3f7e2c106c04afb9ae1da1a9592af112d3d3c12cf25d719b748
7
+ data.tar.gz: a58856d9e2bb5763a98a1eebd3740cfabc2a4e9b2ec5148035c446ae5462aeb4c7ae01e46bf416ec9abb844f0c33d425a2d9221fcdb02ac53d3c5b1ca08d30cb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pavlov_rss (0.0.3)
4
+ pavlov_rss (0.0.4)
5
5
  activesupport
6
6
  nokogiri
7
7
 
@@ -4,42 +4,36 @@ require 'active_support/core_ext'
4
4
 
5
5
  module PavlovRss
6
6
  class Reader
7
- def initialize(urls_or_lambdas)
8
- @lambdas = Array(urls_or_lambdas).map do |url_or_lambda|
9
- case url_or_lambda
10
- when String
11
- lambda {open(url_or_lambda, &:read)}
12
- else
13
- url_or_lambda
14
- end
15
- end
7
+ def opener &opener
8
+ @opener = opener
9
+ end
10
+
11
+ def fetch
12
+ hash_to_item(rss_to_hash(Nokogiri.XML(@opener.call)))
16
13
  end
17
14
 
18
15
  def check
19
- now = @lambdas.map(&:call).map(&Nokogiri.method(:XML))
16
+ now = fetch
20
17
  @prev ||= now
21
- result = @prev.zip(now).map do |p,n|
22
- new_items p, n
23
- end
18
+ result = now - @prev
24
19
  @prev = now
25
20
  return result
26
21
  end
27
22
 
28
- def item_to_json rss
29
- value = Hash.from_xml(rss.to_xml)
23
+ def rss_to_hash rss
24
+ Hash.from_xml(rss.to_xml)
25
+ end
26
+
27
+ def hash_to_item hash
30
28
  result = case
31
- when value.has_key?('rss')
32
- value['rss']['channel']['item']
29
+ when hash.has_key?('rss')
30
+ hash['rss']['channel']['item']
33
31
  when value.has_key?('feed')
34
- value['feed']['entry']
32
+ hash['feed']['entry']
35
33
  end
36
34
  result ||= []
37
35
  return result if result.is_a? Array
38
36
  return [result]
39
37
  end
40
-
41
- def new_items lhs, rhs
42
- item_to_json(rhs) - item_to_json(lhs)
43
- end
44
38
  end
45
39
  end
@@ -1,3 +1,3 @@
1
1
  module PavlovRss
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -1,185 +1,203 @@
1
1
  require 'spec_helper'
2
2
  require 'pavlov_rss'
3
3
  require 'nokogiri'
4
- require 'fake_web'
5
4
 
6
5
  describe PavlovRss::Reader do
7
- after do
8
- FakeWeb.clean_registry
6
+ describe '#hash_to_item' do
7
+ subject { described_class.new.hash_to_item(hash) }
8
+
9
+ describe do
10
+ let(:hash) do
11
+ {'rss' => {'channel' => {'item' => []}}}
12
+ end
13
+ it { should be_empty }
14
+ end
15
+
16
+ describe do
17
+ let(:hash) do
18
+ {'rss' => {'channel' => {'item' =>
19
+ {'title' => 'title1'}
20
+ }}}
21
+ end
22
+ it { should have(1).item }
23
+ end
24
+
25
+ describe do
26
+ let(:hash) do
27
+ {'rss' => {'channel' => {'item' => [
28
+ {'title' => 'title1'},
29
+ {'title' => 'title2'},
30
+ ]}}}
31
+ end
32
+ it { should have(2).items }
33
+ end
9
34
  end
10
35
 
11
- context "with an example reader" do
12
- before do
13
- @url = "http://example.com/rss.xml"
14
- @reader = PavlovRss::Reader.new @url
15
- end
16
-
17
- describe "#check" do
18
- context "with static rss" do
19
- before do
20
- FakeWeb.register_uri(:get, @url, body: feed('rss1.xml'))
21
- end
22
-
23
- it "returns [[]] at first time" do
24
- @reader.check.should == [[]]
25
- end
26
-
27
- it "returns [[]] without changes" do
28
- @reader.check
29
- @reader.check.should == [[]]
30
- end
31
- end
32
-
33
- it "does not return [[]] with any chagnes" do
34
- FakeWeb.register_uri(:get, @url, [
35
- {body: feed('rss1.xml')},
36
- {body: feed('rss2.xml')},
37
- ])
38
- @reader.check
39
- @reader.check.should_not == [[]]
40
- end
41
-
42
- it "returns new items" do
43
- FakeWeb.register_uri(:get, @url, [
44
- {body: feed('rss0.xml')},
45
- {body: feed('rss1.xml')},
46
- {body: feed('rss2.xml')},
47
- {body: feed('rss3.xml')},
48
- {body: feed('rss4.xml')},
49
- {body: feed('rss5.xml')},
50
- ])
51
- @reader.check
52
- @reader.check.should == [[
53
- {
54
- "title"=>"title1",
55
- "link"=>"http://example.com/title1",
56
- "description"=>"description1"
57
- }]]
58
- @reader.check.should == [[
59
- {
60
- "title"=>"title2",
61
- "link"=>"http://example.com/title2",
62
- "description"=>"description2"
63
- }]]
64
- @reader.check.should == [[
65
- {
66
- "title"=>"title3",
67
- "link"=>"http://example.com/title3",
68
- "description"=>"description3"
69
- }]]
70
- @reader.check.should == [[
71
- {
72
- "title"=>"title4",
73
- "link"=>"http://example.com/title4",
74
- "description"=>"description4"
75
- }]]
76
- @reader.check.should == [[
77
- {
78
- "title"=>"title5",
79
- "link"=>"http://example.com/title5",
80
- "description"=>"description5"
81
- }]]
82
- @reader.check.should == [[]]
83
- end
84
- end
85
-
86
- describe "#new_items" do
87
- it "returns empty with same rss" do
88
- rss1 = Nokogiri.XML(feed('rss1.xml'))
89
- rss2 = Nokogiri.XML(feed('rss1.xml'))
90
- items = @reader.new_items rss1, rss2
91
- items.should == []
92
- end
93
-
94
- it "returns empty with not same rss" do
95
- rss1 = Nokogiri.XML(feed('rss1.xml'))
96
- rss2 = Nokogiri.XML(feed('rss2.xml'))
97
- items = @reader.new_items rss1, rss2
98
-
99
- items.should == [
100
- {
101
- "title"=>"title2",
102
- "link"=>"http://example.com/title2",
103
- "description"=>"description2"
104
- }]
105
- end
106
- end
107
-
108
- describe "#item_to_json" do
109
- it "works" do
110
- rss = Nokogiri.XML(feed('rss1.xml'))
111
- result = @reader.item_to_json rss
112
- result.should == [
113
- {
114
- "title"=>"title1",
115
- "link"=>"http://example.com/title1",
116
- "description"=>"description1"
117
- }]
118
- end
119
- it "works on 0-items rss" do
120
- rss = Nokogiri.XML(feed('rss0.xml'))
121
- result = @reader.item_to_json rss
122
- result.should == []
123
- end
124
- it "works on atom" do
125
- atom = Nokogiri.XML(feed('atom.xml'))
126
- result = @reader.item_to_json atom
127
- result.should == [{
128
- "title"=>"title",
129
- "id"=>"tag_string",
130
- "content"=>"content"
131
- }]
36
+ describe '#rss_to_hash' do
37
+ shared_examples 'hashfied rss', rss_to_hash: :works do
38
+ subject { described_class.new.rss_to_hash(Nokogiri.XML(rss)) }
39
+ it { should == expected }
40
+ end
41
+
42
+ describe 'works on general rss', rss_to_hash: :works do
43
+ let(:rss) { feed('rss2.xml') }
44
+ let(:expected) do
45
+ {'rss'=>{'version'=>'2.0', 'channel'=>{'title'=>'title', 'link'=>'http://example.com', 'description'=>'description', 'item'=>[{'title'=>'title2', 'link'=>'http://example.com/title2', 'description'=>'description2'}, {'title'=>'title1', 'link'=>'http://example.com/title1', 'description'=>'description1'}]}}}
46
+ end
47
+ end
48
+
49
+ describe 'works on 1-item rss', rss_to_hash: :works do
50
+ let(:rss) { feed('rss1.xml') }
51
+ let(:expected) do
52
+ {'rss' => {'version'=>'2.0', 'channel'=>{'title'=>'title', 'link'=>'http://example.com', 'description'=>'description', 'item'=>{'title'=>'title1', 'link'=>'http://example.com/title1', 'description'=>'description1'}}}}
53
+ end
54
+ end
55
+
56
+ describe 'works on 0-item rss', rss_to_hash: :works do
57
+ let(:rss) { feed('rss0.xml') }
58
+ let(:expected) do
59
+ {'rss' => {'version'=>'2.0', 'channel'=>{'title'=>'title', 'link'=>'http://example.com', 'description'=>'description'}}}
60
+ end
61
+ end
62
+
63
+ describe 'works on atom', rss_to_hash: :works do
64
+ let(:rss) { feed('atom.xml') }
65
+ let(:expected) do
66
+ {'feed'=>{'xmlns'=>'http://www.w3.org/2005/Atom', 'entry'=>{'title'=>'title', 'id'=>'tag_string', 'content'=>'content'}}}
132
67
  end
133
68
  end
134
69
  end
135
70
 
136
- context 'with a labmda' do
137
- before do
138
- @url = "http://example.com/rss.xml"
139
- @reader = PavlovRss::Reader.new lambda { open(@url, &:read) }
140
- end
141
- describe '#check' do
142
- it 'works' do
143
- FakeWeb.register_uri(:get, @url, [
144
- {body: feed('rss0.xml')},
145
- {body: feed('rss1.xml')},
146
- {body: feed('rss2.xml')},
147
- {body: feed('rss3.xml')},
148
- {body: feed('rss4.xml')},
149
- {body: feed('rss5.xml')},
150
- ])
151
- @reader.check
152
- @reader.check.should == [[
153
- {
154
- "title"=>"title1",
155
- "link"=>"http://example.com/title1",
156
- "description"=>"description1"
157
- }]]
158
- @reader.check.should == [[
159
- {
160
- "title"=>"title2",
161
- "link"=>"http://example.com/title2",
162
- "description"=>"description2"
163
- }]]
164
- @reader.check.should == [[
165
- {
166
- "title"=>"title3",
167
- "link"=>"http://example.com/title3",
168
- "description"=>"description3"
169
- }]]
170
- @reader.check.should == [[
171
- {
172
- "title"=>"title4",
173
- "link"=>"http://example.com/title4",
174
- "description"=>"description4"
175
- }]]
176
- @reader.check.should == [[
177
- {
178
- "title"=>"title5",
179
- "link"=>"http://example.com/title5",
180
- "description"=>"description5"
181
- }]]
182
- @reader.check.should == [[]]
71
+ describe '#fetch' do
72
+ shared_examples 'fetched rss', fetch: :works do
73
+ before { subject.opener { rss } }
74
+ its(:fetch) { should == expected }
75
+ end
76
+
77
+ describe 'works with rss0.xml', fetch: :works do
78
+ let(:rss) { feed('rss0.xml') }
79
+ let(:expected) { [] }
80
+ end
81
+
82
+ describe 'works with rss1.xml', fetch: :works do
83
+ let(:rss) { feed('rss1.xml') }
84
+ let(:expected) do
85
+ [
86
+ {"title"=>"title1", "link"=>"http://example.com/title1", "description"=>"description1"},
87
+ ]
88
+ end
89
+ end
90
+
91
+ describe 'works with rss2.xml', fetch: :works do
92
+ let(:rss) { feed('rss2.xml') }
93
+ let(:expected) do
94
+ [
95
+ {"title"=>"title2", "link"=>"http://example.com/title2", "description"=>"description2"},
96
+ {"title"=>"title1", "link"=>"http://example.com/title1", "description"=>"description1"},
97
+ ]
98
+ end
99
+ end
100
+
101
+ describe 'works with rss3.xml', fetch: :works do
102
+ let(:rss) { feed('rss3.xml') }
103
+ let(:expected) do
104
+ [
105
+ {"title"=>"title3", "link"=>"http://example.com/title3", "description"=>"description3"},
106
+ {"title"=>"title2", "link"=>"http://example.com/title2", "description"=>"description2"},
107
+ {"title"=>"title1", "link"=>"http://example.com/title1", "description"=>"description1"},
108
+ ]
109
+ end
110
+ end
111
+
112
+ describe 'works with rss4.xml', fetch: :works do
113
+ let(:rss) { feed('rss4.xml') }
114
+ let(:expected) do
115
+ [
116
+ {"title"=>"title4", "link"=>"http://example.com/title4", "description"=>"description4"},
117
+ {"title"=>"title3", "link"=>"http://example.com/title3", "description"=>"description3"},
118
+ {"title"=>"title2", "link"=>"http://example.com/title2", "description"=>"description2"},
119
+ ]
120
+ end
121
+ end
122
+
123
+ describe 'works with rss5.xml', fetch: :works do
124
+ let(:rss) { feed('rss5.xml') }
125
+ let(:expected) do
126
+ [
127
+ {"title"=>"title5", "link"=>"http://example.com/title5", "description"=>"description5"},
128
+ {"title"=>"title4", "link"=>"http://example.com/title4", "description"=>"description4"},
129
+ {"title"=>"title3", "link"=>"http://example.com/title3", "description"=>"description3"},
130
+ ]
131
+ end
132
+ end
133
+ end
134
+
135
+ describe '#check' do
136
+ shared_examples 'check works', check: :works do
137
+ before do
138
+ subject.stub(:fetch).and_return(*fetches)
139
+ subject.check.should be_empty
140
+ end
141
+ its(:check) { should == expected }
142
+ end
143
+
144
+ describe 'works with empty items', check: :works do
145
+ let(:fetches) { [[], []] }
146
+ let(:expected) { [] }
147
+ end
148
+
149
+ describe 'works with same items', check: :works do
150
+ let(:fetches) do
151
+ [
152
+ [{'title' => '1'}],
153
+ [{'title' => '1'}],
154
+ ]
155
+ end
156
+ let(:expected) { [] }
157
+ end
158
+
159
+ describe 'works with added items', check: :works do
160
+ let(:fetches) do
161
+ [
162
+ [],
163
+ [{'title' => '1'}],
164
+ ]
165
+ end
166
+ let(:expected) { [{'title' => '1'}] }
167
+ end
168
+
169
+ describe 'works with removed items', check: :works do
170
+ let(:fetches) do
171
+ [
172
+ [{'title' => '1'}],
173
+ [],
174
+ ]
175
+ end
176
+ let(:expected) { [] }
177
+ end
178
+
179
+ describe 'works with various items', check: :works do
180
+ let(:fetches) do
181
+ [
182
+ [
183
+ {'title' => 'static1'},
184
+ {'title' => 'static2'},
185
+ {'title' => 'remove1'},
186
+ {'title' => 'remove2'},
187
+ ],
188
+ [
189
+ {'title' => 'static1'},
190
+ {'title' => 'static2'},
191
+ {'title' => 'add1'},
192
+ {'title' => 'add2'},
193
+ ],
194
+ ]
195
+ end
196
+ let(:expected) do
197
+ [
198
+ {'title' => 'add1'},
199
+ {'title' => 'add2'},
200
+ ]
183
201
  end
184
202
  end
185
203
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pavlov_rss
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Minwoo Lee
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-14 00:00:00.000000000 Z
12
+ date: 2014-03-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri