diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..9408010 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,10 @@ +Metrics/LineLength: + Exclude: + - spec/**/* + - jekyll-seo-tag.gemspec + +Style/Documentation: + Enabled: false + +Style/FileName: + Enabled: false diff --git a/Rakefile b/Rakefile index b7e9ed5..4c774a2 100644 --- a/Rakefile +++ b/Rakefile @@ -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 diff --git a/jekyll-seo-tag.gemspec b/jekyll-seo-tag.gemspec index bc207b0..9ba99bb 100644 --- a/jekyll-seo-tag.gemspec +++ b/jekyll-seo-tag.gemspec @@ -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 diff --git a/lib/jekyll-seo-tag.rb b/lib/jekyll-seo-tag.rb index 1b6f62b..376772f 100644 --- a/lib/jekyll-seo-tag.rb +++ b/lib/jekyll-seo-tag.rb @@ -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 diff --git a/lib/jekyll-seo-tag/filters.rb b/lib/jekyll-seo-tag/filters.rb index 0f0d6ef..24856c6 100644 --- a/lib/jekyll-seo-tag/filters.rb +++ b/lib/jekyll-seo-tag/filters.rb @@ -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) diff --git a/lib/jekyll-seo-tag/version.rb b/lib/jekyll-seo-tag/version.rb index ee50ec8..97b1dca 100644 --- a/lib/jekyll-seo-tag/version.rb +++ b/lib/jekyll-seo-tag/version.rb @@ -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 diff --git a/script/cibuild b/script/cibuild index 861a7c7..e75ad1f 100755 --- a/script/cibuild +++ b/script/cibuild @@ -3,4 +3,5 @@ set -ex bundle exec rake spec +bundle exec rubocop -S -D bundle exec gem build jekyll-seo-tag.gemspec diff --git a/spec/jekyll_seo_tag_spec.rb b/spec/jekyll_seo_tag_spec.rb index 3118013..4408cba 100644 --- a/spec/jekyll_seo_tag_spec.rb +++ b/spec/jekyll_seo_tag_spec.rb @@ -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(/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}) + expect(subject.render(context)).to match(%r{}) 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(/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}) 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(/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}) end - it "uses the page description" do - page = page({"description" => "foo"}) - context = context({ :page => page }) - expect(subject.render(context)).to match(//) - expect(subject.render(context)).to match(//) + it 'uses the page description' do + page = page('description' => 'foo') + context = context(page: page) + expect(subject.render(context)).to match(%r{}) + expect(subject.render(context)).to match(%r{}) 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(//) - expect(subject.render(context)).to match(//) + 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{}) + expect(subject.render(context)).to match(%r{}) 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(//) - expect(subject.render(context)).to match(//) + 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{}) + expect(subject.render(context)).to match(%r{}) end - it "uses the site url to build the seo url" do - site = site({"url" => "http://example.invalid"}) - context = context({ :site => site }) - expected = // + it 'uses the site url to build the seo url' do + site = site('url' => 'http://example.invalid') + context = context(site: site) + expected = %r{} expect(subject.render(context)).to match(expected) - expected = // + expected = %r{} 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 = // + it 'uses site.github.url to build the seo url' do + site = site('github' => { 'url' => 'http://example.invalid' }) + context = context(site: site) + expected = %r{} expect(subject.render(context)).to match(expected) - expected = // + expected = %r{} 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!! - expected = %r!! + page = page('permalink' => '/page/index.html') + site = site('url' => 'http://example.invalid') + context = context(page: page, site: site) + + expected = %r{} + expect(subject.render(context)).to match(expected) + + expected = %r{} 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!! + it 'uses baseurl to build the seo url' do + site = site('url' => 'http://example.invalid', 'baseurl' => '/foo') + context = context(site: site) + expected = %r{} expect(subject.render(context)).to match(expected) - expected = %r!! + expected = %r{} 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(//) - data = output.match(/}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 = // + expected = %r{} expect(output).to match(expected) - data = output.match(/}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 = // + expected = %r{} expect(subject.render(context)).to match(expected) - expected = // + expected = %r{} 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(/}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(/}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!! + it 'outputs the image' do + page = page('image' => 'foo.png') + site = site('url' => 'http://example.invalid') + context = context(page: page, site: site) + expected = %r{} 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!! + it 'uses site.name if site.title is not present' do + site = site('name' => 'Site Name', 'title' => nil) + context = context(site: site) + expected = %r{} 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!! + 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{} 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!! + 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{} 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) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a391dd0..ed7ff23 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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