From 521aae9de080f4f8818ea9ac52630749f3c6303b Mon Sep 17 00:00:00 2001 From: Elia Schito Date: Mon, 16 Jan 2023 19:05:19 +0100 Subject: [PATCH] Allow storing static preferences using string class names This will make unnecessary to wrap these definitions under `.to_prepare` blocks. Additionally the error message for unexpected keys has improved and now lists both all the unexpected keys along with the expected keys, mentioning the name associated to the definition. The only thing that changed is that it doesn't do so when the configuration is added but rather when it's fetched. --- .../preferences/static_model_preferences.rb | 28 +++++++++++-------- .../static_model_preferences_spec.rb | 8 ++++-- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/core/lib/spree/preferences/static_model_preferences.rb b/core/lib/spree/preferences/static_model_preferences.rb index 6b213d801a6..dd5dfdbce33 100644 --- a/core/lib/spree/preferences/static_model_preferences.rb +++ b/core/lib/spree/preferences/static_model_preferences.rb @@ -7,13 +7,8 @@ class Definition attr_reader :preferences def initialize(klass, hash) - hash = hash.symbolize_keys - hash.keys.each do |key| - if !klass.defined_preferences.include?(key) - raise "Preference #{key.inspect} is not defined on #{klass}" - end - end - @preferences = hash + @klass = klass + @preferences = hash.symbolize_keys end def fetch(key, &block) @@ -27,20 +22,29 @@ def []=(key, value) def to_hash @preferences.deep_dup end + + delegate :keys, to: :@preferences end def initialize - @store = Hash.new do |data, klass| - data[klass] = {} - end + @store = {} end def add(klass, name, preferences) - @store[klass.to_s][name] = Definition.new(klass, preferences) + @store[klass.to_s] ||= {} + @store[klass.to_s][name] = Definition.new(klass.to_s, preferences) end def for_class(klass) - @store[klass.to_s] + (@store[klass.to_s] || {}).tap do |names_with_prefs| + names_with_prefs.each do |name, preferences| + klass_keys = klass.defined_preferences.map(&:to_s) + extra_keys = preferences.keys.map(&:to_s) - klass_keys + next if extra_keys.empty? + + raise "Unexpected keys found for #{klass} under #{name}: #{extra_keys.to_sentence} (expected keys: #{klass_keys.to_sentence})" + end + end end end end diff --git a/core/spec/models/spree/preferences/static_model_preferences_spec.rb b/core/spec/models/spree/preferences/static_model_preferences_spec.rb index 9781a12d0f6..1c3e6f9c086 100644 --- a/core/spec/models/spree/preferences/static_model_preferences_spec.rb +++ b/core/spec/models/spree/preferences/static_model_preferences_spec.rb @@ -32,9 +32,13 @@ module Spree end it "errors assigning invalid preferences" do + subject.add(preference_class, 'my_definition', { ice_cream: 'chocolate' }) + expect { - subject.add(preference_class, 'my_definition', { ice_cream: 'chocolate' }) - }.to raise_error(/\APreference :ice_cream is not defined/) + subject.for_class(preference_class) + }.to raise_error( + /\AUnexpected keys found for #{Regexp.escape preference_class.to_s} under my_definition: ice_cream \(expected keys: color\)/ + ) end context "with stored definitions" do