earl 1.0.0 → 2.0.0
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 +7 -0
- data/.github/workflows/ruby-tests.yml +32 -0
- data/.gitignore +20 -4
- data/.rubocop.yml +35 -0
- data/.rubocop_todo.yml +22 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +15 -3
- data/Guardfile +9 -4
- data/LICENSE +3 -1
- data/{README.rdoc → README.md} +44 -46
- data/Rakefile +7 -32
- data/earl.gemspec +19 -20
- data/lib/earl/earl.rb +63 -49
- data/lib/earl/scraper.rb +16 -17
- data/lib/earl/version.rb +3 -1
- data/lib/earl.rb +6 -0
- data/spec/fixtures/cassettes/feed/is_atom_feed.yml +2298 -0
- data/spec/fixtures/cassettes/feed/is_rss_feed.yml +48 -0
- data/spec/fixtures/cassettes/feed/no_feed.yml +69 -0
- data/spec/fixtures/cassettes/feed/with_atom_and_rss_feed.yml +1471 -0
- data/spec/fixtures/cassettes/feed/with_rss_feed.yml +47 -0
- data/spec/fixtures/cassettes/oembed/no_oembed.yml +101 -0
- data/spec/fixtures/cassettes/oembed/youtube_oembed.yml +129 -0
- data/spec/integration/feed_spec.rb +54 -54
- data/spec/integration/oembed_spec.rb +23 -27
- data/spec/spec_helper.rb +4 -2
- data/spec/support/fixtures.rb +8 -3
- data/spec/support/vcr.rb +9 -0
- data/spec/unit/earl/earl_spec.rb +5 -6
- data/spec/unit/earl/feed_spec.rb +29 -26
- data/spec/unit/earl/oembed_spec.rb +24 -23
- data/spec/unit/earl/scraper_spec.rb +19 -18
- data/spec/unit/earl_spec.rb +39 -30
- metadata +48 -97
- data/.document +0 -5
- data/.rspec +0 -1
- data/.travis.yml +0 -11
- data/Gemfile.lock +0 -60
- data/script/console +0 -10
@@ -1,78 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
|
-
# These tests hit real network endpoints - not included in the default test runs. Run with:
|
4
|
-
# rake spec:integration
|
5
|
-
# or
|
6
|
-
# rake spec:all
|
7
|
-
#
|
8
5
|
describe Earl do
|
9
|
-
|
6
|
+
subject(:instance) { Earl[url] }
|
10
7
|
|
11
|
-
|
8
|
+
vcr_base = 'feed'
|
12
9
|
|
13
|
-
context
|
14
|
-
let(:url) { '
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
context 'when page has no feeds associated', vcr: { cassette_name: "#{vcr_base}/no_feed" } do
|
11
|
+
let(:url) { 'https://www.google.com/' }
|
12
|
+
it { expect(subject.feed?).to be false }
|
13
|
+
it { expect(subject.rss_feed).to be_nil }
|
14
|
+
it { expect(subject.feed).to be_nil }
|
18
15
|
end
|
19
16
|
|
20
|
-
context
|
21
|
-
let(:url) { '
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
context 'when page has rss feed associated', vcr: { cassette_name: "#{vcr_base}/with_rss_feed" } do
|
18
|
+
let(:url) { 'https://rubyweekly.com/' }
|
19
|
+
it { expect(subject.feed?).to be true }
|
20
|
+
it { expect(subject.rss_feed).to eql('/rss/') }
|
21
|
+
it { expect(subject.feed).to eql('/rss/') }
|
25
22
|
end
|
26
23
|
|
27
|
-
# context "when page has atom feed associated" do
|
28
|
-
# let(:url) { 'http:// still looking for a page that just has atom' }
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
# end
|
24
|
+
# # context "when page has atom feed associated" do
|
25
|
+
# # let(:url) { 'http:// still looking for a page that just has atom' }
|
26
|
+
# # { expect(subject.feed?).to be true }
|
27
|
+
# # { expect(subject.atom_feed).to eql('http://www.readwriteweb.com/atom.xml') }
|
28
|
+
# # { expect(subject.feed).to eql('http://www.readwriteweb.com/atom.xml') }
|
29
|
+
# # end
|
33
30
|
|
34
|
-
context
|
35
|
-
let(:url) { '
|
36
|
-
let(:expected_rss_feed) { '
|
37
|
-
let(:expected_atom_feed) { '
|
31
|
+
context 'when page has rss and atom feed associated', vcr: { cassette_name: "#{vcr_base}/with_atom_and_rss_feed" } do
|
32
|
+
let(:url) { 'https://0xfe.blogspot.com/' }
|
33
|
+
let(:expected_rss_feed) { 'https://0xfe.blogspot.com/feeds/posts/default?alt=rss' }
|
34
|
+
let(:expected_atom_feed) { 'https://0xfe.blogspot.com/feeds/posts/default' }
|
38
35
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
describe
|
43
|
-
context
|
36
|
+
it { expect(subject.feed?).to be true }
|
37
|
+
it { expect(subject.rss_feed).to eql(expected_rss_feed) }
|
38
|
+
it { expect(subject.atom_feed).to eql(expected_atom_feed) }
|
39
|
+
describe '#feed' do
|
40
|
+
context 'default (rss)' do
|
44
41
|
subject { instance.feed }
|
45
|
-
it {
|
42
|
+
it { expect(subject).to eql(expected_rss_feed) }
|
46
43
|
end
|
47
|
-
context
|
44
|
+
context 'rss prefered' do
|
48
45
|
subject { instance.feed(:rss) }
|
49
|
-
it {
|
46
|
+
it { expect(subject).to eql(expected_rss_feed) }
|
50
47
|
end
|
51
|
-
context
|
48
|
+
context 'atom prefered' do
|
52
49
|
subject { instance.feed(:atom) }
|
53
|
-
it {
|
50
|
+
it { expect(subject).to eql(expected_atom_feed) }
|
54
51
|
end
|
55
52
|
end
|
56
53
|
end
|
57
54
|
|
58
|
-
context
|
59
|
-
let(:url) { '
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
55
|
+
context 'when page IS an rss feed', vcr: { cassette_name: "#{vcr_base}/is_rss_feed" } do
|
56
|
+
let(:url) { 'https://cprss.s3.amazonaws.com/rubyweekly.com.xml' }
|
57
|
+
it { expect(subject.url).to eql(url) }
|
58
|
+
it { expect(subject.base_url).to eql(url) }
|
59
|
+
it { expect(subject.content_type).to eql('application/xml') }
|
60
|
+
# TODO: fix rss feed detection
|
61
|
+
# it { expect(subject.feed?).to be true }
|
62
|
+
# it { expect(subject.rss_feed).to eql(url) }
|
63
|
+
# it { expect(subject.feed).to eql(url) }
|
64
|
+
it { expect(subject.feed?).to be false }
|
65
|
+
it { expect(subject.rss_feed).to be_nil }
|
66
|
+
it { expect(subject.feed).to be_nil }
|
66
67
|
end
|
67
68
|
|
68
|
-
context
|
69
|
-
let(:url) { '
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
69
|
+
context 'when page IS an atom feed', vcr: { cassette_name: "#{vcr_base}/is_atom_feed" } do
|
70
|
+
let(:url) { 'https://0xfe.blogspot.com/feeds/posts/default' }
|
71
|
+
it { expect(subject.url).to eql(url) }
|
72
|
+
it { expect(subject.base_url).to eql(url) }
|
73
|
+
it { expect(subject.content_type).to eql('application/atom+xml') }
|
74
|
+
it { expect(subject.feed?).to be true }
|
75
|
+
it { expect(subject.atom_feed).to eql(url) }
|
76
|
+
it { expect(subject.feed).to eql(url) }
|
76
77
|
end
|
77
|
-
|
78
78
|
end
|
@@ -1,40 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
|
-
# These tests hit real network endpoints - not included in the default test runs. Run with:
|
4
|
-
# rake spec:integration
|
5
|
-
# or
|
6
|
-
# rake spec:all
|
7
|
-
#
|
8
5
|
describe Earl do
|
9
|
-
|
6
|
+
subject(:instance) { Earl[url] }
|
10
7
|
|
11
|
-
|
8
|
+
vcr_base = 'oembed'
|
12
9
|
|
13
|
-
context
|
14
|
-
let(:url) { '
|
15
|
-
|
16
|
-
|
17
|
-
describe
|
10
|
+
context 'when page does not support oembed', vcr: { cassette_name: "#{vcr_base}/no_oembed" } do
|
11
|
+
let(:url) { 'https://github.com/evendis/earl' }
|
12
|
+
it { expect(subject.oembed).to be_nil }
|
13
|
+
it { expect(subject.oembed_html).to be_nil }
|
14
|
+
describe '#metadata' do
|
18
15
|
subject { instance.metadata }
|
19
|
-
it { subject[:base_url].
|
20
|
-
it { subject[:content_type].
|
21
|
-
it { subject[:html].
|
16
|
+
it { expect(subject[:base_url]).to match(%r{github\.com/evendis/earl}) }
|
17
|
+
it { expect(subject[:content_type]).to eql('text/html') }
|
18
|
+
it { expect(subject[:html]).to be_nil }
|
22
19
|
end
|
23
20
|
end
|
24
21
|
|
25
|
-
context
|
26
|
-
let(:url) { '
|
27
|
-
let(:expected_oembed_html) {
|
22
|
+
context 'when youtube oembed', vcr: { cassette_name: "#{vcr_base}/youtube_oembed" } do
|
23
|
+
let(:url) { 'https://www.youtube.com/watch?v=hNSkCqMUMQA' }
|
24
|
+
let(:expected_oembed_html) { 'https://www.youtube.com/embed/hNSkCqMUMQA?feature=oembed' }
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
describe
|
26
|
+
it { expect(subject.oembed).to be_a(Hash) }
|
27
|
+
it { expect(subject.oembed_html).to include(expected_oembed_html) }
|
28
|
+
describe '#metadata' do
|
32
29
|
subject { instance.metadata }
|
33
|
-
it { subject[:base_url].
|
34
|
-
it { subject[:content_type].
|
35
|
-
it { subject[:title].
|
36
|
-
it { subject[:html].
|
30
|
+
it { expect(subject[:base_url]).to eql(url) }
|
31
|
+
it { expect(subject[:content_type]).to eql('text/html') }
|
32
|
+
it { expect(subject[:title]).to eql('[JA][Keynote] Ruby Taught Me About Encoding Under the Hood / Mari Imaizumi @ima1zumi') }
|
33
|
+
it { expect(subject[:html]).to include(expected_oembed_html) }
|
37
34
|
end
|
38
35
|
end
|
39
|
-
|
40
|
-
end
|
36
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'earl'
|
2
4
|
|
3
5
|
# Requires supporting files with custom matchers and macros, etc,
|
4
6
|
# in ./support/ and its subdirectories.
|
5
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
6
8
|
|
7
9
|
RSpec.configure do |config|
|
8
10
|
# == Mock Framework
|
@@ -21,4 +23,4 @@ RSpec.configure do |config|
|
|
21
23
|
# examples within a transaction, remove the following line or assign false
|
22
24
|
# instead of true.
|
23
25
|
# config.use_transactional_fixtures = true
|
24
|
-
end
|
26
|
+
end
|
data/spec/support/fixtures.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FixtureHelper
|
2
|
-
def
|
3
|
-
# File.new( File.dirname(__FILE__) + "/../fixtures/#{name}.html" ).read
|
4
|
+
def fixture_path(name)
|
4
5
|
File.dirname(__FILE__) + "/../fixtures/#{name}.html"
|
5
6
|
end
|
7
|
+
|
8
|
+
def fixture(name)
|
9
|
+
File.new(fixture_path(name)).read
|
10
|
+
end
|
6
11
|
end
|
7
12
|
|
8
13
|
RSpec.configure do |conf|
|
9
14
|
conf.include FixtureHelper
|
10
|
-
end
|
15
|
+
end
|
data/spec/support/vcr.rb
ADDED
data/spec/unit/earl/earl_spec.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Earl do
|
4
|
-
|
5
|
-
|
6
|
-
describe '##new' do
|
6
|
+
describe '.new' do
|
7
7
|
subject { Earl.new('http://test.host/') }
|
8
|
-
|
8
|
+
it { expect(subject.to_s).to eql('http://test.host/') }
|
9
9
|
end
|
10
10
|
|
11
11
|
describe '[]=' do
|
12
12
|
subject { Earl['http://test.host/'] }
|
13
|
-
|
13
|
+
it { expect(subject.to_s).to eql('http://test.host/') }
|
14
14
|
end
|
15
|
-
|
16
15
|
end
|
data/spec/unit/earl/feed_spec.rb
CHANGED
@@ -1,59 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Earl do
|
4
6
|
let(:instance) { Earl[url] }
|
5
7
|
let(:url) { 'http:://example.com' }
|
6
8
|
|
7
|
-
before
|
9
|
+
before do
|
10
|
+
allow_any_instance_of(Earl).to receive(:uri_response).and_return(source)
|
11
|
+
end
|
8
12
|
subject { instance }
|
9
13
|
|
10
|
-
context
|
14
|
+
context 'when page has no feeds associated' do
|
11
15
|
let(:source) { fixture(:page_without_feeds) }
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
it { expect(subject.feed?).to be false }
|
17
|
+
it { expect(subject.rss_feed).to be_nil }
|
18
|
+
it { expect(subject.feed).to be_nil }
|
15
19
|
end
|
16
20
|
|
17
|
-
context
|
21
|
+
context 'when page has rss feed associated' do
|
18
22
|
let(:source) { fixture(:page_with_rss_feed) }
|
19
|
-
|
20
|
-
|
21
|
-
|
23
|
+
it { expect(subject.feed?).to be true }
|
24
|
+
it { expect(subject.rss_feed).to eql('http://www.readwriteweb.com/rss.xml') }
|
25
|
+
it { expect(subject.feed).to eql('http://www.readwriteweb.com/rss.xml') }
|
22
26
|
end
|
23
27
|
|
24
|
-
context
|
28
|
+
context 'when page has atom feed associated' do
|
25
29
|
let(:source) { fixture(:page_with_atom_feed) }
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
it { expect(subject.feed?).to be true }
|
31
|
+
it { expect(subject.atom_feed).to eql('http://www.readwriteweb.com/atom.xml') }
|
32
|
+
it { expect(subject.feed).to eql('http://www.readwriteweb.com/atom.xml') }
|
29
33
|
end
|
30
34
|
|
31
|
-
context
|
35
|
+
context 'when page has rss and atom feed associated' do
|
32
36
|
let(:source) { fixture(:page_with_rss_and_atom_feeds) }
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
describe
|
37
|
-
context
|
37
|
+
it { expect(subject.feed?).to be true }
|
38
|
+
it { expect(subject.rss_feed).to eql('http://www.readwriteweb.com/rss.xml') }
|
39
|
+
it { expect(subject.atom_feed).to eql('http://www.readwriteweb.com/atom.xml') }
|
40
|
+
describe '#feed' do
|
41
|
+
context 'default (rss)' do
|
38
42
|
subject { instance.feed }
|
39
|
-
it {
|
43
|
+
it { expect(subject).to eql('http://www.readwriteweb.com/rss.xml') }
|
40
44
|
end
|
41
|
-
context
|
45
|
+
context 'rss prefered' do
|
42
46
|
subject { instance.feed(:rss) }
|
43
|
-
it {
|
47
|
+
it { expect(subject).to eql('http://www.readwriteweb.com/rss.xml') }
|
44
48
|
end
|
45
|
-
context
|
49
|
+
context 'atom prefered' do
|
46
50
|
subject { instance.feed(:atom) }
|
47
|
-
it {
|
51
|
+
it { expect(subject).to eql('http://www.readwriteweb.com/atom.xml') }
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
52
56
|
# context "when page IS an rss feed" do
|
53
57
|
# let(:source) { fixture(:page_as_rss) }
|
54
|
-
# its(:
|
58
|
+
# its(:feed?) { should be_true }
|
55
59
|
# its(:rss_feed) { should eql(url) }
|
56
60
|
# its(:feed) { should eql(url) }
|
57
61
|
# end
|
58
|
-
|
59
62
|
end
|
@@ -1,49 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
class MockOembedResponse
|
4
|
-
def
|
6
|
+
def fields
|
5
7
|
{ 'html' => '<iframe/>' }
|
6
8
|
end
|
7
9
|
end
|
8
10
|
|
9
11
|
describe Earl do
|
10
|
-
let(:instance) { Earl.new(url,options) }
|
12
|
+
let(:instance) { Earl.new(url, options) }
|
11
13
|
let(:url) { 'http:://example.com' }
|
12
14
|
let(:options) { {} }
|
13
15
|
|
14
|
-
describe
|
16
|
+
describe '#oembed_options' do
|
15
17
|
subject { instance.oembed_options }
|
16
|
-
context
|
17
|
-
let(:expected) { { :
|
18
|
-
it {
|
18
|
+
context 'with default options' do
|
19
|
+
let(:expected) { { maxwidth: '560', maxheight: '315' } }
|
20
|
+
it { expect(subject).to eql(expected) }
|
19
21
|
end
|
20
|
-
context
|
21
|
-
let(:options) { { :
|
22
|
-
let(:expected) { { :
|
23
|
-
it {
|
22
|
+
context 'with custom options' do
|
23
|
+
let(:options) { { oembed: { maxwidth: '260' } } }
|
24
|
+
let(:expected) { { maxwidth: '260', maxheight: '315' } }
|
25
|
+
it { expect(subject).to eql(expected) }
|
24
26
|
end
|
25
|
-
context
|
26
|
-
let(:expected) { { :
|
27
|
+
context 'with custom options passed to oembed' do
|
28
|
+
let(:expected) { { maxwidth: '360', maxheight: '315' } }
|
27
29
|
before do
|
28
|
-
|
29
|
-
instance.oembed({ :
|
30
|
+
allow(instance).to receive(:fetch_oembed).and_return(nil)
|
31
|
+
instance.oembed({ maxwidth: '360' })
|
30
32
|
end
|
31
|
-
it {
|
33
|
+
it { expect(subject).to eql(expected) }
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
describe
|
37
|
+
describe '#oembed' do
|
36
38
|
let(:dummy_response) { MockOembedResponse.new }
|
37
39
|
before do
|
38
|
-
instance.
|
39
|
-
|
40
|
+
expect(instance).to receive(:base_url).and_return('')
|
41
|
+
expect(instance).to receive(:fetch_oembed).and_return(dummy_response)
|
40
42
|
end
|
41
43
|
subject { instance.oembed }
|
42
|
-
it {
|
43
|
-
describe
|
44
|
+
it { expect(subject).to eql({ html: '<iframe/>' }) }
|
45
|
+
describe '#oembed_html' do
|
44
46
|
subject { instance.oembed_html }
|
45
|
-
it {
|
47
|
+
it { expect(subject).to eql('<iframe/>') }
|
46
48
|
end
|
47
49
|
end
|
48
|
-
|
49
|
-
end
|
50
|
+
end
|
@@ -1,31 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Earl::Scraper do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
before do
|
7
|
+
allow_any_instance_of(Earl).to receive(:uri_response).and_return(
|
8
|
+
<<-DOC
|
9
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
10
|
+
<html></html>
|
11
|
+
DOC
|
10
12
|
)
|
11
13
|
end
|
12
14
|
|
13
15
|
describe 'When validating URLs' do
|
14
|
-
before
|
16
|
+
before do
|
15
17
|
class Earl::TestScraper < Earl::Scraper
|
16
|
-
match
|
17
|
-
define_attribute(:title) {|
|
18
|
+
match %r{^http://www\.test\.com/$}
|
19
|
+
define_attribute(:title) { |_response| :test_title }
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
it '
|
22
|
-
Earl['http://www.test.com/'].title.
|
23
|
+
it 'returns the result if the URL matches the scraper regexp' do
|
24
|
+
expect(Earl['http://www.test.com/'].title).to eql :test_title
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
28
|
describe 'When retrieving the response' do
|
27
|
-
it '
|
28
|
-
Earl['test'].response.css('html').size.
|
29
|
+
it 'returns a Nokogiri document' do
|
30
|
+
expect(Earl['test'].response.css('html').size).to eql 1
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -38,11 +40,10 @@ describe Earl::Scraper do
|
|
38
40
|
|
39
41
|
it 'inherits all attributes from its superclass' do
|
40
42
|
scraper = SubScraper.new('foo.bar')
|
41
|
-
scraper.attributes.
|
42
|
-
scraper.attributes.
|
43
|
-
scraper.attributes.
|
44
|
-
scraper.attributes.
|
43
|
+
expect(scraper.attributes).to include(:title)
|
44
|
+
expect(scraper.attributes).to include(:description)
|
45
|
+
expect(scraper.attributes).to include(:image)
|
46
|
+
expect(scraper.attributes).to include(:some_attribute)
|
45
47
|
end
|
46
48
|
end
|
47
|
-
|
48
49
|
end
|
data/spec/unit/earl_spec.rb
CHANGED
@@ -1,65 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Earl do
|
4
|
-
|
5
|
-
|
6
|
+
before do
|
7
|
+
allow_any_instance_of(Earl).to receive(:uri_response).and_return(source)
|
8
|
+
end
|
6
9
|
let(:url) { 'http://mock.net' }
|
7
|
-
|
8
|
-
subject { instance }
|
10
|
+
subject(:instance) { Earl[url] }
|
9
11
|
|
10
12
|
describe '#title' do
|
11
|
-
|
13
|
+
subject { instance.title }
|
14
|
+
context 'example with title tag' do
|
12
15
|
let(:source) { fixture(:bicycles) }
|
13
|
-
|
16
|
+
it { expect(subject).to eql('bicycles (bicycles) on Twitter') }
|
14
17
|
end
|
15
|
-
context
|
18
|
+
context 'youtube example with title tag' do
|
16
19
|
let(:source) { fixture(:youtube) }
|
17
|
-
|
20
|
+
it { expect(subject).to eql('YouTube - Symptoms of Swine Flu') }
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
21
24
|
describe '#description' do
|
22
|
-
|
25
|
+
subject { instance.description }
|
26
|
+
context 'example with description tag' do
|
23
27
|
let(:source) { fixture(:bicycles) }
|
24
|
-
|
28
|
+
it { expect(subject).to eql('I write business plans for a living and fiction to stay sane. I also try my hand at all sorts of creative side projects: painting, game dev, whiskey drinking..') }
|
25
29
|
end
|
26
|
-
context
|
30
|
+
context 'example without description tag' do
|
27
31
|
let(:source) { fixture(:bicycles_without_description) }
|
28
|
-
|
32
|
+
it { expect(subject).to be_nil }
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
32
36
|
describe '#image' do
|
33
|
-
|
37
|
+
subject { instance.image }
|
38
|
+
context 'example with image tag' do
|
34
39
|
let(:source) { fixture(:bicycles) }
|
35
|
-
|
40
|
+
it { expect(subject).to eql('http://assets0.twitter.com/images/loader.gif') }
|
36
41
|
end
|
37
|
-
context
|
42
|
+
context 'example without image tag' do
|
38
43
|
let(:source) { fixture(:bicycles_without_images) }
|
39
|
-
|
44
|
+
it { expect(subject).to be_nil }
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
43
48
|
describe '#attributes' do
|
49
|
+
subject { instance.attributes }
|
44
50
|
let(:source) { fixture(:bicycles) }
|
45
|
-
|
46
|
-
|
47
|
-
|
51
|
+
it 'is an array of expected elements' do
|
52
|
+
expect(subject).to be_an(Array)
|
53
|
+
%i[description title image].each do |attribute|
|
54
|
+
expect(subject).to include(attribute)
|
55
|
+
end
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
51
59
|
describe '#metadata' do
|
60
|
+
subject { instance.metadata }
|
52
61
|
let(:source) { fixture(:bicycles) }
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
+
it { expect(subject).to be_a(Hash) }
|
63
|
+
it 'has the expected elements' do
|
64
|
+
expect(subject).to eql({
|
65
|
+
title: 'bicycles (bicycles) on Twitter',
|
66
|
+
description: 'I write business plans for a living and fiction to stay sane. I also try my hand at all sorts of creative side projects: painting, game dev, whiskey drinking..',
|
67
|
+
image: 'http://assets0.twitter.com/images/loader.gif',
|
68
|
+
rss_feed: '/statuses/user_timeline/user_id.rss',
|
69
|
+
base_url: 'http://mock.net',
|
70
|
+
feed: '/statuses/user_timeline/user_id.rss'
|
71
|
+
})
|
72
|
+
end
|
62
73
|
end
|
63
|
-
|
64
74
|
end
|
65
|
-
|