bateman 0.0.1
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.
- data/.gitignore +18 -0
- data/.travis.yml +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bateman.gemspec +25 -0
- data/lib/bateman.rb +20 -0
- data/lib/bateman/card_attribute.rb +14 -0
- data/lib/bateman/creator_attribute.rb +10 -0
- data/lib/bateman/description_attribute.rb +10 -0
- data/lib/bateman/image_attribute.rb +10 -0
- data/lib/bateman/meta_attribute.rb +70 -0
- data/lib/bateman/null_nokogiri_node.rb +17 -0
- data/lib/bateman/site_attribute.rb +10 -0
- data/lib/bateman/title_attribute.rb +14 -0
- data/lib/bateman/twitter_card.rb +36 -0
- data/lib/bateman/url_attribute.rb +23 -0
- data/lib/bateman/version.rb +3 -0
- data/spec/bateman/card_attribute_spec.rb +25 -0
- data/spec/bateman/creator_attribute_spec.rb +23 -0
- data/spec/bateman/description_attribute_spec.rb +35 -0
- data/spec/bateman/image_attribute_spec.rb +35 -0
- data/spec/bateman/site_attribute_spec.rb +25 -0
- data/spec/bateman/title_attribute_spec.rb +45 -0
- data/spec/bateman/twitter_card_spec.rb +54 -0
- data/spec/bateman/url_attribute_spec.rb +58 -0
- data/spec/fixtures/valid_twitter_card.html +17 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/prepare_html.rb +3 -0
- metadata +168 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- "1.8.7"
|
4
|
+
- "1.9.2"
|
5
|
+
- "1.9.3"
|
6
|
+
- jruby-18mode # JRuby in 1.8 mode
|
7
|
+
- jruby-19mode # JRuby in 1.9 mode
|
8
|
+
- rbx-18mode
|
9
|
+
- rbx-19mode
|
10
|
+
# uncomment this line if your project needs to run something other than `rake`:
|
11
|
+
script: bundle exec rspec spec
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Geoff Harcourt
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Bateman
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'bateman'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install bateman
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bateman.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bateman/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "bateman"
|
8
|
+
gem.version = Bateman::VERSION
|
9
|
+
gem.authors = ["Geoff Harcourt"]
|
10
|
+
gem.email = ["geoff.harcourt@gmail.com"]
|
11
|
+
gem.description = %q{A gem for retrieving a webpage's Twitter Card}
|
12
|
+
gem.summary = %q{Bateman retrieves a webpage's Twitter Card, returning the information as stored in the page's header meta tags.}
|
13
|
+
gem.homepage = "http://github.com/geoffharcourt/bateman"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.test_files = gem.files.grep(%r{^(spec)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
gem.add_runtime_dependency 'httparty'
|
20
|
+
gem.add_runtime_dependency 'nokogiri'
|
21
|
+
|
22
|
+
gem.add_development_dependency 'fakeweb'
|
23
|
+
gem.add_development_dependency 'rspec'
|
24
|
+
gem.add_development_dependency 'simplecov'
|
25
|
+
end
|
data/lib/bateman.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "bateman/version"
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module Bateman
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'bateman/twitter_card'
|
11
|
+
require 'bateman/meta_attribute'
|
12
|
+
require 'bateman/null_nokogiri_node'
|
13
|
+
|
14
|
+
require 'bateman/card_attribute'
|
15
|
+
require 'bateman/creator_attribute'
|
16
|
+
require 'bateman/description_attribute'
|
17
|
+
require 'bateman/image_attribute'
|
18
|
+
require 'bateman/site_attribute'
|
19
|
+
require 'bateman/title_attribute'
|
20
|
+
require 'bateman/url_attribute'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Bateman
|
2
|
+
class MetaAttribute
|
3
|
+
def initialize(html)
|
4
|
+
@html = html
|
5
|
+
@attribute = extract_attribute
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
@attribute.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def extract_attribute
|
15
|
+
relevant_meta_tag_value || html_attribute
|
16
|
+
end
|
17
|
+
|
18
|
+
def relevant_meta_tag_value
|
19
|
+
value_containing_meta_tag_attributes.map{|_k, v| v.value}.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def value_containing_meta_tag_attributes
|
23
|
+
meta_tag_attributes.select{|key, _v| value_attributes.include?(key)}
|
24
|
+
end
|
25
|
+
|
26
|
+
def meta_tag_attributes
|
27
|
+
meta_tag.attributes
|
28
|
+
end
|
29
|
+
|
30
|
+
def meta_tag
|
31
|
+
@html.search(tag_selector).first || NullTwitterMetaTag.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def tag_selector
|
35
|
+
possible_selectors.join(', ')
|
36
|
+
end
|
37
|
+
|
38
|
+
def possible_selectors
|
39
|
+
protocol_attributes.inject([]) do |memo, protocol|
|
40
|
+
name_attributes.each do |name_attribute|
|
41
|
+
memo << %Q{meta[#{name_attribute}="#{protocol}:#{attribute_name}"]}
|
42
|
+
end
|
43
|
+
|
44
|
+
memo
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def name_attributes
|
49
|
+
%w(name property)
|
50
|
+
end
|
51
|
+
|
52
|
+
def protocol_attributes
|
53
|
+
%w(twitter og)
|
54
|
+
end
|
55
|
+
|
56
|
+
def value_attributes
|
57
|
+
%w(content value)
|
58
|
+
end
|
59
|
+
|
60
|
+
def html_attribute
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class NullTwitterMetaTag
|
66
|
+
def attributes
|
67
|
+
[]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Bateman
|
2
|
+
class TwitterCard
|
3
|
+
attr_reader :card, :creator, :description, :image, :site, :title, :url
|
4
|
+
|
5
|
+
def initialize(url)
|
6
|
+
@uri = URI.parse(url)
|
7
|
+
|
8
|
+
fetch
|
9
|
+
process_html_document
|
10
|
+
set_attributes_from_response
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_attributes_from_response
|
14
|
+
@card = Bateman::CardAttribute.new(@html_document).to_s
|
15
|
+
@creator = Bateman::CreatorAttribute.new(@html_document).to_s
|
16
|
+
@description = Bateman::DescriptionAttribute.new(@html_document).to_s
|
17
|
+
@image = Bateman::ImageAttribute.new(@html_document).to_s
|
18
|
+
@site = Bateman::SiteAttribute.new(@html_document).to_s
|
19
|
+
@title = Bateman::TitleAttribute.new(@html_document).to_s
|
20
|
+
@url = Bateman::UrlAttribute.new(@html_document, @uri).to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch
|
24
|
+
@response = HTTParty.get(@uri.to_s)
|
25
|
+
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def process_html_document
|
30
|
+
@html_document = Nokogiri::HTML(@response.body)
|
31
|
+
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Bateman
|
2
|
+
class UrlAttribute < SiteAttribute
|
3
|
+
def initialize(html, uri = nil)
|
4
|
+
@uri = uri.to_s
|
5
|
+
|
6
|
+
super(html)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def extract_attribute
|
12
|
+
super || @uri
|
13
|
+
end
|
14
|
+
|
15
|
+
def attribute_name
|
16
|
+
'url'
|
17
|
+
end
|
18
|
+
|
19
|
+
def html_attribute
|
20
|
+
(@html.at_css(%q{link[rel="canonical"]}) || NullNokogiriNode.new).attributes['href'].value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::CardAttribute do
|
4
|
+
describe '#to_s' do
|
5
|
+
context 'an HTML document with a twitter:card tag' do
|
6
|
+
it 'returns the twitter:card value' do
|
7
|
+
html = prepare_html(%q{<meta name="twitter:card" content="summary"})
|
8
|
+
|
9
|
+
attribute_object = Bateman::CardAttribute.new(html)
|
10
|
+
|
11
|
+
attribute_object.to_s.should eq('summary')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'an HTML document without a twitter:card tag' do
|
16
|
+
it 'returns "summary"' do
|
17
|
+
html = prepare_html(%q{<head/>})
|
18
|
+
|
19
|
+
attribute_object = Bateman::CardAttribute.new(html)
|
20
|
+
|
21
|
+
attribute_object.to_s.should eq('summary')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::CreatorAttribute do
|
4
|
+
context 'an HTML document with a twitter:creator tag' do
|
5
|
+
it 'returnsthe twitter:creator value' do
|
6
|
+
html = prepare_html(%q{<meta name="twitter:creator" content="@example"})
|
7
|
+
|
8
|
+
attribute_object = Bateman::CreatorAttribute.new(html)
|
9
|
+
|
10
|
+
attribute_object.to_s.should eq('@example')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'an HTML document without a twitter:creator tag' do
|
15
|
+
it 'returns an empty string' do
|
16
|
+
html = prepare_html(%q{<head/>})
|
17
|
+
|
18
|
+
attribute_object = Bateman::CreatorAttribute.new(html)
|
19
|
+
|
20
|
+
attribute_object.to_s.should be_empty
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::DescriptionAttribute do
|
4
|
+
describe '#to_s' do
|
5
|
+
context 'an HTML document with a twitter:description tag' do
|
6
|
+
it 'returns the twitter:description value' do
|
7
|
+
html = prepare_html(%q{<meta name="twitter:description" value="Huey Lewis and the News"})
|
8
|
+
|
9
|
+
attribute_object = Bateman::DescriptionAttribute.new(html)
|
10
|
+
|
11
|
+
attribute_object.to_s.should eq('Huey Lewis and the News')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'an HTML document with an og:description tag and no twitter:description tag' do
|
16
|
+
it 'returns the og:description value' do
|
17
|
+
html = prepare_html(%q{<meta name="og:description" content="Genesis"})
|
18
|
+
|
19
|
+
attribute_object = Bateman::DescriptionAttribute.new(html)
|
20
|
+
|
21
|
+
attribute_object.to_s.should eq('Genesis')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'an HTML document without a twitter/og tag with description information' do
|
26
|
+
it 'returns an empty string' do
|
27
|
+
html = prepare_html(%q{<head/>})
|
28
|
+
|
29
|
+
attribute_object = Bateman::DescriptionAttribute.new(html)
|
30
|
+
|
31
|
+
attribute_object.to_s.should be_empty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::ImageAttribute do
|
4
|
+
describe '#to_s' do
|
5
|
+
context 'an HTML document with a twitter:image tag' do
|
6
|
+
it 'returns the twitter:image value' do
|
7
|
+
html = prepare_html(%q{<meta name="twitter:image" value="http://example.com/img/1.jpg"})
|
8
|
+
|
9
|
+
attribute_object = Bateman::ImageAttribute.new(html)
|
10
|
+
|
11
|
+
attribute_object.to_s.should eq('http://example.com/img/1.jpg')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'an HTML document with an og:image tag and no twitter:image tag' do
|
16
|
+
it 'returns the og:image value' do
|
17
|
+
html = prepare_html(%q{<meta name="og:image" content="http://example.com/img/2.jpg"})
|
18
|
+
|
19
|
+
attribute_object = Bateman::ImageAttribute.new(html)
|
20
|
+
|
21
|
+
attribute_object.to_s.should eq('http://example.com/img/2.jpg')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'an HTML document without a twitter/og tag with image information' do
|
26
|
+
it 'returns an empty string' do
|
27
|
+
html = prepare_html(%q{<head/>})
|
28
|
+
|
29
|
+
attribute_object = Bateman::ImageAttribute.new(html)
|
30
|
+
|
31
|
+
attribute_object.to_s.should be_empty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::SiteAttribute do
|
4
|
+
describe '#to_s' do
|
5
|
+
context 'an HTML document with a twitter:site tag' do
|
6
|
+
it 'returns the twitter:site value' do
|
7
|
+
html = prepare_html(%q{<meta name="twitter:site" content="@example_site"})
|
8
|
+
|
9
|
+
attribute_object = Bateman::SiteAttribute.new(html)
|
10
|
+
|
11
|
+
attribute_object.to_s.should eq('@example_site')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'an HTML document without a twitter:site tag' do
|
16
|
+
it 'returns an empty string' do
|
17
|
+
html = prepare_html(%q{<head/>})
|
18
|
+
|
19
|
+
attribute_object = Bateman::SiteAttribute.new(html)
|
20
|
+
|
21
|
+
attribute_object.to_s.should be_empty
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::TitleAttribute do
|
4
|
+
describe '#to_s' do
|
5
|
+
context 'an HTML document with a twitter:title tag' do
|
6
|
+
it 'returns the twitter:title value' do
|
7
|
+
html = prepare_html(%q{<meta name="twitter:title" value="Huey Lewis and the News"})
|
8
|
+
|
9
|
+
attribute_object = Bateman::TitleAttribute.new(html)
|
10
|
+
|
11
|
+
attribute_object.to_s.should eq('Huey Lewis and the News')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'an HTML document with an og:title tag and no twitter:title tag' do
|
16
|
+
it 'returns the og:title value' do
|
17
|
+
html = prepare_html(%q{<meta name="og:title" content="Genesis"})
|
18
|
+
|
19
|
+
attribute_object = Bateman::TitleAttribute.new(html)
|
20
|
+
|
21
|
+
attribute_object.to_s.should eq('Genesis')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'an HTML document without a twitter/og tag with title information' do
|
26
|
+
it 'returns the HTML <title> tag text' do
|
27
|
+
html = prepare_html(%q{<title>Phil Collins</title>})
|
28
|
+
|
29
|
+
attribute_object = Bateman::TitleAttribute.new(html)
|
30
|
+
|
31
|
+
attribute_object.to_s.should eq('Phil Collins')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'an HTML document with no twitter/og title tag or <title> tag' do
|
36
|
+
it 'returns an empty string' do
|
37
|
+
html = prepare_html('')
|
38
|
+
|
39
|
+
attribute_object = Bateman::TitleAttribute.new(html)
|
40
|
+
|
41
|
+
attribute_object.to_s.should eq('')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::TwitterCard do
|
4
|
+
def request_payload(filename)
|
5
|
+
IO.readlines("./spec/fixtures/#{filename}.html").join
|
6
|
+
end
|
7
|
+
|
8
|
+
context "fully filled out Twitter Card" do
|
9
|
+
before(:each) do
|
10
|
+
@url = 'http://example.com/article_1'
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#initialize" do
|
14
|
+
before(:each) do
|
15
|
+
FakeWeb.register_uri(
|
16
|
+
:get,
|
17
|
+
"http://example.com/article_1",
|
18
|
+
body: request_payload('valid_twitter_card')
|
19
|
+
)
|
20
|
+
|
21
|
+
@twitter_card = Bateman::TwitterCard.new(@url)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "sets the title of the TwitterCard", :focus do
|
25
|
+
@twitter_card.title.should eq('Propellerheads Are Back')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sets the url of the TwitterCard" do
|
29
|
+
@twitter_card.url.should eq('http://www.example.com/123456789')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "sets the card type of the TwitterCard" do
|
33
|
+
@twitter_card.card.should eq('summary')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "sets the site handle of the TwitterCard" do
|
37
|
+
@twitter_card.site.should eq('@example_site')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sets the creator handle of the TwitterCard" do
|
41
|
+
@twitter_card.creator.should eq('@example_author')
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
it "sets the description of the TwitterCard" do
|
46
|
+
@twitter_card.description.should eq('It\'s as if they never went away!')
|
47
|
+
end
|
48
|
+
|
49
|
+
it "sets the image url of the TwitterCard" do
|
50
|
+
@twitter_card.image.should eq('http://example.com/images/velvet_pants.jpg')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bateman::UrlAttribute do
|
4
|
+
describe '#to_s' do
|
5
|
+
context 'an HTML document with a twitter:url tag' do
|
6
|
+
it 'returns the twitter:url value' do
|
7
|
+
html = prepare_html(%q{<meta name="twitter:url" value="http://example.com/articles/1"})
|
8
|
+
|
9
|
+
attribute_object = Bateman::UrlAttribute.new(html)
|
10
|
+
|
11
|
+
attribute_object.to_s.should eq('http://example.com/articles/1')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'an HTML document with an og:url tag and no twitter:url tag' do
|
16
|
+
it 'returns to the og:url value' do
|
17
|
+
html = prepare_html(%q{<meta name="og:url" content="http://example.com/articles/2"})
|
18
|
+
|
19
|
+
attribute_object = Bateman::UrlAttribute.new(html)
|
20
|
+
|
21
|
+
attribute_object.to_s.should eq('http://example.com/articles/2')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'an HTML document without a twitter/og url tag and a canonical link' do
|
26
|
+
it 'returns the canonical link href' do
|
27
|
+
html = prepare_html(%q{<link rel="canonical" href="http://example.com/articles/3" />})
|
28
|
+
|
29
|
+
attribute_object = Bateman::UrlAttribute.new(html)
|
30
|
+
|
31
|
+
attribute_object.to_s.should eq('http://example.com/articles/3')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'an HTML document with no twitter/og url tag or canonical link tag' do
|
36
|
+
context 'when initialized with a uri argument' do
|
37
|
+
it 'returns the uri as a string' do
|
38
|
+
html = prepare_html('html')
|
39
|
+
|
40
|
+
attribute_object = Bateman::UrlAttribute.new(html, 'http:://example.com/articles/4')
|
41
|
+
|
42
|
+
attribute_object.to_s.should eq('http:://example.com/articles/4')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
context 'without a supplied uri argument' do
|
48
|
+
it 'returns an empty string' do
|
49
|
+
html = prepare_html('<html/>')
|
50
|
+
|
51
|
+
attribute_object = Bateman::UrlAttribute.new(html)
|
52
|
+
|
53
|
+
attribute_object.to_s.should eq('')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta name="twitter:card" value="summary">
|
5
|
+
<meta name="twitter:creator" value="@example_author">
|
6
|
+
<meta name="twitter:site" value="@example_site">
|
7
|
+
<meta name="twitter:url" value="http://www.example.com/123456789">
|
8
|
+
<meta name="twitter:title" value="Propellerheads Are Back">
|
9
|
+
<meta name="twitter:description" value="It's as if they never went away!">
|
10
|
+
<meta name="twitter:image" value="http://example.com/images/velvet_pants.jpg">
|
11
|
+
</head>
|
12
|
+
|
13
|
+
<body>
|
14
|
+
He's got a nice body; he's wearing velvet pants.
|
15
|
+
</body>
|
16
|
+
|
17
|
+
</html>
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bateman
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Geoff Harcourt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: nokogiri
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: fakeweb
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: simplecov
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: A gem for retrieving a webpage's Twitter Card
|
95
|
+
email:
|
96
|
+
- geoff.harcourt@gmail.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .travis.yml
|
103
|
+
- Gemfile
|
104
|
+
- LICENSE.txt
|
105
|
+
- README.md
|
106
|
+
- Rakefile
|
107
|
+
- bateman.gemspec
|
108
|
+
- lib/bateman.rb
|
109
|
+
- lib/bateman/card_attribute.rb
|
110
|
+
- lib/bateman/creator_attribute.rb
|
111
|
+
- lib/bateman/description_attribute.rb
|
112
|
+
- lib/bateman/image_attribute.rb
|
113
|
+
- lib/bateman/meta_attribute.rb
|
114
|
+
- lib/bateman/null_nokogiri_node.rb
|
115
|
+
- lib/bateman/site_attribute.rb
|
116
|
+
- lib/bateman/title_attribute.rb
|
117
|
+
- lib/bateman/twitter_card.rb
|
118
|
+
- lib/bateman/url_attribute.rb
|
119
|
+
- lib/bateman/version.rb
|
120
|
+
- spec/bateman/card_attribute_spec.rb
|
121
|
+
- spec/bateman/creator_attribute_spec.rb
|
122
|
+
- spec/bateman/description_attribute_spec.rb
|
123
|
+
- spec/bateman/image_attribute_spec.rb
|
124
|
+
- spec/bateman/site_attribute_spec.rb
|
125
|
+
- spec/bateman/title_attribute_spec.rb
|
126
|
+
- spec/bateman/twitter_card_spec.rb
|
127
|
+
- spec/bateman/url_attribute_spec.rb
|
128
|
+
- spec/fixtures/valid_twitter_card.html
|
129
|
+
- spec/spec_helper.rb
|
130
|
+
- spec/support/prepare_html.rb
|
131
|
+
homepage: http://github.com/geoffharcourt/bateman
|
132
|
+
licenses: []
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
145
|
+
requirements:
|
146
|
+
- - ! '>='
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0'
|
149
|
+
requirements: []
|
150
|
+
rubyforge_project:
|
151
|
+
rubygems_version: 1.8.24
|
152
|
+
signing_key:
|
153
|
+
specification_version: 3
|
154
|
+
summary: Bateman retrieves a webpage's Twitter Card, returning the information as
|
155
|
+
stored in the page's header meta tags.
|
156
|
+
test_files:
|
157
|
+
- spec/bateman/card_attribute_spec.rb
|
158
|
+
- spec/bateman/creator_attribute_spec.rb
|
159
|
+
- spec/bateman/description_attribute_spec.rb
|
160
|
+
- spec/bateman/image_attribute_spec.rb
|
161
|
+
- spec/bateman/site_attribute_spec.rb
|
162
|
+
- spec/bateman/title_attribute_spec.rb
|
163
|
+
- spec/bateman/twitter_card_spec.rb
|
164
|
+
- spec/bateman/url_attribute_spec.rb
|
165
|
+
- spec/fixtures/valid_twitter_card.html
|
166
|
+
- spec/spec_helper.rb
|
167
|
+
- spec/support/prepare_html.rb
|
168
|
+
has_rdoc:
|