From 0ded70bd7e088e7d07cdc818c32058f4a3e72a00 Mon Sep 17 00:00:00 2001 From: Ben Balter Date: Sat, 20 Feb 2016 15:49:55 -0500 Subject: [PATCH 1/2] better specs --- spec/jekyll_seo_tag_spec.rb | 344 ++++++++++++++++++++---------------- spec/spec_helper.rb | 8 +- 2 files changed, 200 insertions(+), 152 deletions(-) diff --git a/spec/jekyll_seo_tag_spec.rb b/spec/jekyll_seo_tag_spec.rb index 86c8124..c7e74e7 100644 --- a/spec/jekyll_seo_tag_spec.rb +++ b/spec/jekyll_seo_tag_spec.rb @@ -2,186 +2,239 @@ 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) } 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{foo}) - expect(subject.render(context)).to match(%r{}) + 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{foo - bar}) + 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{foo}) + expected = %r{} + 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{foo - bar}) + 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{foo}) + 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{Site title}) + end end - 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{}) + context 'with page.description' do + let(:page) { make_page('description' => 'foo') } + + it 'uses the page description' do + expect(output).to match(%r{}) + expect(output).to match(%r{}) + 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{}) - expect(subject.render(context)).to match(%r{}) + 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{}) + expect(output).to match(%r{}) + 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{}) - expect(subject.render(context)).to match(%r{}) + 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{}) + expect(output).to match(%r{}) + 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{} - expect(subject.render(context)).to match(expected) - expected = %r{} - 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{} + expect(output).to match(expected) + expected = %r{} + 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{} + expect(output).to match(expected) + + expected = %r{} + 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{} + expect(output).to match(expected) + expected = %r{} + 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{} + 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 + data = output.match(%r{}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 + 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{}) + data = output.match(%r{}m)[1] + + data = JSON.parse(data) + expect(data['name']).to eql('Foo') + expect(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{} - expect(subject.render(context)).to match(expected) - expected = %r{} - 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{} + expect(output).to match(expected) + expected = %r{} + 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{} - expect(subject.render(context)).to match(expected) + it 'outputs post meta' do + expected = %r{} + expect(output).to match(expected) + data = output.match(%r{}m)[1] + data = JSON.parse(data) - expected = %r{} - expect(subject.render(context)).to match(expected) + expect(data['headline']).to eql('post') + expect(data['description']).to eql('description') + expect(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{} - expect(subject.render(context)).to match(expected) - expected = %r{} - 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{} + expect(output).to match(expected) + + expected = %r{} + 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{} + 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{}) - data = output.match(%r{}m)[1] + it 'outputs social meta' do + data = output.match(%r{}m)[1] + data = JSON.parse(data) - data = JSON.parse(data) - expect(data['name']).to eql('Foo') - expect(data['url']).to eql('http://example.invalid') + expect(data['@type']).to eql('person') + expect(data['name']).to eql('Ben') + expect(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{} - expect(output).to match(expected) - data = output.match(%r{}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{} + 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{} - expect(subject.render(context)).to match(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) - output = subject.render(context) - data = output.match(%r{}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{}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{} - 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{} - 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{} - 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{} - expect(subject.render(context)).to match(expected) + it 'uses site.tile if both site.title and site.name are present' do + expected = %r{} + expect(output).to match(expected) + end + end end it 'outputs valid HTML' do @@ -193,9 +246,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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ed7ff23..4bf3092 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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 From 7568f6b61856ada7a76dfcdb1b7a5a037ba4dfe0 Mon Sep 17 00:00:00 2001 From: Ben Balter Date: Sat, 20 Feb 2016 15:52:16 -0500 Subject: [PATCH 2/2] better json parsing --- spec/jekyll_seo_tag_spec.rb | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/spec/jekyll_seo_tag_spec.rb b/spec/jekyll_seo_tag_spec.rb index c7e74e7..86e5ed9 100644 --- a/spec/jekyll_seo_tag_spec.rb +++ b/spec/jekyll_seo_tag_spec.rb @@ -7,6 +7,8 @@ describe Jekyll::SeoTag do let(:post) { make_post } let(:context) { make_context(page: page, site: site) } let(:output) { subject.render(context) } + let(:json) { output.match(%r{}m)[1] } + let(:json_data) { JSON.parse(json) } before do Jekyll.logger.log_level = :error @@ -119,11 +121,8 @@ describe Jekyll::SeoTag do let(:site) { make_site('logo' => 'logo.png', 'url' => 'http://example.invalid') } it 'outputs the logo' do - data = output.match(%r{}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(json_data['logo']).to eql('http://example.invalid/logo.png') + expect(json_data['url']).to eql('http://example.invalid') end end @@ -132,11 +131,8 @@ describe Jekyll::SeoTag do it 'outputs the site title meta' do expect(output).to match(%r{}) - data = output.match(%r{}m)[1] - - data = JSON.parse(data) - expect(data['name']).to eql('Foo') - expect(data['url']).to eql('http://example.invalid') + expect(json_data['name']).to eql('Foo') + expect(json_data['url']).to eql('http://example.invalid') end end end @@ -167,12 +163,10 @@ describe Jekyll::SeoTag do it 'outputs post meta' do expected = %r{} expect(output).to match(expected) - data = output.match(%r{}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(json_data['headline']).to eql('post') + expect(json_data['description']).to eql('description') + expect(json_data['image']).to eql('/img.png') end end end @@ -210,12 +204,9 @@ describe Jekyll::SeoTag do let(:site) { make_site('social' => social_namespace) } it 'outputs social meta' do - data = output.match(%r{}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(json_data['@type']).to eql('person') + expect(json_data['name']).to eql('Ben') + expect(json_data['sameAs']).to eql(links) end end