Skip to content

Commit

Permalink
Correctly override default backend options
Browse files Browse the repository at this point in the history
  • Loading branch information
shioyama committed Jan 31, 2021
1 parent 3dfc65d commit 452be8f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 19 deletions.
17 changes: 9 additions & 8 deletions lib/mobility/plugins/backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ module Backend
def initialize(*args, **original_options)
super

# Validate that the default backend from config has valid keys
if (default = self.class.defaults[:backend])
name, backend_options = default
extra_keys = backend_options.keys - backend.valid_keys
raise InvalidOptionKey, "These are not valid #{name} backend keys: #{extra_keys.join(', ')}." unless extra_keys.empty?
end

include InstanceMethods
end

Expand Down Expand Up @@ -87,7 +80,7 @@ def initialize_options(original_options)

case options[:backend]
when String, Symbol, Class
@backend, @backend_options = options[:backend], options
@backend, @backend_options = options[:backend], options.dup
when Array
@backend, @backend_options = options[:backend]
@backend_options = @backend_options.merge(original_options)
Expand All @@ -105,6 +98,14 @@ def initialize_options(original_options)
def validate_options(options)
return super unless backend
super(options.slice(*(options.keys - backend.valid_keys)))

# Validate that the default backend from config has valid keys, or if
# it is overridden by an array input that the array has valid keys.
if options[:backend].is_a?(Array)
name, backend_options = options[:backend]
extra_keys = backend_options.keys - backend.valid_keys
raise InvalidOptionKey, "These are not valid #{name} backend keys: #{extra_keys.join(', ')}." unless extra_keys.empty?
end
end

# Override default argument-handling in DSL to store kwargs passed along
Expand Down
65 changes: 54 additions & 11 deletions spec/mobility/plugins/backend_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,22 +171,65 @@
end

describe "#initialize" do
define_plugins :foo
define_plugins :my_plugin

it "excludes backend options from plugin key validation" do
klass = Class.new(Mobility::Pluggable)
backend_class = Class.new
def backend_class.valid_keys
let(:pluggable) do
Class.new(Mobility::Pluggable) do |pluggable|
pluggable.plugin :my_plugin
end
end

before do
Mobility::Backends.register_backend(:my_backend, backend_class)

stub_const('OtherBackendClass', Class.new)
Mobility::Backends.register_backend(:other_backend, OtherBackendClass)
def OtherBackendClass.valid_keys
[:bar]
end
klass.plugin :backend, backend_class
klass.plugin :foo
end

after do
backends = Mobility::Backends.instance_variable_get(:@backends)
backends.delete(:my_backend)
backends.delete(:other_backend)
end

it "excludes backend options from plugin key validation" do
pluggable.plugin :backend, :my_backend

translations = pluggable.new(my_plugin: 'my_plugin', foo: 'bar')
expect(translations.options).to eq(backend: [:my_backend, {}], foo: 'bar', my_plugin: 'my_plugin')
expect(translations.backend_options).to eq(foo: 'bar', my_plugin: 'my_plugin')

expect {
pluggable.new(my_plugin: 'my_plugin', other: 'other')
}.to raise_error(Mobility::Pluggable::InvalidOptionKey, "No plugin configured for these keys: other.")
end

expect { klass.new(foo: 'foo', bar: 'bar') }.not_to raise_error
it "validates backend options when backend is an array" do
pluggable.plugin :backend, :my_backend, foo: "foo"

translations = pluggable.new(my_plugin: 'my_plugin', backend: [:other_backend, bar: "bar"])
expect(translations.options).to eq(backend: [:other_backend, bar: 'bar'], my_plugin: 'my_plugin')
expect(translations.backend_options).to eq(backend: [:other_backend, bar: 'bar'], bar: 'bar', my_plugin: 'my_plugin')
expect(translations.options).not_to be(translations.backend_options)

expect {
pluggable.new(my_plugin: 'my_plugin', backend: [:other_backend, baz: "baz"])
}.to raise_error(Mobility::Plugins::Backend::InvalidOptionKey, "These are not valid other_backend backend keys: baz.")
expect {
klass.new(foo: 'foo', other: 'other')
}.to raise_error(Mobility::Pluggable::InvalidOptionKey)
pluggable.new(my_plugin: 'my_plugin', backend: :other_backend, foo: "foo")
}.to raise_error(Mobility::Pluggable::InvalidOptionKey, "No plugin configured for these keys: foo.")
end

it "validates correct mixed in backend options" do
pluggable.plugin :backend, backend_class, foo: "foo"

translations = pluggable.new(backend: :other_backend, bar: "bar")
expect(translations.options).to eq(backend: :other_backend, bar: 'bar')
expect(translations.backend_options).to eq(backend: :other_backend, bar: 'bar')
expect(translations.options).not_to be(translations.backend_options)
end
end

Expand Down Expand Up @@ -221,7 +264,7 @@ def backend_class.valid_keys
describe "configuring defaults" do
before do
backend_class = stub_const("FooBackend", Class.new(Mobility::Backends::Null))
expect(backend_class).to receive(:valid_keys).twice.and_return([:association_name])
expect(backend_class).to receive(:valid_keys).at_least(1).time.and_return([:association_name])
Mobility::Backends.register_backend(:foo, FooBackend)
end
after { Mobility::Backends.instance_variable_get(:@backends).delete(:foo) }
Expand Down

0 comments on commit 452be8f

Please sign in to comment.