add rubocop

This commit is contained in:
Ben Balter 2016-02-09 18:48:24 -05:00
parent 0b2f7a0aa2
commit f9bcb30d61
9 changed files with 168 additions and 151 deletions

10
.rubocop.yml Normal file
View File

@ -0,0 +1,10 @@
Metrics/LineLength:
Exclude:
- spec/**/*
- jekyll-seo-tag.gemspec
Style/Documentation:
Enabled: false
Style/FileName:
Enabled: false

View File

@ -1,6 +1,6 @@
require "bundler/gem_tasks"
require "rspec/core/rake_task"
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task :default => :spec
task default: :spec

View File

@ -4,31 +4,31 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'jekyll-seo-tag/version'
Gem::Specification.new do |spec|
spec.name = "jekyll-seo-tag"
spec.name = 'jekyll-seo-tag'
spec.version = Jekyll::SeoTag::VERSION
spec.authors = ["Ben Balter"]
spec.email = ["ben.balter@github.com"]
spec.summary = %q{A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content.}
spec.homepage = "https://github.com/benbalter/jekyll-seo-tag"
spec.license = "MIT"
spec.authors = ['Ben Balter']
spec.email = ['ben.balter@github.com']
spec.summary = "A Jekyll plugin to add metadata tags for search engines and social networks to better index and display your site's content."
spec.homepage = 'https://github.com/benbalter/jekyll-seo-tag'
spec.license = 'MIT'
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
# delete this section to allow pushing this gem to any host.
if spec.respond_to?(:metadata)
spec.metadata['allowed_push_host'] = "https://rubygems.org"
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
else
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
end
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.bindir = "exe"
spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.add_dependency "jekyll", ">= 2.0"
spec.add_development_dependency "bundler", "~> 1.10"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.3"
spec.add_development_dependency "html-proofer", "~> 2.5"
spec.require_paths = ['lib']
spec.add_dependency 'jekyll', '>= 2.0'
spec.add_development_dependency 'bundler', '~> 1.10'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'rspec', '~> 3.3'
spec.add_development_dependency 'html-proofer', '~> 2.5'
spec.add_development_dependency 'rubocop', '~> 0.37'
end

View File

