pavlov_rss 0.0.3 → 0.0.4

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