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' } | |