diff --git a/lib/mobility/attributes.rb b/lib/mobility/attributes.rb index 075f45387..2113d027d 100644 --- a/lib/mobility/attributes.rb +++ b/lib/mobility/attributes.rb @@ -191,7 +191,8 @@ def define_reader(attribute) def #{attribute}(**options) return super() if options.delete(:super) #{set_locale_from_options_inline} - mobility_backends[:#{attribute}].read(locale, options) + _, value = mobility_backends[:#{attribute}].read(locale, options) + value end def #{attribute}?(**options) @@ -207,7 +208,8 @@ def define_writer(attribute) def #{attribute}=(value, **options) return super(value) if options.delete(:super) #{set_locale_from_options_inline} - mobility_backends[:#{attribute}].write(locale, value, options) + _, value = mobility_backends[:#{attribute}].write(locale, value, options) + value end EOM end diff --git a/lib/mobility/backend.rb b/lib/mobility/backend.rb index 5cdd2de1a..64bdb39b1 100644 --- a/lib/mobility/backend.rb +++ b/lib/mobility/backend.rb @@ -102,7 +102,8 @@ def locales # @param [Symbol] locale Locale to read # @return [TrueClass,FalseClass] Whether translation is present for locale def present?(locale, options = {}) - Util.present?(read(locale, options)) + _, value = read(locale, options) + Util.present?(value) end # @!method model_class diff --git a/lib/mobility/backends/active_record/column.rb b/lib/mobility/backends/active_record/column.rb index d7f9d268f..cd87f6d67 100644 --- a/lib/mobility/backends/active_record/column.rb +++ b/lib/mobility/backends/active_record/column.rb @@ -37,12 +37,12 @@ class ActiveRecord::Column # @!group Backend Accessors # @!macro backend_reader def read(locale, _ = {}) - model.read_attribute(column(locale)) + [locale, model.read_attribute(column(locale))] end # @!macro backend_writer def write(locale, value, _ = {}) - model.send(:write_attribute, column(locale), value) + [locale, model.send(:write_attribute, column(locale), value)] end # @!endgroup diff --git a/lib/mobility/backends/active_record/container.rb b/lib/mobility/backends/active_record/container.rb index 766b5ad78..09c979f0a 100644 --- a/lib/mobility/backends/active_record/container.rb +++ b/lib/mobility/backends/active_record/container.rb @@ -25,7 +25,7 @@ class ActiveRecord::Container # @param [Hash] options # @return [String,Integer,Boolean] Value of translation def read(locale, _ = nil) - model_translations(locale)[attribute] + [locale, model_translations(locale)[attribute]] end # @note Translation may be a string, integer, boolean, hash or array @@ -36,7 +36,7 @@ def read(locale, _ = nil) # @return [String,Integer,Boolean] Updated value def write(locale, value, _ = nil) set_attribute_translation(locale, value) - model_translations(locale)[attribute] + [locale, model_translations(locale)[attribute]] end # @!endgroup diff --git a/lib/mobility/backends/hash.rb b/lib/mobility/backends/hash.rb index 1b37e7a23..514fb09c1 100644 --- a/lib/mobility/backends/hash.rb +++ b/lib/mobility/backends/hash.rb @@ -12,13 +12,13 @@ class Hash # @!macro backend_reader # @return [Object] def read(locale, _ = {}) - translations[locale] + [locale, translations[locale]] end # @!macro backend_writer # @return [Object] def write(locale, value, _ = {}) - translations[locale] = value + [locale, translations[locale] = value] end # @!endgroup diff --git a/lib/mobility/backends/hash_valued.rb b/lib/mobility/backends/hash_valued.rb index 147475f52..98d580853 100644 --- a/lib/mobility/backends/hash_valued.rb +++ b/lib/mobility/backends/hash_valued.rb @@ -16,12 +16,12 @@ module HashValued # # @!macro backend_reader def read(locale, _options = nil) - translations[locale] + [locale, translations[locale]] end # @!macro backend_writer def write(locale, value, _options = nil) - translations[locale] = value + [locale, translations[locale] = value] end # @!endgroup diff --git a/lib/mobility/backends/key_value.rb b/lib/mobility/backends/key_value.rb index 9f2e18f24..cf039dc7c 100644 --- a/lib/mobility/backends/key_value.rb +++ b/lib/mobility/backends/key_value.rb @@ -57,12 +57,12 @@ module KeyValue # @!group Backend Accessors # @!macro backend_reader def read(locale, options = {}) - translation_for(locale, options).value + [locale, translation_for(locale, options).value] end # @!macro backend_writer def write(locale, value, options = {}) - translation_for(locale, options).value = value + [locale, translation_for(locale, options).value = value] end # @!endgroup diff --git a/lib/mobility/backends/sequel/column.rb b/lib/mobility/backends/sequel/column.rb index 500fe6ca6..d178b840e 100644 --- a/lib/mobility/backends/sequel/column.rb +++ b/lib/mobility/backends/sequel/column.rb @@ -17,14 +17,23 @@ class Sequel::Column # @!macro backend_reader def read(locale, _options = nil) column = column(locale) - model[column] if model.columns.include?(column) + if model.columns.include?(column) + [locale, model[column]] + else + [locale, nil] + end end # @!group Backend Accessors # @!macro backend_writer def write(locale, value, _options = nil) column = column(locale) - model[column] = value if model.columns.include?(column) + if model.columns.include?(column) + model[column] = value + [locale, value] + else + [locale, nil] + end end # @!macro backend_iterator diff --git a/lib/mobility/backends/sequel/container.rb b/lib/mobility/backends/sequel/container.rb index e6a8a1ebb..dd2caba67 100644 --- a/lib/mobility/backends/sequel/container.rb +++ b/lib/mobility/backends/sequel/container.rb @@ -24,7 +24,7 @@ class Sequel::Container # @param [Hash] options # @return [String,Integer,Boolean] Value of translation def read(locale, _ = nil) - model_translations(locale)[attribute] + [locale, model_translations(locale)[attribute]] end # @note Translation may be a string, integer, boolean, hash or array @@ -35,7 +35,7 @@ def read(locale, _ = nil) # @return [String,Integer,Boolean] Updated value def write(locale, value, _ = nil) set_attribute_translation(locale, value) - model_translations(locale)[attribute] + [locale, model_translations(locale)[attribute]] end # @!endgroup # diff --git a/lib/mobility/backends/sequel/pg_hash.rb b/lib/mobility/backends/sequel/pg_hash.rb index fd7787fb4..f5176c228 100644 --- a/lib/mobility/backends/sequel/pg_hash.rb +++ b/lib/mobility/backends/sequel/pg_hash.rb @@ -19,11 +19,11 @@ class PgHash include HashValued def read(locale, options = {}) - super(locale.to_s, options) + [locale, super(locale.to_s, options)[1]] end def write(locale, value, options = {}) - super(locale.to_s, value, options) + [locale, super(locale.to_s, value, options)[1]] end # @!macro backend_iterator diff --git a/lib/mobility/backends/table.rb b/lib/mobility/backends/table.rb index 1b88f1597..c6d0341e5 100644 --- a/lib/mobility/backends/table.rb +++ b/lib/mobility/backends/table.rb @@ -85,12 +85,12 @@ module Table # @!group Backend Accessors # @!macro backend_reader def read(locale, options = {}) - translation_for(locale, options).send(attribute) + [locale, translation_for(locale, options).send(attribute)] end # @!macro backend_writer def write(locale, value, options = {}) - translation_for(locale, options).send("#{attribute}=", value) + [locale, translation_for(locale, options).send("#{attribute}=", value)] end # @!endgroup diff --git a/lib/mobility/plugins/active_model/dirty.rb b/lib/mobility/plugins/active_model/dirty.rb index 5eee31b56..e03a8fc8c 100644 --- a/lib/mobility/plugins/active_model/dirty.rb +++ b/lib/mobility/plugins/active_model/dirty.rb @@ -87,9 +87,12 @@ def write(locale, value, options = {}) locale_accessor = Mobility.normalize_locale_accessor(attribute, locale) if model.changed_attributes.has_key?(locale_accessor) && model.changed_attributes[locale_accessor] == value model.send(:attributes_changed_by_setter).except!(locale_accessor) - elsif read(locale, options.merge(locale: true)) != value - model.send(:mobility_changed_attributes) << locale_accessor - model.send(:attribute_will_change!, locale_accessor) + else + _, backend_value = read(locale, options.merge(locale: true)) + if backend_value != value + model.send(:mobility_changed_attributes) << locale_accessor + model.send(:attribute_will_change!, locale_accessor) + end end super end diff --git a/lib/mobility/plugins/active_record/query.rb b/lib/mobility/plugins/active_record/query.rb index af2da6c1a..4f9101a15 100644 --- a/lib/mobility/plugins/active_record/query.rb +++ b/lib/mobility/plugins/active_record/query.rb @@ -37,7 +37,7 @@ def attribute_alias(attribute, locale = Mobility.locale) def read(locale, **) if (model_attributes_defined? && model_attributes.key?(alias_ = Query.attribute_alias(attribute, locale))) - model_attributes[alias_].value + [locale, model_attributes[alias_].value] else super end diff --git a/lib/mobility/plugins/cache.rb b/lib/mobility/plugins/cache.rb index ab52c803d..850557557 100644 --- a/lib/mobility/plugins/cache.rb +++ b/lib/mobility/plugins/cache.rb @@ -39,9 +39,9 @@ module BackendMethods def read(locale, **options) return super(locale, options) if options.delete(:cache) == false if cache.has_key?(locale) - cache[locale] + [locale, cache[locale]] else - cache[locale] = super(locale, options) + super(locale, options).tap { |_, value| cache[locale] = value } end end @@ -50,7 +50,7 @@ def read(locale, **options) # *false* to disable cache. def write(locale, value, **options) return super if options.delete(:cache) == false - cache[locale] = super + super.tap { |_, value_| cache[locale] = value_ } end # @!endgroup diff --git a/lib/mobility/plugins/default.rb b/lib/mobility/plugins/default.rb index d56a9586c..9c5346b15 100644 --- a/lib/mobility/plugins/default.rb +++ b/lib/mobility/plugins/default.rb @@ -88,10 +88,11 @@ module BackendMethods # *false* to disable presence filter. def read(locale, accessor_options = {}) default = accessor_options.has_key?(:default) ? accessor_options.delete(:default) : options[:default] - if (value = super(locale, accessor_options)).nil? - Default[default, locale: locale, accessor_options: accessor_options, model: model, attribute: attribute] + locale, value = super(locale, accessor_options) + if value.nil? + [locale, Default[default, locale: locale, accessor_options: accessor_options, model: model, attribute: attribute]] else - value + [locale, value] end end # @!endgroup diff --git a/lib/mobility/plugins/fallbacks.rb b/lib/mobility/plugins/fallbacks.rb index 9bdee2f3c..a14bba4ca 100644 --- a/lib/mobility/plugins/fallbacks.rb +++ b/lib/mobility/plugins/fallbacks.rb @@ -145,8 +145,8 @@ def define_read(fallbacks) locales = fallback == true ? fallbacks[locale] : [locale, *fallback] locales.each do |fallback_locale| - value = super(fallback_locale, options) - return value if Util.present?(value) + upstream_locale, value = super(fallback_locale, options) + return [upstream_locale, value] if Util.present?(value) end super(locale, options) diff --git a/lib/mobility/plugins/presence.rb b/lib/mobility/plugins/presence.rb index b9f64b847..0e94bd253 100644 --- a/lib/mobility/plugins/presence.rb +++ b/lib/mobility/plugins/presence.rb @@ -26,7 +26,12 @@ module BackendMethods # @option options [Boolean] presence # *false* to disable presence filter. def read(locale, **options) - options.delete(:presence) == false ? super : Presence[super] + if options.delete(:presence) == false + super + else + locale, value = super + [locale, Presence[value]] + end end # @!macro backend_writer diff --git a/lib/mobility/plugins/sequel/dirty.rb b/lib/mobility/plugins/sequel/dirty.rb index 7956a5181..bd29aa94f 100644 --- a/lib/mobility/plugins/sequel/dirty.rb +++ b/lib/mobility/plugins/sequel/dirty.rb @@ -48,9 +48,12 @@ def write(locale, value, options = {}) if model.column_changes.has_key?(locale_accessor) && model.initial_values[locale_accessor] == value super [model.changed_columns, model.initial_values].each { |h| h.delete(locale_accessor) } - elsif read(locale, options.merge(fallback: false)) != value - model.will_change_column(locale_accessor) - super + else + _, backend_value = read(locale, options.merge(fallback: false)) + if backend_value != value + model.will_change_column(locale_accessor) + super + end end end # @!endgroup diff --git a/spec/mobility/attributes_spec.rb b/spec/mobility/attributes_spec.rb index d7abe3eea..81e83659a 100644 --- a/spec/mobility/attributes_spec.rb +++ b/spec/mobility/attributes_spec.rb @@ -235,18 +235,18 @@ shared_examples_for "reader" do it "correctly maps getter method for translated attribute to backend" do expect(Mobility).to receive(:locale).and_return(:de) - expect(listener).to receive(:read).with(:de, {}).and_return("foo") + expect(listener).to receive(:read).with(:de, {}).and_return([:de, "foo"]) expect(article.title).to eq("foo") end it "correctly maps presence method for translated attribute to backend" do expect(Mobility).to receive(:locale).and_return(:de) - expect(listener).to receive(:read).with(:de, {}).and_return("foo") + expect(listener).to receive(:read).with(:de, {}).and_return([:de, "foo"]) expect(article.title?).to eq(true) end it "correctly maps locale through getter options and converts to boolean" do - expect(listener).to receive(:read).with(:fr, locale: true).and_return("foo") + expect(listener).to receive(:read).with(:fr, locale: true).and_return([:fr, "foo"]) expect(article.title(locale: "fr")).to eq("foo") end @@ -256,7 +256,7 @@ it "correctly maps other options to getter" do expect(Mobility).to receive(:locale).and_return(:de) - expect(listener).to receive(:read).with(:de, someopt: "someval").and_return("foo") + expect(listener).to receive(:read).with(:de, someopt: "someval").and_return([:de, "foo"]) expect(article.title(someopt: "someval")).to eq("foo") end @@ -280,7 +280,7 @@ it "correctly maps other options to setter" do expect(Mobility).to receive(:locale).and_return(:de) - expect(listener).to receive(:write).with(:de, "foo", someopt: "someval").and_return("foo") + expect(listener).to receive(:write).with(:de, "foo", someopt: "someval").and_return([:de, "foo"]) expect(article.send(:title=, "foo", someopt: "someval")).to eq("foo") end diff --git a/spec/mobility/backend_spec.rb b/spec/mobility/backend_spec.rb index 6e0fe8d32..3ed146f27 100644 --- a/spec/mobility/backend_spec.rb +++ b/spec/mobility/backend_spec.rb @@ -32,12 +32,12 @@ describe "#present?" do it "returns true if backend.read(locale) return non-blank value" do - expect(backend_double).to receive(:read).with(:en, {}).and_return("foo") + expect(backend_double).to receive(:read).with(:en, {}).and_return([:en, "foo"]) expect(backend.present?(:en)).to eq(true) end it "returns false if backend.read(locale) returns blank value" do - expect(backend_double).to receive(:read).with(:en, {}).and_return("") + expect(backend_double).to receive(:read).with(:en, {}).and_return([:en, ""]) expect(backend.present?(:en)).to eq(false) end end diff --git a/spec/mobility/backends/active_record/column_spec.rb b/spec/mobility/backends/active_record/column_spec.rb index 471aef5ac..fb94e2ea6 100644 --- a/spec/mobility/backends/active_record/column_spec.rb +++ b/spec/mobility/backends/active_record/column_spec.rb @@ -37,13 +37,13 @@ describe "#read" do it "returns attribute in locale from appropriate column" do aggregate_failures do - expect(backend.read(:en)).to eq("Good post!") - expect(backend.read(:ja)).to eq("なかなか面白い記事") + expect(backend.read(:en)).to eq([:en, "Good post!"]) + expect(backend.read(:ja)).to eq([:ja, "なかなか面白い記事"]) end end it "handles dashed locales" do - expect(backend.read(:"pt-BR")).to eq("Olá") + expect(backend.read(:'pt-BR')).to eq([:'pt-BR', "Olá"]) end end diff --git a/spec/mobility/backends/active_record/key_value_spec.rb b/spec/mobility/backends/active_record/key_value_spec.rb index f6cc0f715..5e6122a6b 100644 --- a/spec/mobility/backends/active_record/key_value_spec.rb +++ b/spec/mobility/backends/active_record/key_value_spec.rb @@ -38,7 +38,7 @@ expect(title_backend.send(:translations)).to receive(:find).thrice.and_call_original title_backend.write(:en, "foo") title_backend.write(:en, "bar") - expect(title_backend.read(:en)).to eq("bar") + expect(title_backend.read(:en)).to eq([:en, "bar"]) end end @@ -51,9 +51,9 @@ expect(title_backend.send(:translations)).to receive(:find).twice.and_call_original title_backend.write(:en, "foo") title_backend.write(:en, "bar") - expect(title_backend.read(:en)).to eq("bar") + expect(title_backend.read(:en)).to eq([:en, "bar"]) title_backend.write(:fr, "baz") - expect(title_backend.read(:fr)).to eq("baz") + expect(title_backend.read(:fr)).to eq([:fr, "baz"]) end it "resets translations cache when model is saved or reloaded" do @@ -102,15 +102,15 @@ it "returns attribute in locale from translations table" do aggregate_failures do - expect(title_backend.read(:en)).to eq("New Article") - expect(content_backend.read(:en)).to eq("Once upon a time...") - expect(title_backend.read(:ja)).to eq("新規記事") - expect(content_backend.read(:ja)).to eq("昔々あるところに…") + expect(title_backend.read(:en)).to eq([:en, "New Article"]) + expect(content_backend.read(:en)).to eq([:en, "Once upon a time..."]) + expect(title_backend.read(:ja)).to eq([:ja, "新規記事"]) + expect(content_backend.read(:ja)).to eq([:ja, "昔々あるところに…"]) end end it "returns nil if no translation exists" do - expect(title_backend.read(:de)).to eq(nil) + expect(title_backend.read(:de)).to eq([:de, nil]) end it "builds translation if no translation exists" do @@ -125,7 +125,7 @@ end it "returns changed value" do - expect(title_backend.read(:en)).to eq("Changed Article Title") + expect(title_backend.read(:en)).to eq([:en, "Changed Article Title"]) end end end diff --git a/spec/mobility/backends/active_record/table_spec.rb b/spec/mobility/backends/active_record/table_spec.rb index be756f645..a6798b3d0 100644 --- a/spec/mobility/backends/active_record/table_spec.rb +++ b/spec/mobility/backends/active_record/table_spec.rb @@ -25,7 +25,7 @@ expect(title_backend.model.send(title_backend.association_name)).to receive(:find).thrice.and_call_original title_backend.write(:en, "foo") title_backend.write(:en, "bar") - expect(title_backend.read(:en)).to eq("bar") + expect(title_backend.read(:en)).to eq([:en, "bar"]) end end @@ -41,9 +41,9 @@ expect(title_backend.model.send(title_backend.association_name)).to receive(:find).twice.and_call_original title_backend.write(:en, "foo") title_backend.write(:en, "bar") - expect(title_backend.read(:en)).to eq("bar") + expect(title_backend.read(:en)).to eq([:en, "bar"]) title_backend.write(:fr, "baz") - expect(title_backend.read(:fr)).to eq("baz") + expect(title_backend.read(:fr)).to eq([:fr, "baz"]) end end @@ -149,15 +149,15 @@ it "returns attribute in locale from model translations table" do aggregate_failures do - expect(title_backend.read(:en)).to eq("New Article") - expect(content_backend.read(:en)).to eq("Once upon a time...") - expect(title_backend.read(:ja)).to eq("新規記事") - expect(content_backend.read(:ja)).to eq("昔々あるところに…") + expect(title_backend.read(:en)).to eq([:en, "New Article"]) + expect(content_backend.read(:en)).to eq([:en, "Once upon a time..."]) + expect(title_backend.read(:ja)).to eq([:ja, "新規記事"]) + expect(content_backend.read(:ja)).to eq([:ja, "昔々あるところに…"]) end end it "returns nil if no translation exists" do - expect(title_backend.read(:de)).to eq(nil) + expect(title_backend.read(:de)).to eq([:de, nil]) end it "builds translation if no translation exists" do @@ -172,7 +172,7 @@ end it "returns changed value" do - expect(title_backend.read(:en)).to eq("Changed Article Title") + expect(title_backend.read(:en)).to eq([:en, "Changed Article Title"]) end end end diff --git a/spec/mobility/backends/hash_spec.rb b/spec/mobility/backends/hash_spec.rb index 1907a2399..0259999f4 100644 --- a/spec/mobility/backends/hash_spec.rb +++ b/spec/mobility/backends/hash_spec.rb @@ -5,14 +5,14 @@ describe "#read/#write" do it "returns value for locale key" do backend = described_class.new - expect(backend.read(:ja)).to eq(nil) - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:ja)).to eq([:ja, nil]) + expect(backend.read(:en)).to eq([:en, nil]) backend.write(:ja, "アアア") - expect(backend.read(:ja)).to eq("アアア") - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:ja)).to eq([:ja, "アアア"]) + expect(backend.read(:en)).to eq([:en, nil]) backend.write(:en, "foo") - expect(backend.read(:ja)).to eq("アアア") - expect(backend.read(:en)).to eq("foo") + expect(backend.read(:ja)).to eq([:ja, "アアア"]) + expect(backend.read(:en)).to eq([:en, "foo"]) end end diff --git a/spec/mobility/backends/sequel/column_spec.rb b/spec/mobility/backends/sequel/column_spec.rb index 76aba7860..df3aca249 100644 --- a/spec/mobility/backends/sequel/column_spec.rb +++ b/spec/mobility/backends/sequel/column_spec.rb @@ -33,13 +33,13 @@ describe "#read" do it "returns attribute in locale from appropriate column" do aggregate_failures do - expect(backend.read(:en)).to eq("Good post!") - expect(backend.read(:ja)).to eq("なかなか面白い記事") + expect(backend.read(:en)).to eq([:en, "Good post!"]) + expect(backend.read(:ja)).to eq([:ja, "なかなか面白い記事"]) end end it "handles dashed locales" do - expect(backend.read(:"pt-BR")).to eq("Olá") + expect(backend.read(:"pt-BR")).to eq([:'pt-BR', "Olá"]) end end diff --git a/spec/mobility/backends/sequel/key_value_spec.rb b/spec/mobility/backends/sequel/key_value_spec.rb index 5be55726c..f5d234bc5 100644 --- a/spec/mobility/backends/sequel/key_value_spec.rb +++ b/spec/mobility/backends/sequel/key_value_spec.rb @@ -43,9 +43,9 @@ expect(article.send(title_backend.association_name)).to receive(:find).twice.and_call_original title_backend.write(:en, "foo") title_backend.write(:en, "bar") - expect(title_backend.read(:en)).to eq("bar") + expect(title_backend.read(:en)).to eq([:en, "bar"]) title_backend.write(:fr, "baz") - expect(title_backend.read(:fr)).to eq("baz") + expect(title_backend.read(:fr)).to eq([:fr, "baz"]) end it "resets translations cache when model is refreshed" do @@ -88,15 +88,15 @@ it "returns attribute in locale from translations table" do aggregate_failures do - expect(title_backend.read(:en)).to eq("New Article") - expect(content_backend.read(:en)).to eq("Once upon a time...") - expect(title_backend.read(:ja)).to eq("新規記事") - expect(content_backend.read(:ja)).to eq("昔々あるところに…") + expect(title_backend.read(:en)).to eq([:en, "New Article"]) + expect(content_backend.read(:en)).to eq([:en, "Once upon a time..."]) + expect(title_backend.read(:ja)).to eq([:ja, "新規記事"]) + expect(content_backend.read(:ja)).to eq([:ja, "昔々あるところに…"]) end end it "returns nil if no translation exists" do - expect(title_backend.read(:de)).to eq(nil) + expect(title_backend.read(:de)).to eq([:de, nil]) end describe "reading back written attributes" do @@ -105,7 +105,7 @@ end it "returns changed value" do - expect(title_backend.read(:en)).to eq("Changed Article Title") + expect(title_backend.read(:en)).to eq([:en, "Changed Article Title"]) end end end diff --git a/spec/mobility/backends/sequel/table_spec.rb b/spec/mobility/backends/sequel/table_spec.rb index d031bbec6..7e396f74e 100644 --- a/spec/mobility/backends/sequel/table_spec.rb +++ b/spec/mobility/backends/sequel/table_spec.rb @@ -36,9 +36,9 @@ expect(article.send(article.title_backend.association_name)).to receive(:find).twice.and_call_original title_backend.write(:en, "foo") title_backend.write(:en, "bar") - expect(title_backend.read(:en)).to eq("bar") + expect(title_backend.read(:en)).to eq([:en, "bar"]) title_backend.write(:fr, "baz") - expect(title_backend.read(:fr)).to eq("baz") + expect(title_backend.read(:fr)).to eq([:fr, "baz"]) end # Using Article to test separate backends with separate tables fails @@ -68,15 +68,15 @@ it "returns attribute in locale from translations table" do aggregate_failures do - expect(title_backend.read(:en)).to eq("New Article") - expect(content_backend.read(:en)).to eq("Once upon a time...") - expect(title_backend.read(:ja)).to eq("新規記事") - expect(content_backend.read(:ja)).to eq("昔々あるところに…") + expect(title_backend.read(:en)).to eq([:en, "New Article"]) + expect(content_backend.read(:en)).to eq([:en, "Once upon a time..."]) + expect(title_backend.read(:ja)).to eq([:ja, "新規記事"]) + expect(content_backend.read(:ja)).to eq([:ja, "昔々あるところに…"]) end end it "returns nil if no translation exists" do - expect(title_backend.read(:de)).to eq(nil) + expect(title_backend.read(:de)).to eq([:de, nil]) end describe "reading back written attributes" do @@ -85,7 +85,7 @@ end it "returns changed value" do - expect(title_backend.read(:en)).to eq("Changed Article Title") + expect(title_backend.read(:en)).to eq([:en, "Changed Article Title"]) end end end diff --git a/spec/mobility/plugins/active_model/dirty_spec.rb b/spec/mobility/plugins/active_model/dirty_spec.rb index 7c5a1c9ad..cac9bc393 100644 --- a/spec/mobility/plugins/active_model/dirty_spec.rb +++ b/spec/mobility/plugins/active_model/dirty_spec.rb @@ -10,11 +10,12 @@ def define_backend_class Class.new do include Mobility::Backend def read(locale, **) - values[locale] + [locale, values[locale]] end def write(locale, value, **) values[locale] = value + [locale, value] end private diff --git a/spec/mobility/plugins/active_record/dirty_spec.rb b/spec/mobility/plugins/active_record/dirty_spec.rb index 10bf2d43c..4bc3c61f4 100644 --- a/spec/mobility/plugins/active_record/dirty_spec.rb +++ b/spec/mobility/plugins/active_record/dirty_spec.rb @@ -34,11 +34,11 @@ def clear_changes_information Class.new do include Mobility::Backend def read(locale, **) - values[locale] + [locale, values[locale]] end def write(locale, value, **) - values[locale] = value + [locale, values[locale] = value] end private diff --git a/spec/mobility/plugins/attribute_methods_spec.rb b/spec/mobility/plugins/attribute_methods_spec.rb index 1a884a959..9ebd73c38 100644 --- a/spec/mobility/plugins/attribute_methods_spec.rb +++ b/spec/mobility/plugins/attribute_methods_spec.rb @@ -21,14 +21,14 @@ describe "#translated_attributes" do it "returns hash of translated attribute names/values" do - expect(backend).to receive(:read).once.with(Mobility.locale, {}).and_return('foo') + expect(backend).to receive(:read).once.with(Mobility.locale, {}).and_return([Mobility.locale, 'foo']) expect(instance.translated_attributes).to eq('title' => 'foo') end end describe "#attributes" do it "adds translated attributes to normal attributes" do - expect(backend).to receive(:read).once.with(Mobility.locale, {}).and_return('foo') + expect(backend).to receive(:read).once.with(Mobility.locale, {}).and_return([Mobility.locale, 'foo']) expect(instance.attributes).to eq(untranslated_attributes.merge('title' => 'foo')) end end diff --git a/spec/mobility/plugins/cache_spec.rb b/spec/mobility/plugins/cache_spec.rb index 2945669b2..460d0b683 100644 --- a/spec/mobility/plugins/cache_spec.rb +++ b/spec/mobility/plugins/cache_spec.rb @@ -12,17 +12,17 @@ describe "#read" do it "caches reads" do - expect(listener).to receive(:read).once.with(locale, options).and_return("foo") - 2.times { expect(backend.read(locale, options)).to eq("foo") } + expect(listener).to receive(:read).once.with(locale, options).and_return([locale, "foo"]) + 2.times { expect(backend.read(locale, options)).to eq([locale, "foo"]) } end it "does not cache reads with cache: false option" do - expect(listener).to receive(:read).twice.with(locale, options).and_return("foo") - 2.times { expect(backend.read(locale, options.merge(cache: false))).to eq("foo") } + expect(listener).to receive(:read).twice.with(locale, options).and_return([locale, "foo"]) + 2.times { expect(backend.read(locale, options.merge(cache: false))).to eq([locale, "foo"]) } end it "does not modify options passed in" do - allow(listener).to receive(:read).with(locale, {}).and_return("foo") + allow(listener).to receive(:read).with(locale, {}).and_return([locale, "foo"]) options = { cache: false } backend.read(locale, options) expect(options).to eq({ cache: false }) @@ -31,22 +31,22 @@ describe "#write" do it "returns value fetched from backend" do - expect(listener).to receive(:write).twice.with(locale, "foo", options).and_return("bar") - 2.times { expect(backend.write(locale, "foo", options)).to eq("bar") } + expect(listener).to receive(:write).twice.with(locale, "foo", options).and_return([locale, "bar"]) + 2.times { expect(backend.write(locale, "foo", options)).to eq([locale, "bar"]) } end it "stores value fetched from backend in cache" do - expect(listener).to receive(:write).once.with(locale, "foo", options).and_return("bar") - expect(backend.write(locale, "foo", options)).to eq("bar") + expect(listener).to receive(:write).once.with(locale, "foo", options).and_return([locale, "bar"]) + expect(backend.write(locale, "foo", options)).to eq([locale, "bar"]) expect(listener).not_to receive(:read) - expect(backend.read(locale, options)).to eq("bar") + expect(backend.read(locale, options)).to eq([locale, "bar"]) end it "does not store value in cache with cache: false option" do - allow(listener).to receive(:write).once.with(locale, "foo", options).and_return("bar") - expect(backend.write(locale, "foo", options.merge(cache: false))).to eq("bar") - expect(listener).to receive(:read).with(locale, options).and_return("baz") - expect(backend.read(locale, options)).to eq("baz") + allow(listener).to receive(:write).once.with(locale, "foo", options).and_return([locale, "bar"]) + expect(backend.write(locale, "foo", options.merge(cache: false))).to eq([locale, "bar"]) + expect(listener).to receive(:read).with(locale, options).and_return([locale, "baz"]) + expect(backend.read(locale, options)).to eq([locale, "baz"]) end it "does not modify options passed in" do @@ -62,15 +62,15 @@ shared_examples_for "cache that resets on model action" do |action, options = nil| it "updates backend cache on #{action}" do aggregate_failures "reading and writing" do - expect(listener).to receive(:write).with(:en, "foo", {}).and_return("foo set") + expect(listener).to receive(:write).with(:en, "foo", {}).and_return([:en, "foo set"]) backend.write(:en, "foo") - expect(backend.read(:en)).to eq("foo set") + expect(backend.read(:en)).to eq([:en, "foo set"]) end aggregate_failures "resetting model" do options ? instance.send(action, options) : instance.send(action) - expect(listener).to receive(:read).with(:en, {}).and_return("from backend") - expect(backend.read(:en)).to eq("from backend") + expect(listener).to receive(:read).with(:en, {}).and_return([:en, "from backend"]) + expect(backend.read(:en)).to eq([:en, "from backend"]) end end end @@ -78,20 +78,20 @@ shared_examples_for "cache that resets on model action with multiple backends" do |action, options = nil| it "updates cache on both backends on #{action}" do aggregate_failures "reading and writing" do - expect(listener).to receive(:write).with(:en, "foo", {}).and_return("foo set") - expect(content_listener).to receive(:write).with(:en, "bar", {}).and_return("bar set") + expect(listener).to receive(:write).with(:en, "foo", {}).and_return([:en, "foo set"]) + expect(content_listener).to receive(:write).with(:en, "bar", {}).and_return([:en, "bar set"]) backend.write(:en, "foo") instance.content_backend.write(:en, "bar") - expect(backend.read(:en)).to eq("foo set") - expect(instance.content_backend.read(:en)).to eq("bar set") + expect(backend.read(:en)).to eq([:en, "foo set"]) + expect(instance.content_backend.read(:en)).to eq([:en, "bar set"]) end aggregate_failures "resetting model" do options ? instance.send(action, options) : instance.send(action) - expect(listener).to receive(:read).with(:en, {}).and_return("from title backend") - expect(backend.read(:en)).to eq("from title backend") - expect(content_listener).to receive(:read).with(:en, {}).and_return("from content backend") - expect(instance.content_backend.read(:en)).to eq("from content backend") + expect(listener).to receive(:read).with(:en, {}).and_return([:en, "from title backend"]) + expect(backend.read(:en)).to eq([:en, "from title backend"]) + expect(content_listener).to receive(:read).with(:en, {}).and_return([:en, "from content backend"]) + expect(instance.content_backend.read(:en)).to eq([:en, "from content backend"]) end end end diff --git a/spec/mobility/plugins/default_spec.rb b/spec/mobility/plugins/default_spec.rb index e3d6fec6f..4e8ebca32 100644 --- a/spec/mobility/plugins/default_spec.rb +++ b/spec/mobility/plugins/default_spec.rb @@ -9,33 +9,33 @@ describe "#read" do it "returns value if not nil" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return("foo") - expect(backend.read(:fr)).to eq("foo") + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, "foo"]) + expect(backend.read(:fr)).to eq([:fr, "foo"]) end it "returns value if value is false" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return(false) - expect(backend.read(:fr)).to eq(false) + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, false]) + expect(backend.read(:fr)).to eq([:fr, false]) end it "returns default if backend return value is nil" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return(nil) - expect(backend.read(:fr)).to eq("default foo") + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, nil]) + expect(backend.read(:fr)).to eq([:fr, "default foo"]) end it "returns value of default override if passed as option to reader" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return(nil) - expect(backend.read(:fr, default: "default bar")).to eq("default bar") + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, nil]) + expect(backend.read(:fr, default: "default bar")).to eq([:fr, "default bar"]) end it "returns nil if passed default: nil as option to reader" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return(nil) - expect(backend.read(:fr, default: nil)).to eq(nil) + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, nil]) + expect(backend.read(:fr, default: nil)).to eq([:fr, nil]) end it "returns false if passed default: false as option to reader" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return(nil) - expect(backend.read(:fr, default: false)).to eq(false) + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, nil]) + expect(backend.read(:fr, default: false)).to eq([:fr, false]) end end end @@ -44,36 +44,36 @@ plugin_setup default: Proc.new { |attribute, locale, options| "#{attribute} in #{locale} with #{options[:this]}" } it "calls default with model and attribute as args if default is a Proc" do - expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return(nil) - expect(backend.read(:fr, this: 'option')).to eq("title in fr with option") + expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return([:fr, nil]) + expect(backend.read(:fr, this: 'option')).to eq([:fr, "title in fr with option"]) end it "calls default with model and attribute as args if default option is a Proc" do aggregate_failures do # with no arguments - expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return(nil) + expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return([:fr, nil]) default_as_option = Proc.new { "default" } - expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq("default") + expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq([:fr, "default"]) # with one argument - expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return(nil) + expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return([:fr, nil]) default_as_option = Proc.new { |attribute| "default #{attribute}" } - expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq("default title") + expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq([:fr, "default title"]) # with two arguments - expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return(nil) + expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return([:fr, nil]) default_as_option = Proc.new { |attribute, locale| "default #{attribute} #{locale}" } - expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq("default title fr") + expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq([:fr, "default title fr"]) # with three arguments - expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return(nil) + expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return([:fr, nil]) default_as_option = Proc.new { |attribute, locale, options| "default #{attribute} #{locale} #{options[:this]}" } - expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq("default title fr option") + expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq([:fr, "default title fr option"]) # with any arguments - expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return(nil) + expect(listener).to receive(:read).once.with(:fr, this: 'option').and_return([:fr, nil]) default_as_option = Proc.new { |attribute, **| "default #{attribute}" } - expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq("default title") + expect(backend.read(:fr, default: default_as_option, this: 'option')).to eq([:fr, "default title"]) end end end diff --git a/spec/mobility/plugins/fallbacks_spec.rb b/spec/mobility/plugins/fallbacks_spec.rb index fe0ed4b7e..1171ff331 100644 --- a/spec/mobility/plugins/fallbacks_spec.rb +++ b/spec/mobility/plugins/fallbacks_spec.rb @@ -8,60 +8,60 @@ plugin_setup fallbacks: { :'en-US' => 'de-DE', :pt => 'de-DE' } it "returns value when value is not nil" do - allow(listener).to receive(:read).once.with(:ja, {}).and_return("ja val") - expect(backend.read(:ja)).to eq("ja val") + allow(listener).to receive(:read).once.with(:ja, {}).and_return([:ja, "ja val"]) + expect(backend.read(:ja)).to eq([:ja, "ja val"]) end it "falls through to fallback locale when value is nil" do allow(listener).to receive(:read).exactly(3).times do |locale| - { :'en-US' => nil, :en => nil, :'de-DE' => 'de val' }.fetch(locale) + [locale, { :'en-US' => nil, :en => nil, :'de-DE' => 'de val' }.fetch(locale)] end - expect(backend.read(:'en-US')).to eq("de val") + expect(backend.read(:'en-US')).to eq([:'de-DE', 'de val']) end it "falls through to fallback locale when value is blank" do allow(listener).to receive(:read).exactly(3).times do |locale| - { :'en-US' => '', :en => '', :'de-DE' => 'de val' }.fetch(locale) + [locale, { :'en-US' => '', :en => '', :'de-DE' => 'de val' }.fetch(locale)] end - expect(backend.read(:'en-US')).to eq("de val") + expect(backend.read(:'en-US')).to eq([:'de-DE', "de val"]) end it "returns backend value when no fallback is found" do expect(listener).to receive(:read).exactly(5).times do |locale| - { :'en-US' => '', :en => '', :'de-DE' => nil, :de => nil }.fetch(locale) + [locale, { :'en-US' => '', :en => '', :'de-DE' => nil, :de => nil }.fetch(locale)] end - expect(backend.read(:'en-US')).to eq('') + expect(backend.read(:'en-US')).to eq([:'en-US', '']) end it "returns backend value when fallback: false option is passed" do - expect(listener).to receive(:read).once.with(:'en-US', {}).and_return('') - expect(backend.read(:'en-US', fallback: false)).to eq('') + expect(listener).to receive(:read).once.with(:'en-US', {}).and_return([:'en-US', '']) + expect(backend.read(:'en-US', fallback: false)).to eq([:'en-US', '']) end it "falls through to fallback locale when fallback: true option is passed" do expect(listener).to receive(:read).exactly(2).times do |locale| - { :'en-US' => '', :en => 'en val' }.fetch(locale) + [locale, { :'en-US' => '', :en => 'en val' }.fetch(locale)] end - expect(backend.read(:'en-US', fallback: true)).to eq("en val") + expect(backend.read(:'en-US', fallback: true)).to eq([:en, "en val"]) end it "uses locale passed in as value of fallback option when present" do expect(listener).to receive(:read).exactly(2).times do |locale| - { :'en-US' => '', :ja => 'ja val' }.fetch(locale) + [locale, { :'en-US' => '', :ja => 'ja val' }.fetch(locale)] end - expect(backend.read(:'en-US', fallback: :ja)).to eq("ja val") + expect(backend.read(:'en-US', fallback: :ja)).to eq([:ja, "ja val"]) end it "uses array of locales passed in as value of fallback options when present" do expect(listener).to receive(:read).exactly(2).times do |locale| - { :'en-US' => '', :pl => 'pl val', :'de-DE' => 'de val' }.fetch(locale) + [locale, { :'en-US' => '', :pl => 'pl val', :'de-DE' => 'de val' }.fetch(locale)] end - expect(backend.read(:"en-US", fallback: [:pl, :'de-DE'])).to eq("pl val") + expect(backend.read(:"en-US", fallback: [:pl, :'de-DE'])).to eq([:pl, "pl val"]) end it "passes options to getter in fallback locale" do - expect(listener).to receive(:read).once.with(:'en-US', foo: true).and_return("bar") - expect(backend.read(:'en-US', foo: true)).to eq("bar") + expect(listener).to receive(:read).once.with(:'en-US', foo: true).and_return([:'en-US', "bar"]) + expect(backend.read(:'en-US', foo: true)).to eq([:'en-US', "bar"]) end it "does not modify options passed in" do @@ -81,9 +81,9 @@ I18n.fallbacks = I18n::Locale::Fallbacks.new I18n.fallbacks.map('en-US' => ['ja']) allow(listener).to receive(:read) do |locale| - { :'en-US' => '', :en => '', :ja => 'ja val' }.fetch(locale) + [locale, { :'en-US' => '', :en => '', :ja => 'ja val' }.fetch(locale)] end - expect(backend.read(:'en-US')).to eq('ja val') + expect(backend.read(:'en-US')).to eq([:ja, 'ja val']) I18n.fallbacks = i18n_fallbacks end end @@ -93,30 +93,30 @@ plugin_setup fallbacks: nil it "does not use fallbacks when accessor fallback option is false or nil" do - expect(listener).to receive(:read).with(:'en-US', {}).once.and_return('') - expect(backend.read(:'en-US')).to eq('') - expect(listener).to receive(:read).with(:'en-US', {}).once.and_return('') - expect(backend.read(:'en-US', fallback: false)).to eq('') + expect(listener).to receive(:read).with(:'en-US', {}).once.and_return([:'en-US', '']) + expect(backend.read(:'en-US')).to eq([:'en-US', '']) + expect(listener).to receive(:read).with(:'en-US', {}).once.and_return([:'en-US', '']) + expect(backend.read(:'en-US', fallback: false)).to eq([:'en-US', '']) end it "uses locale passed in as value of fallback option when present" do allow(listener).to receive(:read) do |locale| - { :'en-US' => '', :en => '', :ja => 'ja val' }.fetch(locale) + [locale, { :'en-US' => '', :en => '', :ja => 'ja val' }.fetch(locale)] end - expect(backend.read(:"en-US", fallback: :ja)).to eq('ja val') + expect(backend.read(:"en-US", fallback: :ja)).to eq([:ja, 'ja val']) end it "uses array of locales passed in as value of fallback options when present" do expect(listener).to receive(:read).exactly(4).times do |locale| - { :'en-US' => '', :pl => 'pl val', :'de-DE' => 'de val' }.fetch(locale) + [locale, { :'en-US' => '', :pl => 'pl val', :'de-DE' => 'de val' }.fetch(locale)] end - expect(backend.read(:'en-US', fallback: [:pl, :'de-DE'])).to eq('pl val') - expect(backend.read(:'en-US', fallback: [:'de-DE', :pl])).to eq('de val') + expect(backend.read(:'en-US', fallback: [:pl, :'de-DE'])).to eq([:pl, 'pl val']) + expect(backend.read(:'en-US', fallback: [:'de-DE', :pl])).to eq([:'de-DE', 'de val']) end it "does not use fallbacks when fallback: true option is passed" do - expect(listener).to receive(:read).once.with(:'en-US', {}).and_return(nil) - expect(backend.read(:'en-US', fallback: true)).to eq(nil) + expect(listener).to receive(:read).once.with(:'en-US', {}).and_return([:'en-US', nil]) + expect(backend.read(:'en-US', fallback: true)).to eq([:'en-US', nil]) end end end diff --git a/spec/mobility/plugins/presence_spec.rb b/spec/mobility/plugins/presence_spec.rb index fe7bbefe0..f817d66a1 100644 --- a/spec/mobility/plugins/presence_spec.rb +++ b/spec/mobility/plugins/presence_spec.rb @@ -9,33 +9,33 @@ describe "#read" do it "passes through present values unchanged" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return("foo") - expect(backend.read(:fr)).to eq("foo") + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, "foo"]) + expect(backend.read(:fr)).to eq([:fr, "foo"]) end it "converts blank strings to nil" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return("") - expect(backend.read(:fr)).to eq(nil) + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, ""]) + expect(backend.read(:fr)).to eq([:fr, nil]) end it "passes through nil values unchanged" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return(nil) - expect(backend.read(:fr)).to eq(nil) + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, nil]) + expect(backend.read(:fr)).to eq([:fr, nil]) end it "passes through false values unchanged" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return(false) - expect(backend.read(:fr)).to eq(false) + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, false]) + expect(backend.read(:fr)).to eq([:fr, false]) end it "does not convert blank string to nil if presence: false passed as option" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return("") - expect(backend.read(:fr, presence: false)).to eq("") + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, ""]) + expect(backend.read(:fr, presence: false)).to eq([:fr, ""]) end it "does not modify options passed in" do options = { presence: false } - expect(listener).to receive(:read).once.with(:fr, {}).and_return("") + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, ""]) backend.read(:fr, options) expect(options).to eq({ presence: false }) end @@ -43,28 +43,28 @@ describe "#write" do it "passes through present values unchanged" do - expect(listener).to receive(:write).once.with(:fr, "foo", {}).and_return("foo") - expect(backend.write(:fr, "foo")).to eq("foo") + expect(listener).to receive(:write).once.with(:fr, "foo", {}).and_return([:fr, "foo"]) + expect(backend.write(:fr, "foo")).to eq([:fr, "foo"]) end it "converts blank strings to nil" do - expect(listener).to receive(:write).once.with(:fr, nil, {}).and_return(nil) - expect(backend.write(:fr, "")).to eq(nil) + expect(listener).to receive(:write).once.with(:fr, nil, {}).and_return([:fr, nil]) + expect(backend.write(:fr, "")).to eq([:fr, nil]) end it "passes through nil values unchanged" do - expect(listener).to receive(:write).once.with(:fr, nil, {}).and_return(nil) - expect(backend.write(:fr, nil)).to eq(nil) + expect(listener).to receive(:write).once.with(:fr, nil, {}).and_return([:fr, nil]) + expect(backend.write(:fr, nil)).to eq([:fr, nil]) end it "passes through false values unchanged" do - expect(listener).to receive(:write).once.with(:fr, false, {}).and_return(false) - expect(backend.write(:fr, false)).to eq(false) + expect(listener).to receive(:write).once.with(:fr, false, {}).and_return([:fr, false]) + expect(backend.write(:fr, false)).to eq([:fr, false]) end it "does not convert blank string to nil if presence: false passed as option" do - expect(listener).to receive(:write).once.with(:fr, "", {}).and_return("") - expect(backend.write(:fr, "", presence: false)).to eq("") + expect(listener).to receive(:write).once.with(:fr, "", {}).and_return([:fr, ""]) + expect(backend.write(:fr, "", presence: false)).to eq([:fr, ""]) end it "does not modify options passed in" do @@ -81,15 +81,15 @@ describe "#read" do it "does not convert blank strings to nil" do - expect(listener).to receive(:read).once.with(:fr, {}).and_return("") - expect(backend.read(:fr)).to eq("") + expect(listener).to receive(:read).once.with(:fr, {}).and_return([:fr, ""]) + expect(backend.read(:fr)).to eq([:fr, ""]) end end describe "#write" do it "does not convert blank strings to nil" do - expect(listener).to receive(:write).once.with(:fr, "", {}).and_return("") - expect(backend.write(:fr, "")).to eq("") + expect(listener).to receive(:write).once.with(:fr, "", {}).and_return([:fr, ""]) + expect(backend.write(:fr, "")).to eq([:fr, ""]) end end end diff --git a/spec/mobility/plugins/sequel/dirty_spec.rb b/spec/mobility/plugins/sequel/dirty_spec.rb index 27b459e0a..ebe847feb 100644 --- a/spec/mobility/plugins/sequel/dirty_spec.rb +++ b/spec/mobility/plugins/sequel/dirty_spec.rb @@ -14,11 +14,11 @@ let(:backend_class) do Class.new(Mobility::Backends::Null) do def read(locale, **options) - values[locale] + [locale, values[locale]] end def write(locale, value, **options) - values[locale] = value + [locale, values[locale] = value] end private diff --git a/spec/support/shared_examples/backend_examples.rb b/spec/support/shared_examples/backend_examples.rb index d3c19e069..1eae2fdc1 100644 --- a/spec/support/shared_examples/backend_examples.rb +++ b/spec/support/shared_examples/backend_examples.rb @@ -12,7 +12,7 @@ it "can be called without options hash" do backend.write(Mobility.locale, "foo") backend.read(Mobility.locale) - expect(backend.read(Mobility.locale)).to eq("foo") + expect(backend.read(Mobility.locale)).to eq([Mobility.locale, "foo"]) end end diff --git a/spec/support/shared_examples/dup_examples.rb b/spec/support/shared_examples/dup_examples.rb index cf0cf7f7e..631e8691e 100644 --- a/spec/support/shared_examples/dup_examples.rb +++ b/spec/support/shared_examples/dup_examples.rb @@ -11,8 +11,8 @@ dupped_instance = instance.dup dupped_backend = dupped_instance.send("#{attribute}_backend") - expect(dupped_backend.read(:en)).to eq("foo") - expect(dupped_backend.read(:ja)).to eq("ほげ") + expect(dupped_backend.read(:en)).to eq([:en, "foo"]) + expect(dupped_backend.read(:ja)).to eq([:ja, "ほげ"]) save_or_raise(dupped_instance) expect(dupped_instance.send(attribute)).to eq(instance.send(attribute)) @@ -20,14 +20,14 @@ if ENV['ORM'] == 'active_record' # Ensure duped instances are pointing to different objects instance_backend.write(:en, "bar") - expect(dupped_backend.read(:en)).to eq("foo") + expect(dupped_backend.read(:en)).to eq([:en, "foo"]) end # Ensure we haven't mucked with the original instance instance.reload - expect(instance_backend.read(:en)).to eq("foo") - expect(instance_backend.read(:ja)).to eq("ほげ") + expect(instance_backend.read(:en)).to eq([:en, "foo"]) + expect(instance_backend.read(:ja)).to eq([:ja, "ほげ"]) end it "dups new record" do diff --git a/spec/support/shared_examples/serialization_examples.rb b/spec/support/shared_examples/serialization_examples.rb index 1216455f0..2adcb2877 100644 --- a/spec/support/shared_examples/serialization_examples.rb +++ b/spec/support/shared_examples/serialization_examples.rb @@ -12,8 +12,8 @@ context "with nil serialized column" do it "returns nil in any locale" do - expect(backend.read(:en)).to eq(nil) - expect(backend.read(:ja)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) + expect(backend.read(:ja)).to eq([:ja, nil]) end end @@ -23,8 +23,8 @@ instance.save instance.reload - expect(backend.read(:ja)).to eq("あああ") - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:ja)).to eq([:ja, "あああ"]) + expect(backend.read(:en)).to eq([:en, nil]) end end @@ -35,11 +35,11 @@ instance.save instance.reload - expect(backend.read(:ja)).to eq("あああ") - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:ja)).to eq([:ja, "あああ"]) + expect(backend.read(:en)).to eq([:en, nil]) other_backend = instance.mobility_backends[attribute2.to_sym] - expect(other_backend.read(:ja)).to eq(nil) - expect(other_backend.read(:en)).to eq("aaa") + expect(other_backend.read(:ja)).to eq([:ja, nil]) + expect(other_backend.read(:en)).to eq([:en, "aaa"]) end end end @@ -60,7 +60,7 @@ backend.write(:en, nil) expect(instance.read_attribute(column1)).to match_hash({ en: nil }) instance.save - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) expect(instance.read_attribute(column1)).to match_hash({}) end @@ -74,11 +74,11 @@ instance.reload if ENV['RAILS_VERSION'] < '5.0' # don't ask me why # Note: Sequel backend and Rails < 5.0 return a blank string here. - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) expect(instance.send(attribute1)).to eq(nil) instance.reload - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) expect(instance.read_attribute(column1)).to eq({}) end @@ -105,7 +105,7 @@ it "saves empty hash for serialized translations by default" do expect(instance.send(attribute1)).to eq(nil) - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) instance.save expect(instance.read_attribute(column1)).to eq({}) end @@ -162,8 +162,8 @@ def get_translations(instance, column) context "with nil serialized column" do it "returns nil in any locale" do - expect(backend.read(:en)).to eq(nil) - expect(backend.read(:ja)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) + expect(backend.read(:ja)).to eq([:ja, nil]) end end @@ -173,8 +173,8 @@ def get_translations(instance, column) instance.save instance.reload - expect(backend.read(:ja)).to eq("あああ") - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:ja)).to eq([:ja, "あああ"]) + expect(backend.read(:en)).to eq([:en, nil]) end end @@ -185,11 +185,11 @@ def get_translations(instance, column) instance.save instance.reload - expect(backend.read(:ja)).to eq("あああ") - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:ja)).to eq([:ja, "あああ"]) + expect(backend.read(:en)).to eq([:en, nil]) other_backend = instance.mobility_backends[attribute2.to_sym] - expect(other_backend.read(:ja)).to eq(nil) - expect(other_backend.read(:en)).to eq("aaa") + expect(other_backend.read(:ja)).to eq([:ja, nil]) + expect(other_backend.read(:en)).to eq([:en, "aaa"]) end end end @@ -210,7 +210,7 @@ def get_translations(instance, column) backend.write(:en, nil) expect(get_translations(instance, column1)).to match_hash({ en: nil }) instance.save - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) expect(instance[column1]).to eq(serialize({})) end @@ -234,15 +234,15 @@ def get_translations(instance, column) # Note that for Jsonb backend (when format is nil) this correctly returns # nil. if format - expect(backend.read(:en)).to eq("") + expect(backend.read(:en)).to eq([:en, ""]) expect(instance.send(attribute1)).to eq("") else - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) expect(instance.send(attribute1)).to eq(nil) end instance.reload - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) expect(instance[column1]).to eq(serialize({})) end @@ -269,7 +269,7 @@ def get_translations(instance, column) it "saves empty hash for serialized translations by default" do expect(instance.send(attribute1)).to eq(nil) - expect(backend.read(:en)).to eq(nil) + expect(backend.read(:en)).to eq([:en, nil]) instance.save expect(instance[column1]).to eq(serialize({})) end