introduce the localized_attributes hash property for entities + fix the unit specs

did committed Mar 13, 2015
commit 8b6e8a655757d2280c9c9bfe0b38cd0c867c338e
Showing 18 changed files with 67 additions and 77 deletions
.gitignore +1 -0
@@ @@ -12,6 +12,7 @@ spec/reports
test/tmp
test/version_tmp
tmp
+ benchmark.rb
# YARD artifacts
.yardoc
locomotive/steam/decorators/i18n_decorator.rb b/lib/locomotive/steam/decorators/i18n_decorator.rb +22 -20
@@ @@ -4,7 +4,7 @@ module Locomotive
class I18nDecorator < SimpleDelegator
- # attr_accessor :__localized_attributes__
+ attr_accessor :__localized_attributes__
attr_accessor :__frozen_locale__
attr_reader :__locale__
attr_reader :__default_locale__
@@ @@ -12,7 +12,7 @@ module Locomotive
def initialize(object, locale = nil, default_locale = nil)
# ::Object.send(:puts, "Decorating #{object.class.name} with #{self.class.name}")
- # self.__localized_attributes__ = attributes || (object.respond_to?(:localized_attributes) ? object.localized_attributes : [])
+ self.__localized_attributes__ = object.localized_attributes
self.__frozen_locale__ = false
self.__locale__ = locale
self.__default_locale__ = default_locale
@@ @@ -27,7 +27,7 @@ module Locomotive
new(object, locale, default_locale)
end
- object_or_list.respond_to?(:attributes) ? decorated.first : decorated
+ object_or_list.respond_to?(:localized_attributes) ? decorated.first : decorated
end
end
@@ @@ -60,10 +60,13 @@ module Locomotive
end
def __is_localized_attribute__(name)
- return false if name == :try
- # __localized_attributes__.include?(name.to_sym)
- field = __getobj__.public_send(name.to_sym)
- field.respond_to?(:__translations__)
+ __localized_attributes__.include?(name.to_sym)
+
+ # OLD VERSION
+ # return false if name == :try
+ # # __localized_attributes__.include?(name.to_sym)
+ # field = __getobj__.public_send(name.to_sym)
+ # field.respond_to?(:__translations__)
end
def __get_localized_value__(name)
@@ @@ -98,24 +101,23 @@ module Locomotive
def method_missing(name, *args, &block)
# ::Object.send(:puts, "[#{name}][#{__locale__.inspect}][#{__default_locale__.inspect}] with #{args.inspect}") # DEBUG:
- if name.to_s.end_with?('=') && __is_localized_attribute__(name.to_s.chop)
- __set_localized_value__(name.to_s.chop, args.first)
- elsif !name.to_s.end_with?('=') && __is_localized_attribute__(name)
- __get_localized_value__(name)
- else
- # Note: we want to hit the method_missing of the target object
- __getobj__.send(name, *args, &block)
- end
-
- # if __is_localized_attribute__(name)
- # __get_localized_value__(name)
- # elsif name.to_s.end_with?('=') && __is_localized_attribute__(name.to_s.chop)
- # ::Object.send(:puts, "YOUPI (2)")
+ # if name.to_s.end_with?('=') && __is_localized_attribute__(name.to_s.chop)
# __set_localized_value__(name.to_s.chop, args.first)
+ # elsif !name.to_s.end_with?('=') && __is_localized_attribute__(name)
+ # __get_localized_value__(name)
# else
# # Note: we want to hit the method_missing of the target object
# __getobj__.send(name, *args, &block)
# end
+
+ if __is_localized_attribute__(name)
+ __get_localized_value__(name)
+ elsif name.to_s.end_with?('=') && __is_localized_attribute__(name.to_s.chop)
+ __set_localized_value__(name.to_s.chop, args.first)
+ else
+ # Note: we want to hit the method_missing of the target object
+ __getobj__.send(name, *args, &block)
+ end
end
#:nocov:
locomotive/steam/decorators/template_decorator.rb b/lib/locomotive/steam/decorators/template_decorator.rb +1 -1
@@ @@ -7,7 +7,7 @@ module Locomotive
class TemplateDecorator < I18nDecorator
def liquid_source
- if attributes.key?(:template_path)
+ if self.respond_to?(:template_path)
source_from_template_file
else
self.source
locomotive/steam/liquid/drops/i18n_base.rb b/lib/locomotive/steam/liquid/drops/i18n_base.rb +1 -1
@@ @@ -4,7 +4,7 @@ module Locomotive
module Drops
class I18nBase < Base
- def initialize(source, localized_attributes = nil)
+ def initialize(source)
# puts "creating #{self.class.name} drop for #{source.class.name}(#{source.object_id.inspect})"
decorated = source if source.respond_to?(:__locale__)
decorated ||= Locomotive::Steam::Decorators::I18nDecorator.new(source)
locomotive/steam/models/entity.rb b/lib/locomotive/steam/models/entity.rb +1 -1
@@ @@ -5,7 +5,7 @@ module Locomotive::Steam
include Locomotive::Steam::Models::Concerns::Validation
- attr_accessor :attributes
+ attr_accessor :attributes, :localized_attributes
def initialize(attributes)
@attributes = attributes.with_indifferent_access
locomotive/steam/models/mapper.rb b/lib/locomotive/steam/models/mapper.rb +4 -0
@@ @@ -44,6 +44,10 @@ module Locomotive::Steam
entity_klass.new(deserialize(attributes)).tap do |entity|
attach_entity_to_associations(entity)
set_default_attributes(entity)
+
+ entity.localized_attributes = localized_attributes.inject({}) do |hash, attribute|
+ hash[attribute] = true; hash
+ end
end
end
spec/unit/adapters/filesystem/yaml_loaders/snippet_spec.rb +1 -1
@@ @@ -10,7 +10,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::Snippet do
describe '#load' do
- let(:scope) { instance_double('Scope', locale: :en) }
+ let(:scope) { instance_double('Scope', locale: :fr, default_locale: :en) }
subject { loader.load(scope).sort { |a, b| a[:name] <=> b[:name] } }
spec/unit/decorators/i18n_decorator_spec.rb +1 -1
@@ @@ -4,7 +4,7 @@ describe Locomotive::Steam::Decorators::I18nDecorator do
let(:field) { i18n_field(:title, { en: 'Hello world!', fr: 'Bonjour monde' }) }
let(:other_field) { i18n_field(:slug, 'hello-world') }
- let(:page) { instance_double('Page', published?: true, title: field, slug: other_field) }
+ let(:page) { instance_double('Page', published?: true, title: field, slug: other_field, localized_attributes: { title: true, slug: true }) }
let(:locale) { 'fr' }
let(:default_locale) { nil }
let(:decorated) { described_class.new(page, locale, default_locale) }
spec/unit/liquid/drops/content_entry_spec.rb +4 -4
@@ @@ -4,7 +4,7 @@ describe Locomotive::Steam::Liquid::Drops::ContentEntry do
let(:site) { instance_double('Site', default_locale: 'en') }
let(:type) { instance_double('Type', fields_by_name: { title: instance_double('Field', type: :string ) }) }
- let(:entry) { instance_double('Article', _id: 42, content_type: type, title: 'Hello world', _label: 'Hello world', _slug: 'hello-world', _translated: false, seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description') }
+ let(:entry) { instance_double('Article', _id: 42, localized_attributes: {}, content_type: type, title: 'Hello world', _label: 'Hello world', _slug: 'hello-world', _translated: false, seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description') }
let(:assigns) { {} }
let(:services) { Locomotive::Steam::Services.build_instance }
let(:context) { ::Liquid::Context.new(assigns, {}, { services: services, site: site, locale: 'en' }) }
@@ @@ -32,7 +32,7 @@ describe Locomotive::Steam::Liquid::Drops::ContentEntry do
let(:authors) { instance_double('AuthorsRepository', first: 'john', local_conditions: {}) }
let(:type) { instance_double('Type', fields_by_name: { authors: instance_double('Field', type: :has_many ) }) }
- let(:entry) { instance_double('Article', content_type: type, authors: authors) }
+ let(:entry) { instance_double('Article', content_type: type, authors: authors, localized_attributes: {}) }
before { allow(authors).to receive(:dup).and_return(authors) }
@@ @@ -80,8 +80,8 @@ describe Locomotive::Steam::Liquid::Drops::ContentEntry do
describe 'i18n' do
- let(:entry) { instance_double('Article', content_type: type, attributes: { title: { en: 'Hello world', fr: 'Bonjour monde' } }) }
- let(:drop) { described_class.new(entry, [:title]).tap { |d| d.context = context } }
+ let(:entry) { instance_double('Article', content_type: type, localized_attributes: { title: true }, title: { en: 'Hello world', fr: 'Bonjour monde' }) }
+ let(:drop) { described_class.new(entry).tap { |d| d.context = context } }
subject { drop.before_method(:title) }
spec/unit/liquid/drops/content_type_proxy_collection_spec.rb +2 -2
@@ @@ -19,7 +19,7 @@ describe Locomotive::Steam::Liquid::Drops::ContentTypeProxyCollection do
describe 'acts as a collection' do
before do
- allow(services.repositories.content_entry).to receive(:all).with(content_type, nil).and_return(['a', 'b'])
+ allow(services.repositories.content_entry).to receive(:all).with(nil).and_return(['a', 'b'])
end
describe '#first' do
@@ @@ -39,7 +39,7 @@ describe Locomotive::Steam::Liquid::Drops::ContentTypeProxyCollection do
let(:assigns) { { 'with_scope' => { 'visible' => true } } }
before do
- expect(services.repositories.content_entry).to receive(:all).with(content_type, { 'visible' => true }).and_return(['a', 'b'])
+ expect(services.repositories.content_entry).to receive(:all).with({ 'visible' => true }).and_return(['a', 'b'])
end
describe '#first' do
spec/unit/liquid/drops/page_spec.rb +2 -2
@@ @@ -103,8 +103,8 @@ describe Locomotive::Steam::Liquid::Drops::Page do
describe 'i18n' do
- let(:page) { instance_double('Page', attributes: { title: { en: 'About us', fr: 'A notre sujet' } }, templatized?: false) }
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:title]).tap { |d| d.context = context } }
+ let(:page) { instance_double('Page', title: { en: 'About us', fr: 'A notre sujet' }, templatized?: false, localized_attributes: { title: true }) }
+ let(:drop) { described_class.new(page).tap { |d| d.context = context } }
it { expect(subject.title).to eq 'About us' }
spec/unit/liquid/drops/site_spec.rb +1 -1
@@ @@ -4,7 +4,7 @@ describe Locomotive::Steam::Liquid::Drops::Site do
let(:services) { Locomotive::Steam::Services.build_instance }
let(:context) { ::Liquid::Context.new({}, {}, { services: services }) }
- let(:site) { instance_double('Site', name: 'Locomotive', domains: ['acme.org'], seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description') }
+ let(:site) { instance_double('Site', name: 'Locomotive', domains: ['acme.org'], seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description', localized_attributes: {}) }
let(:drop) { described_class.new(site).tap { |d| d.context = context } }
subject { drop }
spec/unit/liquid/tags/extends_spec.rb +4 -19
@@ @@ -27,26 +27,11 @@ describe Locomotive::Steam::Liquid::Tags::Extends do
let!(:template) { parse_template(source, options) }
- describe 'parent template already parsed' do
+ let(:parent) { instance_double('Index', localized_attributes: { source: true, template: true }, source: { en: 'Hello world!' }, template: { en: nil }) }
- let(:parent_template) { parse_template('Hello world') }
- let(:parent) { instance_double('Index', attributes: { template: { en: parent_template } }, localized_attributes: [:template]) }
-
- it { expect(listener.event_names.first).to eq :extends }
- it { expect(template.render).to eq 'Hello world' }
- it { expect(options[:page]).to eq page }
-
- end
-
- describe 'parent template not parsed yet' do
-
- let(:parent) { instance_double('Index', attributes: { source: { en: 'Hello world!' }, template: { en: nil } }, localized_attributes: [:template, :source]) }
-
- it { expect(listener.event_names.first).to eq :extends }
- it { expect(template.render).to eq 'Hello world!' }
- it { expect(options[:page]).to eq page }
-
- end
+ it { expect(listener.event_names.first).to eq :extends }
+ it { expect(template.render).to eq 'Hello world!' }
+ it { expect(options[:page]).to eq page }
end
spec/unit/liquid/tags/link_to_spec.rb +6 -6
@@ @@ -39,8 +39,8 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
describe '#render' do
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:title, :fullpath]) }
- let(:page) { liquid_instance_double('Index', handle: 'index', attributes: { title: { en: 'Home', fr: 'Accueil' }, fullpath: fullpath }, templatized?: false) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page) }
+ let(:page) { liquid_instance_double('Index', handle: 'index', localized_attributes: { title: true, fullpath: true }, title: { en: 'Home', fr: 'Accueil' }, fullpath: fullpath, templatized?: false) }
let(:fullpath) { { en: 'index', fr: 'index' } }
before do
@@ @@ -86,10 +86,10 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
describe 'link to a content entry (drop)' do
let(:assigns) { { 'article' => entry_drop } }
- let(:entry_drop) { Locomotive::Steam::Liquid::Drops::ContentEntry.new(entry, [:_label, :_slug]) }
- let(:entry) { liquid_instance_double('Article', attributes: { _label: { en: 'Hello world', fr: 'Bonjour monde' }, _slug: { en: 'hello-world', fr: 'bonjour-monde' } }) }
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:fullpath]) }
- let(:page) { liquid_instance_double('ArticleTemplate', title: 'Template of an article', handle: 'article', attributes: { fullpath: { en: 'my-articles/content_type_template', fr: 'mes-articles/content_type_template' } }, localized_attributes: [:fullpath], content_entry: entry_drop.send(:_source), templatized?: true) }
+ let(:entry_drop) { Locomotive::Steam::Liquid::Drops::ContentEntry.new(entry) }
+ let(:entry) { liquid_instance_double('Article', localized_attributes: { _label: true, _slug: true }, _label: { en: 'Hello world', fr: 'Bonjour monde' }, _slug: { en: 'hello-world', fr: 'bonjour-monde' }) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page) }
+ let(:page) { liquid_instance_double('ArticleTemplate', title: 'Template of an article', handle: 'article', fullpath: { en: 'my-articles/content_type_template', fr: 'mes-articles/content_type_template' }, localized_attributes: { fullpath: true }, content_entry: entry_drop.send(:_source), templatized?: true) }
let(:source) { '{% link_to article %}' }
before do
spec/unit/liquid/tags/locale_switcher_spec.rb +6 -8
@@ @@ -6,9 +6,8 @@ describe Locomotive::Steam::Liquid::Tags::LocaleSwitcher do
let(:assigns) { { 'page' => drop } }
let(:services) { Locomotive::Steam::Services.build_instance }
let(:site) { instance_double('Site', locales: %w(en fr), default_locale: 'en') }
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:title, :fullpath]) }
- let(:attributes) { { title: { en: 'Home', fr: 'Accueil' }, fullpath: { en: 'index', fr: 'index' } } }
- let(:page) { liquid_instance_double('Index', attributes: attributes, templatized?: false) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page) }
+ let(:page) { liquid_instance_double('Index', localized_attributes: { title: true, fullpath: true }, title: { en: 'Home', fr: 'Accueil' }, fullpath: { en: 'index', fr: 'index' }, templatized?: false) }
let(:context) { ::Liquid::Context.new(assigns, {}, { services: services, site: site, locale: locale }) }
subject { render_template(source, context) }
@@ @@ -46,11 +45,10 @@ describe Locomotive::Steam::Liquid::Tags::LocaleSwitcher do
describe 'the page is templatized' do
let(:assigns) { { 'article' => entry_drop, 'page' => drop } }
- let(:entry_drop) { Locomotive::Steam::Liquid::Drops::ContentEntry.new(entry, [:_label, :_slug]) }
- let(:entry) { liquid_instance_double('Article', attributes: { _label: { en: 'Hello world', fr: 'Bonjour monde' }, _slug: { en: 'hello-world', fr: 'bonjour-monde' } }) }
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:fullpath]) }
- let(:attributes) { { fullpath: { en: 'my-articles/content_type_template', fr: 'mes-articles/content_type_template' } } }
- let(:page) { liquid_instance_double('ArticleTemplate', title: 'Article template', attributes: attributes, content_entry: entry_drop.send(:_source), templatized?: true) }
+ let(:entry_drop) { Locomotive::Steam::Liquid::Drops::ContentEntry.new(entry) }
+ let(:entry) { liquid_instance_double('Article', _label: { en: 'Hello world', fr: 'Bonjour monde' }, _slug: { en: 'hello-world', fr: 'bonjour-monde' }, localized_attributes: { _label: true, _slug: true }) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page) }
+ let(:page) { liquid_instance_double('ArticleTemplate', title: 'Article template', fullpath: { en: 'my-articles/content_type_template', fr: 'mes-articles/content_type_template' }, content_entry: entry_drop.send(:_source), templatized?: true, localized_attributes: { fullpath: true }) }
let(:source) { '{% locale_switcher label: "title" %}' }
it { is_expected.to eq '<div id="locale-switcher"><a href="/my-articles/hello-world" class="en current">Hello world</a> | <a href="/fr/mes-articles/bonjour-monde" class="fr">Bonjour monde</a></div>' }
spec/unit/liquid/tags/path_to_spec.rb +8 -8
@@ @@ -32,8 +32,8 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
describe 'from a handle of a page' do
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:fullpath]) }
- let(:page) { liquid_instance_double('Index', title: 'Index', handle: 'index', attributes: { fullpath: fullpath }, templatized?: false) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page) }
+ let(:page) { liquid_instance_double('Index', title: 'Index', handle: 'index', fullpath: fullpath, localized_attributes: { fullpath: true }, templatized?: false) }
let(:fullpath) { { en: 'index', fr: 'index' } }
let(:source) { '{% path_to index %}' }
@@ @@ -56,8 +56,8 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
describe 'from a page (drop) itself' do
let(:assigns) { { 'about_us' => drop } }
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:fullpath]) }
- let(:page) { liquid_instance_double('AboutUs', title: 'About us', handle: 'index', attributes: { fullpath: fullpath }, localized_attributes: [:fullpath], templatized?: false) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page) }
+ let(:page) { liquid_instance_double('AboutUs', title: 'About us', handle: 'index', localized_attributes: { fullpath: true }, fullpath: fullpath, localized_attributes: [:fullpath], templatized?: false) }
let(:fullpath) { { en: 'about-us', fr: 'a-notre-sujet' } }
let(:source) { '{% path_to about_us %}' }
@@ @@ -75,10 +75,10 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
describe 'from a content entry (drop)' do
let(:assigns) { { 'article' => entry_drop } }
- let(:entry_drop) { Locomotive::Steam::Liquid::Drops::ContentEntry.new(entry, [:_slug]) }
- let(:entry) { liquid_instance_double('Article', attributes: { _slug: { en: 'hello-world', fr: 'bonjour-monde' } }) }
- let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page, [:fullpath]) }
- let(:page) { liquid_instance_double('ArticleTemplate', title: 'Template of an article', handle: 'article', attributes: { fullpath: { en: 'my-articles/content_type_template', fr: 'mes-articles/content_type_template' } }, localized_attributes: [:fullpath], content_entry: entry_drop.send(:_source), templatized?: true) }
+ let(:entry_drop) { Locomotive::Steam::Liquid::Drops::ContentEntry.new(entry) }
+ let(:entry) { liquid_instance_double('Article', localized_attributes: { _slug: true }, _slug: { en: 'hello-world', fr: 'bonjour-monde' }) }
+ let(:drop) { Locomotive::Steam::Liquid::Drops::Page.new(page) }
+ let(:page) { liquid_instance_double('ArticleTemplate', title: 'Template of an article', handle: 'article', localized_attributes: { fullpath: true }, fullpath: { en: 'my-articles/content_type_template', fr: 'mes-articles/content_type_template' }, content_entry: entry_drop.send(:_source), templatized?: true) }
let(:source) { '{% path_to article %}' }
before do
spec/unit/services/parent_finder_service_spec.rb +1 -1
@@ @@ -9,7 +9,7 @@ describe Locomotive::Steam::ParentFinderService do
describe '#find' do
let(:name) { '' }
- let(:another_page) { instance_double('Index', title: 'Index', attributes: {}) }
+ let(:another_page) { instance_double('Index', title: 'Index', attributes: {}, localized_attributes: {}) }
let(:page) { instance_double('AboutUs', title: 'About us') }
subject { service.find(page, name).try(:title) }
spec/unit/services/translator_service_spec.rb +1 -1
@@ @@ -19,7 +19,7 @@ describe Locomotive::Steam::TranslatorService do
let(:translation) { instance_double('Translation', values: { 'en' => 'Example text', 'es' => 'Texto de ejemplo' }) }
before do
- allow(repository).to receive(:find).with('example_test').and_return(translation)
+ allow(repository).to receive(:by_key).with('example_test').and_return(translation)
end
it { is_expected.to eq 'Example text' }