Merge pull request #51 from benbalter/better-specs

DRY up the specs a bit
This commit is contained in:
Ben Balter 2016-02-20 15:53:33 -05:00
commit fc0aa0b89b
2 changed files with 192 additions and 153 deletions

View File

@ -2,186 +2,230 @@ require 'spec_helper'
describe Jekyll::SeoTag do
subject { Jekyll::SeoTag.parse('seo', nil, nil, nil) }
let(:page) { make_page }
let(:site) { make_site }
let(:post) { make_post }
let(:context) { make_context(page: page, site: site) }
let(:output) { subject.render(context) }
let(:json) { output.match(%r{<script type=\"application/ld\+json\">(.*)</script>}m)[1] }
let(:json_data) { JSON.parse(json) }
before do
Jekyll.logger.log_level = :error
end
it 'builds' do
expect(subject.render(context)).to match(/Jekyll SEO tag/i)
expect(output).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(%r{<title>foo</title>})
expect(subject.render(context)).to match(%r{<meta property="og:title" content="foo" />})
it 'outputs the plugin version' do
version = Jekyll::SeoTag::VERSION
expect(output).to match(/Jekyll SEO tag v#{version}/i)
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(%r{<title>foo - bar</title>})
context 'with page.title' do
let(:page) { make_page('title' => 'foo') }
it 'builds the title with a page title only' do
expect(output).to match(%r{<title>foo</title>})
expected = %r{<meta property="og:title" content="foo" />}
expect(output).to match(expected)
end
context 'with site.title' do
let(:site) { make_site('title' => 'bar') }
it 'builds the title with a page title and site title' do
expect(output).to match(%r{<title>foo - bar</title>})
end
end
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(%r{<title>foo</title>})
context 'with site.title' do
let(:site) { make_site('title' => 'Site title') }
it 'builds the title with only a site title' do
expect(output).to match(%r{<title>Site title</title>})
end
end
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" />})
context 'with page.description' do
let(:page) { make_page('description' => 'foo') }
it 'uses the page description' do
expect(output).to match(%r{<meta name="description" content="foo" />})
expect(output).to match(%r{<meta property='og:description' content="foo" />})
end
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(%r{<meta name="description" content="foobar" />})
expect(subject.render(context)).to match(%r{<meta property='og:description' content="foobar" />})
context 'with page.excerpt' do
let(:page) { make_page('excerpt' => 'foo') }
it 'uses the page excerpt when no page description exists' do
expect(output).to match(%r{<meta name="description" content="foo" />})
expect(output).to match(%r{<meta property='og:description' content="foo" />})
end
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(%r{<meta name="description" content="foo" />})
expect(subject.render(context)).to match(%r{<meta property='og:description' content="foo" />})
context 'with site.description' do
let(:site) { make_site('description' => 'foo') }
it 'uses the site description when no page description nor excerpt exist' do
expect(output).to match(%r{<meta name="description" content="foo" />})
expect(output).to match(%r{<meta property='og:description' content="foo" />})
end
end
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 = %r{<meta property='og:url' content='http://example.invalid/page.html' />}
expect(subject.render(context)).to match(expected)
context 'with site.url' do
let(:site) { make_site('url' => 'http://example.invalid') }
it 'uses the site url to build the seo url' do
expected = %r{<link rel="canonical" href="http://example.invalid/page.html" />}
expect(output).to match(expected)
expected = %r{<meta property='og:url' content='http://example.invalid/page.html' />}
expect(output).to match(expected)
end
context 'with page.permalink' do
let(:page) { make_page('permalink' => '/page/index.html') }
it "uses replaces '/index.html' with '/'" do
expected = %r{<link rel="canonical" href="http://example.invalid/page/" />}
expect(output).to match(expected)
expected = %r{<meta property='og:url' content='http://example.invalid/page/' />}
expect(output).to match(expected)
end
end
context 'with site.baseurl' do
let(:site) { make_site('url' => 'http://example.invalid', 'baseurl' => '/foo') }
it 'uses baseurl to build the seo url' do
expected = %r{<link rel="canonical" href="http://example.invalid/foo/page.html" />}
expect(output).to match(expected)
expected = %r{<meta property='og:url' content='http://example.invalid/foo/page.html' />}
expect(output).to match(expected)
end
end
context 'with page.image' do
let(:page) { make_page('image' => 'foo.png') }
it 'outputs the image' do
expected = %r{<meta property="og:image" content="http://example.invalid/foo.png" />}
expect(output).to match(expected)
end
end
context 'with site.logo' do
let(:site) { make_site('logo' => 'logo.png', 'url' => 'http://example.invalid') }
it 'outputs the logo' do
expect(json_data['logo']).to eql('http://example.invalid/logo.png')
expect(json_data['url']).to eql('http://example.invalid')
end
end
context 'with site.title' do
let(:site) { make_site('title' => 'Foo', 'url' => 'http://example.invalid') }
it 'outputs the site title meta' do
expect(output).to match(%r{<meta property="og:site_name" content="Foo" />})
expect(json_data['name']).to eql('Foo')
expect(json_data['url']).to eql('http://example.invalid')
end
end
end
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 = %r{<meta property='og:url' content='http://example.invalid/page.html' />}
expect(subject.render(context)).to match(expected)
context 'with site.github.url' do
let(:github_namespace) { { 'url' => 'http://example.invalid' } }
let(:site) { make_site('github' => github_namespace) }
it 'uses site.github.url to build the seo url' do
expected = %r{<link rel="canonical" href="http://example.invalid/page.html" \/>}
expect(output).to match(expected)
expected = %r{<meta property='og:url' content='http://example.invalid/page.html' />}
expect(output).to match(expected)
end
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)
context 'posts' do
context 'with post meta' do
let(:meta) do
{
'title' => 'post',
'description' => 'description',
'image' => '/img.png'
}
end
let(:page) { make_post(meta) }
expected = %r{<link rel="canonical" href="http://example.invalid/page/" />}
expect(subject.render(context)).to match(expected)
it 'outputs post meta' do
expected = %r{<meta property="og:type" content="article" />}
expect(output).to match(expected)
expected = %r{<meta property='og:url' content='http://example.invalid/page/' />}
expect(subject.render(context)).to match(expected)
expect(json_data['headline']).to eql('post')
expect(json_data['description']).to eql('description')
expect(json_data['image']).to eql('/img.png')
end
end
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" />}
expect(subject.render(context)).to match(expected)
expected = %r{<meta property='og:url' content='http://example.invalid/foo/page.html' />}
expect(subject.render(context)).to match(expected)
context 'twitter' do
context 'with site.twitter.username' do
let(:site) { make_site('twitter' => { 'username' => 'jekyllrb' }) }
context 'with page.author as a string' do
let(:page) { make_page('author' => 'benbalter') }
it 'outputs twitter card meta' do
expected = %r{<meta name="twitter:site" content="@jekyllrb" />}
expect(output).to match(expected)
expected = %r{<meta name="twitter:creator" content="@benbalter" />}
expect(output).to match(expected)
end
end
context 'with page.author as an object' do
let(:page) { make_page('author' => { 'twitter' => '@test' }) }
it 'supports author data as an object' do
expected = %r{<meta name="twitter:creator" content="@test" />}
expect(output).to match(expected)
end
end
end
end
it 'outputs the site title meta' do
site = site('title' => 'Foo', 'url' => 'http://example.invalid')
context = context(site: site)
output = subject.render(context)
context 'with site.social' do
let(:links) { ['http://foo.invalid', 'http://bar.invalid'] }
let(:social_namespace) { { 'name' => 'Ben', 'links' => links } }
let(:site) { make_site('social' => social_namespace) }
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')
it 'outputs social meta' do
expect(json_data['@type']).to eql('person')
expect(json_data['name']).to eql('Ben')
expect(json_data['sameAs']).to eql(links)
end
end
it 'outputs post meta' do
post = post('title' => 'post', 'description' => 'description', 'image' => '/img.png')
context = context(page: post)
output = subject.render(context)
expected = %r{<meta property="og:type" content="article" />}
expect(output).to match(expected)
data = output.match(%r{<script type=\"application/ld\+json\">(.*)</script>}m)[1]
data = JSON.parse(data)
context 'with site.name' do
let(:site) { make_site('name' => 'Site name') }
expect(data['headline']).to eql('post')
expect(data['description']).to eql('description')
expect(data['image']).to eql('/img.png')
end
it 'uses site.name if site.title is not present' do
expected = %r{<meta property="og:site_name" content="Site name" />}
expect(output).to match(expected)
end
it 'outputs twitter card meta' do
site = site('twitter' => { 'username' => 'jekyllrb' })
page = page('author' => 'benbalter')
context = context(site: site, page: page)
context 'with site.title' do
let(:site) { make_site('name' => 'Site Name', 'title' => 'Site Title') }
expected = %r{<meta name="twitter:site" content="@jekyllrb" />}
expect(subject.render(context)).to match(expected)
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)
output = subject.render(context)
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)
end
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(%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')
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" />}
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" />}
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" />}
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" />}
expect(subject.render(context)).to match(expected)
it 'uses site.tile if both site.title and site.name are present' do
expected = %r{<meta property="og:site_name" content="Site Title" />}
expect(output).to match(expected)
end
end
end
it 'outputs valid HTML' do
@ -193,9 +237,4 @@ describe Jekyll::SeoTag do
status = HTML::Proofer.new(dest_dir, options).run
expect(status).to eql(true)
end
it 'outputs the plugin version' do
version = Jekyll::SeoTag::VERSION
expect(subject.render(context)).to match(/Jekyll SEO tag v#{version}/i)
end
end

View File

@ -19,13 +19,13 @@ CONFIG_DEFAULTS = {
'gems' => ['jekyll-seo-tag']
}.freeze
def page(options = {})
def make_page(options = {})
page = Jekyll::Page.new site, CONFIG_DEFAULTS['source'], '', 'page.md'
page.data = options
page
end
def post(options = {})
def make_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
@ -33,11 +33,11 @@ def post(options = {})
page
end
def site(options = {})
def make_site(options = {})
config = Jekyll.configuration CONFIG_DEFAULTS.merge(options)
Jekyll::Site.new(config)
end
def context(registers = {})
def make_context(registers = {})
Liquid::Context.new({}, {}, { site: site, page: page }.merge(registers))
end