@ -2,9 +2,10 @@ require 'jekyll-seo-tag/filters'
module Jekyll
class SeoTag < Liquid::Tag
attr_accessor :context
MINIFY_REGEX = /(>\n|[%}]})\s+(<|{[{%])/
def render(context)
@context = context
output = template.render!(payload, info)
@ -16,15 +17,15 @@ module Jekyll
def payload
{
"page" => context.registers[:page],
"site" => context.registers[:site].site_payload["site"]
'page' => context.registers[:page],
'site' => context.registers[:site].site_payload['site']
}
end
def info
{
:registers => context.registers,
:filters => [Jekyll::Filters, JekyllSeoTag::Filters]
registers: context.registers,
filters: [Jekyll::Filters, JekyllSeoTag::Filters]
}
end
@ -33,11 +34,15 @@ module Jekyll
end
def template_contents
@template_contents ||= File.read(template_path).gsub(/(>\n|[%}]})\s+(<|{[{%])/,'\1\2').chomp
@template_contents ||= begin
File.read(template_path).gsub(MINIFY_REGEX, '\1\2').chomp
end
end
def template_path
@template_path ||= File.expand_path "./template.html", File.dirname(__FILE__)
@template_path ||= begin
File.expand_path './template.html', File.dirname(__FILE__)
end
end
end
end

View File

@ -1,6 +1,5 @@
module JekyllSeoTag
module Filters
# This is available in Liquid from version 3 which is required by Jekyll 3
# Provided here for compatibility with Jekyll 2.x
def default(input, default_value = ''.freeze)

View File

@ -3,6 +3,6 @@ module Liquid; class Tag; end; end
module Jekyll
class SeoTag < Liquid::Tag
VERSION = "1.0.0"
VERSION = '1.0.0'.freeze
end
end

View File

@ -3,4 +3,5 @@
set -ex
bundle exec rake spec
bundle exec rubocop -S -D
bundle exec gem build jekyll-seo-tag.gemspec

View File

@ -1,192 +1,194 @@
require 'spec_helper'
describe Jekyll::SeoTag do
subject { Jekyll::SeoTag.parse("seo", nil, nil, nil) }
subject { Jekyll::SeoTag.parse('seo', nil, nil, nil) }
before do
Jekyll.logger.log_level = :error
end
it "builds" do
it 'builds' do
expect(subject.render(context)).to match(/Jekyll SEO tag/i)
end
it "builds the title with a page title only" do
page = page({"title" => "foo"})
context = context({ :page => page })
expect(subject.render(context)).to match(/<title>foo<\/title>/)
expect(subject.render(context)).to match(/<meta property="og:title" content="foo" \/>/)
it 'builds the title with a page title only' do
page = page('title' => 'foo')
context = context(page: page)
expect(subject.render(context)).to match(%r{<title>foo</title>})
expect(subject.render(context)).to match(%r{<meta property="og:title" content="foo" />})
end
it "builds the title with a page title and site title" do
page = page({"title" => "foo"})
site = site({"title" => "bar"})
context = context({ :page => page, :site => site })
expect(subject.render(context)).to match(/<title>foo - bar<\/title>/)
it 'builds the title with a page title and site title' do
page = page('title' => 'foo')
site = site('title' => 'bar')
context = context(page: page, site: site)
expect(subject.render(context)).to match(%r{<title>foo - bar</title>})
end
it "builds the title with only a site title" do
site = site({"title" => "foo"})
context = context({ :site => site })
expect(subject.render(context)).to match(/<title>foo<\/title>/)
it 'builds the title with only a site title' do
site = site('title' => 'foo')
context = context(site: site)
expect(subject.render(context)).to match(%r{<title>foo</title>})
end
it "uses the page description" do
page = page({"description" => "foo"})
context = context({ :page => page })
expect(subject.render(context)).to match(/<meta name="description" content="foo" \/>/)
expect(subject.render(context)).to match(/<meta property='og:description' content="foo" \/>/)
it 'uses the page description' do
page = page('description' => 'foo')
context = context(page: page)
expect(subject.render(context)).to match(%r{<meta name="description" content="foo" />})
expect(subject.render(context)).to match(%r{<meta property='og:description' content="foo" />})
end
it "uses the page excerpt when no page description exists" do
page = page({"description" => "foobar"})
context = context({ :page => page })
expect(subject.render(context)).to match(/<meta name="description" content="foobar" \/>/)
expect(subject.render(context)).to match(/<meta property='og:description' content="foobar" \/>/)
it 'uses the page excerpt when no page description exists' do
page = page('description' => 'foobar')
context = context(page: page)
expect(subject.render(context)).to match(%r{<meta name="description" content="foobar" />})
expect(subject.render(context)).to match(%r{<meta property='og:description' content="foobar" />})
end
it "uses the site description when no page description nor excerpt exist" do
site = site({"description" => "foo"})
context = context({ :site => site })
expect(subject.render(context)).to match(/<meta name="description" content="foo" \/>/)
expect(subject.render(context)).to match(/<meta property='og:description' content="foo" \/>/)
it 'uses the site description when no page description nor excerpt exist' do
site = site('description' => 'foo')
context = context(site: site)
expect(subject.render(context)).to match(%r{<meta name="description" content="foo" />})
expect(subject.render(context)).to match(%r{<meta property='og:description' content="foo" />})
end
it "uses the site url to build the seo url" do
site = site({"url" => "http://example.invalid"})
context = context({ :site => site })
expected = /<link rel="canonical" href="http:\/\/example.invalid\/page.html" \/>/
it 'uses the site url to build the seo url' do
site = site('url' => 'http://example.invalid')
context = context(site: site)
expected = %r{<link rel="canonical" href="http://example.invalid/page.html" />}
expect(subject.render(context)).to match(expected)
expected = /<meta property='og:url' content='http:\/\/example.invalid\/page.html' \/>/
expected = %r{<meta property='og:url' content='http://example.invalid/page.html' />}
expect(subject.render(context)).to match(expected)
end
it "uses site.github.url to build the seo url" do
site = site({"github" => { "url" => "http://example.invalid" }} )
context = context({ :site => site })
expected = /<link rel="canonical" href="http:\/\/example.invalid\/page.html" \/>/
it 'uses site.github.url to build the seo url' do
site = site('github' => { 'url' => 'http://example.invalid' })
context = context(site: site)
expected = %r{<link rel="canonical" href="http://example.invalid/page.html" \/>}
expect(subject.render(context)).to match(expected)
expected = /<meta property='og:url' content='http:\/\/example.invalid\/page.html' \/>/
expected = %r{<meta property='og:url' content='http://example.invalid/page.html' />}
expect(subject.render(context)).to match(expected)
end
it "uses replaces '/index.html' with '/'" do
page = page({ "permalink" => "/page/index.html" })
site = site({ "url" => "http://example.invalid" })
context = context({ :page => page, :site => site })
expected = %r!<link rel="canonical" href="http://example.invalid/page/" />!
expected = %r!<meta property='og:url' content='http://example.invalid/page/' />!
page = page('permalink' => '/page/index.html')
site = site('url' => 'http://example.invalid')
context = context(page: page, site: site)
expected = %r{<link rel="canonical" href="http://example.invalid/page/" />}
expect(subject.render(context)).to match(expected)
expected = %r{<meta property='og:url' content='http://example.invalid/page/' />}
expect(subject.render(context)).to match(expected)
end
it "uses baseurl to build the seo url" do
site = site({ "url" => "http://example.invalid", "baseurl" => "/foo" })
context = context({ :site => site })
expected = %r!<link rel="canonical" href="http://example.invalid/foo/page.html" />!
it 'uses baseurl to build the seo url' do
site = site('url' => 'http://example.invalid', 'baseurl' => '/foo')
context = context(site: site)
expected = %r{<link rel="canonical" href="http://example.invalid/foo/page.html" />}
expect(subject.render(context)).to match(expected)
expected = %r!<meta property='og:url' content='http://example.invalid/foo/page.html' />!
expected = %r{<meta property='og:url' content='http://example.invalid/foo/page.html' />}
expect(subject.render(context)).to match(expected)
end
it "outputs the site title meta" do
site = site({"title" => "Foo", "url" => "http://example.invalid"})
context = context({ :site => site })
it 'outputs the site title meta' do
site = site('title' => 'Foo', 'url' => 'http://example.invalid')
context = context(site: site)
output = subject.render(context)
expect(output).to match(/<meta property="og:site_name" content="Foo" \/>/)
data = output.match(/<script type=\"application\/ld\+json\">(.*)<\/script>/m)[1]
expect(output).to match(%r{<meta property="og:site_name" content="Foo" />})
data = output.match(%r{<script type=\"application/ld\+json\">(.*)</script>}m)[1]
data = JSON.parse(data)
expect(data["name"]).to eql("Foo")
expect(data["url"]).to eql("http://example.invalid")
expect(data['name']).to eql('Foo')
expect(data['url']).to eql('http://example.invalid')
end
it "outputs post meta" do
post = post({"title" => "post", "description" => "description", "image" => "/img.png" })
context = context({ :page => post })
it 'outputs post meta' do
post = post('title' => 'post', 'description' => 'description', 'image' => '/img.png')
context = context(page: post)
output = subject.render(context)
expected = /<meta property="og:type" content="article" \/>/
expected = %r{<meta property="og:type" content="article" />}
expect(output).to match(expected)
data = output.match(/<script type=\"application\/ld\+json\">(.*)<\/script>/m)[1]
data = output.match(%r{<script type=\"application/ld\+json\">(.*)</script>}m)[1]
data = JSON.parse(data)
expect(data["headline"]).to eql("post")
expect(data["description"]).to eql("description")
expect(data["image"]).to eql("/img.png")
expect(data['headline']).to eql('post')
expect(data['description']).to eql('description')
expect(data['image']).to eql('/img.png')
end
it "outputs twitter card meta" do
site = site({"twitter" => { "username" => "jekyllrb" }})
page = page({"author" => "benbalter"})
context = context({ :site => site, :page => page })
it 'outputs twitter card meta' do
site = site('twitter' => { 'username' => 'jekyllrb' })
page = page('author' => 'benbalter')
context = context(site: site, page: page)
expected = /<meta name="twitter:site" content="@jekyllrb" \/>/
expected = %r{<meta name="twitter:site" content="@jekyllrb" />}
expect(subject.render(context)).to match(expected)
expected = /<meta name="twitter:creator" content="@benbalter" \/>/
expected = %r{<meta name="twitter:creator" content="@benbalter" />}
expect(subject.render(context)).to match(expected)
end
it "outputs social meta" do
links = ["http://foo.invalid", "http://bar.invalid"]
site = site({"social" => { "name" => "Ben", "links" => links }})
context = context({ :site => site })
it 'outputs social meta' do
links = ['http://foo.invalid', 'http://bar.invalid']
site = site('social' => { 'name' => 'Ben', 'links' => links })
context = context(site: site)
output = subject.render(context)
data = output.match(/<script type=\"application\/ld\+json\">(.*)<\/script>/m)[1]
data = output.match(%r{<script type=\"application/ld\+json\">(.*)</script>}m)[1]
data = JSON.parse(data)
expect(data["@type"]).to eql("person")
expect(data["name"]).to eql("Ben")
expect(data["sameAs"]).to eql(links)
expect(data['@type']).to eql('person')
expect(data['name']).to eql('Ben')
expect(data['sameAs']).to eql(links)
end
it "outputs the logo" do
site = site({"logo" => "logo.png", "url" => "http://example.invalid" })
context = context({ :site => site })
it 'outputs the logo' do
site = site('logo' => 'logo.png', 'url' => 'http://example.invalid')
context = context(site: site)
output = subject.render(context)
data = output.match(/<script type=\"application\/ld\+json\">(.*)<\/script>/m)[1]
data = output.match(%r{<script type=\"application/ld\+json\">(.*)</script>}m)[1]
data = JSON.parse(data)
expect(data["logo"]).to eql("http://example.invalid/logo.png")
expect(data["url"]).to eql("http://example.invalid")
expect(data['logo']).to eql('http://example.invalid/logo.png')
expect(data['url']).to eql('http://example.invalid')
end
it "outputs the image" do
page = page({ "image" => "foo.png" })
site = site({ "url" => "http://example.invalid" })
context = context({ :page => page, :site => site })
expected = %r!<meta property="og:image" content="http://example.invalid/foo.png" />!
it 'outputs the image' do
page = page('image' => 'foo.png')
site = site('url' => 'http://example.invalid')
context = context(page: page, site: site)
expected = %r{<meta property="og:image" content="http://example.invalid/foo.png" />}
expect(subject.render(context)).to match(expected)
end
it "uses site.name if site.title is not present" do
site = site({"name" => "Site Name", "title" => nil })
context = context({ :site => site })
expected = %r!<meta property="og:site_name" content="Site Name" />!
it 'uses site.name if site.title is not present' do
site = site('name' => 'Site Name', 'title' => nil)
context = context(site: site)
expected = %r{<meta property="og:site_name" content="Site Name" />}
expect(subject.render(context)).to match(expected)
end
it "uses site.tile if both site.title and site.name are present" do
site = site({"name" => "Site Name", "title" => "Site Title" })
context = context({ :site => site })
expected = %r!<meta property="og:site_name" content="Site Title" />!
it 'uses site.tile if both site.title and site.name are present' do
site = site('name' => 'Site Name', 'title' => 'Site Title')
context = context(site: site)
expected = %r{<meta property="og:site_name" content="Site Title" />}
expect(subject.render(context)).to match(expected)
end
it "supports author data as an object" do
site = site({"twitter" => { "username" => "jekyllrb" }})
page = page({"author" => {"twitter" => "@test"}})
context = context({ :site => site, :page => page })
expected = %r!<meta name="twitter:creator" content="@test" />!
it 'supports author data as an object' do
site = site('twitter' => { 'username' => 'jekyllrb' })
page = page('author' => { 'twitter' => '@test' })
context = context(site: site, page: page)
expected = %r{<meta name="twitter:creator" content="@test" />}
expect(subject.render(context)).to match(expected)
end
it "outputs valid HTML" do
it 'outputs valid HTML' do
site.process
options = {
:check_html => true,
:checks_to_ignore => ["ScriptCheck", "LinkCheck", "ImageCheck"]
check_html: true,
checks_to_ignore: %w(ScriptCheck LinkCheck ImageCheck)
}
status = HTML::Proofer.new(dest_dir, options).run
expect(status).to eql(true)

View File

@ -3,41 +3,41 @@ require 'jekyll'
require 'jekyll-seo-tag'
require 'html/proofer'
ENV["JEKYLL_LOG_LEVEL"] = "error"
ENV['JEKYLL_LOG_LEVEL'] = 'error'
def dest_dir
File.expand_path("../tmp/dest", File.dirname(__FILE__))
File.expand_path('../tmp/dest', File.dirname(__FILE__))
end
def source_dir
File.expand_path("./fixtures", File.dirname(__FILE__))
File.expand_path('./fixtures', File.dirname(__FILE__))
end
CONFIG_DEFAULTS = {
"source" => source_dir,
"destination" => dest_dir,
"gems" => ["jekyll-seo-tag"]
}
'source' => source_dir,
'destination' => dest_dir,
'gems' => ['jekyll-seo-tag']
}.freeze
def page(options={})
page = Jekyll::Page.new site, CONFIG_DEFAULTS["source"], "", "page.md"
def page(options = {})
page = Jekyll::Page.new site, CONFIG_DEFAULTS['source'], '', 'page.md'
page.data = options
page
end
def post(options={})
filename = File.expand_path("2015-01-01-post.md", CONFIG_DEFAULTS["source"])
config = { :site => site, :collection => site.collections["posts"] }
def post(options = {})
filename = File.expand_path('2015-01-01-post.md', CONFIG_DEFAULTS['source'])
config = { site: site, collection: site.collections['posts'] }
page = Jekyll::Document.new filename, config
page.merge_data!(options)
page
end
def site(options={})
def site(options = {})
config = Jekyll.configuration CONFIG_DEFAULTS.merge(options)
Jekyll::Site.new(config)
end
def context(registers={})
Liquid::Context.new({}, {}, { :site => site, :page => page }.merge(registers))
def context(registers = {})
Liquid::Context.new({}, {}, { site: site, page: page }.merge(registers))
end