From 85bb7b1a88a908fd1a1d6646f01d700356651797 Mon Sep 17 00:00:00 2001 From: yulii Date: Sun, 29 Sep 2013 18:14:14 +0900 Subject: [PATCH] bug fix --- config/locales/snipp.yml | 2 +- lib/snipp/config.rb | 4 +- lib/snipp/markups/html.rb | 105 ++++++++--------- lib/snipp/version.rb | 2 +- spec/snipp/markups/html_spec.rb | 199 ++++++++++++++++++++++++++------ 5 files changed, 216 insertions(+), 96 deletions(-) diff --git a/config/locales/snipp.yml b/config/locales/snipp.yml index d921154..d794e77 100644 --- a/config/locales/snipp.yml +++ b/config/locales/snipp.yml @@ -8,7 +8,7 @@ en: site_name: "Snipp" title: "Default Title for Open Graph" description: "Default Description for Open Graph" - type: "website" + type: "article" views: snipp: diff --git a/lib/snipp/config.rb b/lib/snipp/config.rb index 138ef10..75a6d10 100644 --- a/lib/snipp/config.rb +++ b/lib/snipp/config.rb @@ -12,7 +12,7 @@ def self.config class Configuration #:nodoc: include ActiveSupport::Configurable - config_accessor :root_url, :markup, :html_meta_tags + config_accessor :root_url, :markup, :html_meta def param_name config.param_name.respond_to?(:call) ? config.param_name.call : config.param_name @@ -26,7 +26,7 @@ def param_name configure do |config| config.markup = :microdata - config.html_meta_tags = { + config.html_meta = { title: '', description: '', keywords: '', diff --git a/lib/snipp/markups/html.rb b/lib/snipp/markups/html.rb index 82b86d7..4edb70d 100644 --- a/lib/snipp/markups/html.rb +++ b/lib/snipp/markups/html.rb @@ -3,49 +3,30 @@ module Markup module Html def set_html_meta args, options = {} - i18n_options = { - scope: (([:views] + params[:controller].split('/')) << params[:action] << :meta), - default_scope: [:default, :meta] - }.merge(options) - - link = args.delete(:link) - html_meta.merge!(link: link) if link - - Snipp.config.html_meta_tags.each do |name, content| - value = html_meta_contents(name, content, args[name], i18n_options) - html_meta[name] = value unless value.blank? - end + merger = lambda {|key, old, new| Hash === old && Hash === new ? old.merge(new, &merger) : new } + html_meta.merge!(args, &merger) + meta_options.merge!(options) end def set_html_meta! args - @html_meta = {} - link = args.delete(:link) - html_meta.merge!(link: link) if link - - args.each do |name, content| - html_meta[name] = html_meta_contents(name, content, content, {}) if content - end + @html_meta = args end def html_meta_tags result = '' - set_html_meta({}) if html_meta.empty? + meta_link = html_meta.delete(:link)||{} - # TDK + # Title title = html_meta.delete(:title) - unless title.blank? - result << content_tag(:title, title) - result << tag(:meta, name: :title, content: title) - end - - html_meta.each do |name, content| - if content.is_a?(Hash) - result << build_meta_property_tags(name, content) + title = select_content(:title) if title.empty? + result << content_tag(:title, title) unless title.blank? + + html_meta.each do |name, value| + if value.is_a?(Hash) + result << build_property_contents(value, name, name) else - Array(content).each do |c| - result << tag(:meta, name: name, content: c) unless c.blank? - end + result << build_contents(name, value) end end @@ -57,45 +38,55 @@ def html_meta_tags end private - def html_meta_contents property, content, arg, options = {} - result = {} - if content.is_a?(Hash) - opts = options.dup - opts[:scope] << property - opts[:default_scope] << property - content.each do |key, value| - result[key] = html_meta_contents(key, value, (arg ? arg[key] : nil), opts) - end - else - result = arg||content - result = I18n.t(property, options.merge(default: '')) if result.blank? - result = I18n.t(property, scope: options[:default_scope], default: '') if result.blank? + def html_meta + @html_meta ||= Snipp.config.html_meta.dup + end + + def meta_options + @meta_options ||= { default: '' } + end + + def select_content key, options = {} +#puts key + options[:scope] ||= "views.#{params[:controller].gsub(%r{/}, '.')}.#{params[:action]}.meta" + options[:default] ||= 'default.meta' + content = I18n.t("#{options[:scope]}.#{key}" ,meta_options) + content = I18n.t("#{options[:default]}.#{key}" ,default: '') if content.empty? + content + end + + # + def build_contents name, content + result = '' + Array(content).each do |content| +#puts "#{name} => #{content}" + content = select_content(name) if content.empty? + result << tag(:meta, name: name, content: content) unless content.empty? end result end - def build_meta_property_tags(property, content) + # + def build_property_contents values, property, key result = '' - if content.is_a?(Hash) - content.each do |key, value| - result << build_meta_property_tags("#{property}:#{key}", value) + if values.is_a?(Hash) + values.each do |k, v| + result << build_property_contents(v, "#{property}:#{k}", "#{key}.#{k}") end else - Array(content).each do |c| - if c.is_a?(Hash) - result << build_meta_property_tags(property, c) + Array(values).each do |content| + if content.is_a?(Hash) + result << build_contents(content, property, key) else - result << tag(:meta, property: "#{property}", content: c) unless c.blank? +#puts "#{key} => #{content}" + content = select_content(key) if content.empty? + result << tag(:meta, property: "#{property}", content: content) unless content.empty? end end end result end - def html_meta - @html_meta ||= {} - end - end end end diff --git a/lib/snipp/version.rb b/lib/snipp/version.rb index cfb0fbd..c0cd66b 100644 --- a/lib/snipp/version.rb +++ b/lib/snipp/version.rb @@ -1,3 +1,3 @@ module Snipp - VERSION = "0.1.3" + VERSION = "0.1.4" end diff --git a/spec/snipp/markups/html_spec.rb b/spec/snipp/markups/html_spec.rb index faa80c7..45e75fe 100644 --- a/spec/snipp/markups/html_spec.rb +++ b/spec/snipp/markups/html_spec.rb @@ -1,51 +1,180 @@ # coding: UTF-8 require 'spec_helper' -class Snipp::Markup::Html::Spec - - DEFAULT_SCOPE = [:default, :meta] - PAGE_SCOPE = [:views, :snipp, :html, :meta] - - META = { - title: I18n.t(:title ,scope: PAGE_SCOPE, value: "Embedding Values"), - description: I18n.t(:description ,scope: PAGE_SCOPE), - keywords: I18n.t(:keywords ,scope: DEFAULT_SCOPE) - } - OG = { - site_name: I18n.t("og.site_name" ,scope: DEFAULT_SCOPE), - title: I18n.t("og.title" ,scope: PAGE_SCOPE ,text: "Insert"), - description: I18n.t("og.description" ,scope: DEFAULT_SCOPE), - type: "article" - } - LINK = { - canonical: 'http://127.0.0.1/canonical' - } -end - describe Snipp::Markup::Html do - before do - Snipp::Hooks.init - visit "/html" -#puts page.html + let(:view) do + clazz = Class.new do + include ActionView::Helpers + include Snipp::Markup::Html + end + view = clazz.new + view.stub(:params).and_return(params) + view + end + + let(:params) { { controller: "snipp", action: "html" } } + + describe "#set_html_meta" do + let(:args) do + { + title: "Spec Title", + description: "Spec Description", + keywords: "Spec Keywords", + og: { + site_name: "Spec OG Site Name", + title: "Spec OG Title", + description: "Spec OG Description", + type: "article", + image: "https://github.com/yulii/snipp" + }, + link: { + canonical: "https://github.com/yulii/snipp" + } + } + end + + let(:object) do + view.set_html_meta(args.dup) + view.send(:html_meta) + end + + it do + expect(object).to include(args) + end + + context "when do nothing" do + let(:params) { { controller: "nothing", action: "undefined" } } + let(:args) do + Snipp.config.html_meta.select {|k, v| not v.nil? and not v.empty? } + end + + it do + expect(object).to include(args) + end + end + end + + describe "#html_meta_tags" do + let(:args) do + { + title: "Spec Title", + description: "Spec Description", + keywords: "Spec Keywords", + og: { + site_name: "Spec OG Site Name", + title: "Spec OG Title", + description: "Spec OG Description", + type: "article", + url: "https://github.com/yulii/snipp", + image: "https://github.com/yulii/snipp" + }, + link: { + canonical: "https://github.com/yulii/snipp" + } + } + end + + let(:object) do + view.set_html_meta(args.dup) + view.send(:html_meta_tags) + end + + it { expect(object).to include(view.content_tag(:title, args[:title])) } + [:description, :keywords].each do |name| + it { expect(object).to include(view.tag(:meta, name: name, content: args[name])) } + end + [:site_name, :title, :description, :type, :url, :image].each do |property| + it { expect(object).to include(view.tag(:meta, property: "og:#{property}", content: args[:og][property])) } + end + [:canonical].each do |rel| + it { expect(object).to include(view.tag(:link, rel: rel, href: args[:link][rel])) } + end + end - context "HTML Meta Tags" do - Snipp::Markup::Html::Spec::META.each do |key, value| - it "should have a `#{key}` tag" do - expect(page).to have_selector("meta[name=\"#{key}\"][content=\"#{value}\"]", count: 1) + describe "#select_content" do + let(:options) do + { value: 'Value', default: '' } + end + + let(:object) do + view.stub(:meta_options).and_return(options) + view + end + + context "when there is I18n dictionary of controller/action" do + [:title, :description].each do |key| + it { expect(object.send(:select_content, key)).to eq(I18n.t("views.snipp.html.meta.#{key}", options)) } end end - Snipp::Markup::Html::Spec::OG.each do |key, value| - it "should have a `og:#{key}` tag" do - expect(page).to have_selector("meta[property=\"og:#{key}\"][content=\"#{value}\"]", count: 1) + + context "when there is NOT I18n dictionary of controller/action" do + let(:params) { { controller: "nothing", action: "undefined" } } + + [:title, :description, :keywords].each do |key| + it { expect(object.send(:select_content, key)).to eq(I18n.t("default.meta.#{key}")) } + end + [:site_name, :title, :description, :type].each do |property| + it { expect(object.send(:select_content, "og.#{property}")).to eq(I18n.t("default.meta.og.#{property}")) } end end - Snipp::Markup::Html::Spec::LINK.each do |key, value| - it "should have a `link[rel=\"#{key}\"]` tag" do - expect(page).to have_selector("link[rel=\"#{key}\"][href=\"#{value}\"]", count: 1) + + context "when there is no I18n dictionaries" do + [:nothing, :undefined].each do |key| + it { expect(view.send(:select_content, key)).to be_empty } end end end + describe "#build_contents" do + context "when content is Scalar" do + it do + expect( + view.send(:build_contents, :name, 'content') + ).to eq( + view.tag(:meta, name: :name, content: 'content') + ) + end + end + context "when content is Array" do + it do + expect( + view.send(:build_contents, 'robots', ['index', 'follow']) + ).to eq( + view.tag(:meta, name: 'robots', content: 'index') + + view.tag(:meta, name: 'robots', content: 'follow') + ) + end + end + context "when content is empty string" do + it { expect(view.send(:build_contents, :name, '')).to be_empty } + end + end + + context "when HTML document has rendered" do + before(:all) do + Snipp::Hooks.init + visit "/html" + end + + let(:scope) { 'views.snipp.html.meta' } + let(:default) { 'default.meta' } + let(:url) { 'http://127.0.0.1/canonical' } + + # HTML Meta + it { expect(page).to have_selector("title", count: 1, text: I18n.t("#{scope}.title" ,value: "Embedding Values")) } + it { expect(page).to have_selector("meta[name=\"description\"][content=\"#{I18n.t("#{scope}.description")}\"]", count: 1) } + it { expect(page).to have_selector("meta[name=\"keywords\"][content=\"#{I18n.t("#{default}.keywords")}\"]", count: 1) } + + # Open Graph + it { expect(page).to have_selector("meta[property=\"og:site_name\"][content=\"#{I18n.t("#{default}.og.site_name")}\"]", count: 1) } + it { expect(page).to have_selector("meta[property=\"og:type\"][content=\"#{I18n.t("#{default}.og.type")}\"]", count: 1) } + it { expect(page).to have_selector("meta[property=\"og:title\"][content=\"#{I18n.t("#{scope}.og.title" ,text: "Insert")}\"]", count: 1) } + it { expect(page).to have_selector("meta[property=\"og:description\"][content=\"#{I18n.t("#{default}.og.description")}\"]", count: 1) } + + # Link Tags + it { expect(page).to have_selector("link[rel=\"canonical\"][href=\"#{url}\"]", count: 1) } + end + end