157 lines
4.0 KiB
Ruby
157 lines
4.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "pathname"
|
|
require "set"
|
|
|
|
RSpec.describe Dry::Configurable::Config do
|
|
subject(:config) do
|
|
klass.config
|
|
end
|
|
|
|
let(:klass) do
|
|
Class.new do
|
|
extend Dry::Configurable
|
|
end
|
|
end
|
|
|
|
describe "#update" do
|
|
it "sets new config values in a flat config" do
|
|
klass.setting :db
|
|
|
|
config = klass.config.update(db: "sqlite")
|
|
|
|
expect(klass.config).to be(config)
|
|
expect(config.db).to eql("sqlite")
|
|
end
|
|
|
|
it "sets new config values in a nested config" do
|
|
klass.setting :db do
|
|
setting :user, default: "root"
|
|
setting :pass, default: "secret"
|
|
end
|
|
|
|
klass.config.update(db: {user: "jane", pass: "supersecret"})
|
|
|
|
expect(klass.config.db.user).to eql("jane")
|
|
expect(klass.config.db.pass).to eql("supersecret")
|
|
end
|
|
|
|
it "runs constructors" do
|
|
klass.setting :db do
|
|
setting :user, default: "root", constructor: ->(v) { v.upcase }
|
|
setting :sslcert, constructor: ->(v) { v&.values_at(:pem, :pass)&.join }
|
|
end
|
|
|
|
klass.config.update(db: {user: "jane", sslcert: {pem: "cert", pass: "qwerty"}})
|
|
|
|
expect(klass.config.db.user).to eql("JANE")
|
|
expect(klass.config.db.sslcert).to eql("certqwerty")
|
|
end
|
|
|
|
it "raises ArgumentError when setting value is not a Hash" do
|
|
klass.setting :db do
|
|
setting :user
|
|
end
|
|
|
|
expect { klass.config.update(db: "string") }
|
|
.to raise_error(ArgumentError, '"string" is not a valid setting value')
|
|
end
|
|
end
|
|
|
|
describe "#to_h" do
|
|
before do
|
|
klass.setting :db do
|
|
setting :user, default: "root"
|
|
setting :pass, default: "secret"
|
|
setting :ports, default: Set[123, 321]
|
|
end
|
|
end
|
|
|
|
it "is used for equality" do
|
|
expect(klass.config).to eql(klass.config.dup)
|
|
end
|
|
end
|
|
|
|
describe "#dup" do
|
|
context "with a class" do
|
|
it "returns a deep-copy" do
|
|
klass = Class.new do
|
|
include Dry::Configurable
|
|
|
|
setting :db do
|
|
setting :user, default: "root"
|
|
setting :pass, default: "secret"
|
|
setting :ports, default: Set[123]
|
|
end
|
|
end
|
|
|
|
parent = Class.new(klass).new
|
|
parent.config.db.ports << 312
|
|
|
|
expect(parent.config.db.ports).to eql(Set[123, 312])
|
|
expect(parent.config.dup.db.ports).to eql(Set[123, 312])
|
|
|
|
child = Class.new(parent.class).new
|
|
child.config.db.ports << 476
|
|
|
|
expect(child.config.db.ports).to eql(Set[123, 476])
|
|
expect(child.config.dup.db.ports).to eql(Set[123, 476])
|
|
|
|
expect(klass.new.config.db.ports).to eql(Set[123])
|
|
end
|
|
end
|
|
|
|
context "with an object" do
|
|
it "returns a deep-copy" do
|
|
klass.setting :db do
|
|
setting :user, default: "root"
|
|
setting :pass, default: "secret"
|
|
setting :ports, default: Set[123]
|
|
end
|
|
|
|
parent = Class.new(klass) do
|
|
config.db.ports << 312
|
|
end
|
|
|
|
child = Class.new(parent) do
|
|
config.db.ports << 476
|
|
end
|
|
|
|
expect(klass.config.db.ports).to eql(Set[123])
|
|
|
|
expect(parent.config.db.ports).to eql(Set[123, 312])
|
|
expect(child.config.db.ports).to eql(Set[123, 312, 476])
|
|
|
|
expect(parent.config.dup.db.ports).to eql(Set[123, 312])
|
|
expect(child.config.dup.db.ports).to eql(Set[123, 312, 476])
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#[]" do
|
|
it "coerces name from string" do
|
|
klass.setting :db, default: :sqlite
|
|
|
|
expect(klass.config["db"]).to eql(:sqlite)
|
|
end
|
|
|
|
it "raises ArgumentError when name is not valid" do
|
|
expect { klass.config[:hello] }.to raise_error(ArgumentError, /hello/)
|
|
end
|
|
end
|
|
|
|
describe "#method_missing" do
|
|
it "provides access to reader methods" do
|
|
klass.setting :hello
|
|
|
|
expect { klass.config.method(:hello) }.to_not raise_error
|
|
end
|
|
|
|
it "provides access to writer methods" do
|
|
klass.setting :hello
|
|
|
|
expect { klass.config.method(:hello=) }.to_not raise_error
|
|
end
|
|
end
|
|
end
|