Skip to content

Commit

Permalink
Validate configuration when applied
Browse files Browse the repository at this point in the history
  • Loading branch information
apexatoll committed Nov 12, 2023
1 parent 7f5f6ed commit fbe6879
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 33 deletions.
12 changes: 12 additions & 0 deletions lib/kangaru/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module Kangaru
class Application
extend Forwardable

class InvalidConfigError < StandardError; end

attr_reader :paths, :namespace, :database

attr_accessor :config_path
Expand Down Expand Up @@ -38,6 +40,8 @@ def apply_config!

config.import!(config_path) unless config_path.nil?

validate_config!

@database = setup_database!
@configured = true
end
Expand Down Expand Up @@ -73,6 +77,14 @@ def autoloader
end
end

def validate_config!
return if config.valid?

message = config.errors.map(&:full_message).join(", ")

raise InvalidConfigError, message
end

def setup_database!
return unless config.database.adaptor

Expand Down
5 changes: 5 additions & 0 deletions sig/kangaru/application.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module Kangaru
class Application
extend Forwardable

class InvalidConfigError < StandardError
end

attr_reader paths: Paths
attr_reader namespace: Module
attr_reader config: Config
Expand Down Expand Up @@ -34,6 +37,8 @@ module Kangaru

attr_reader autoloader: Zeitwerk::Loader

def validate_config!: -> void

def setup_database!: -> Database?
end
end
47 changes: 44 additions & 3 deletions spec/features/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,27 @@ class TestConfigurator < Kangaru::Configurator
describe "applying config" do
subject(:apply_config!) { SomeGem.apply_config! }

let(:configuration) { nil }
let(:configuration) do
configure_block do
<<~RUBY
config.test.required_attribute = :some_value
RUBY
end
end

let(:configurator_class) do
<<~RUBY
module SomeGem
module Configurators
class TestConfigurator < Kangaru::Configurator
attr_accessor :required_attribute
validates :required_attribute, required: true
end
end
end
RUBY
end

before { gem.load! }

Expand All @@ -138,8 +158,29 @@ class TestConfigurator < Kangaru::Configurator
end

context "when config is applied once" do
it "does not raise any errors" do
expect { apply_config! }.not_to raise_error
context "and config is not valid" do
let(:configuration) { nil }

it "raises an error" do
expect { apply_config! }.to raise_error(
Kangaru::Application::InvalidConfigError,
"Required attribute can't be blank"
)
end
end

context "and config is valid" do
let(:configuration) do
configure_block do
<<~RUBY
config.test.required_attribute = :some_value
RUBY
end
end

it "does not raise any errors" do
expect { apply_config! }.not_to raise_error
end
end
end
end
Expand Down
92 changes: 62 additions & 30 deletions spec/kangaru/application_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,22 @@

let(:database) { instance_spy(Kangaru::Database) }

let(:config_valid?) { true }
let(:config_errors) { [] }

before do
allow(Kangaru::Database).to receive(:new).and_return(database)

allow(application.config).to receive(:import!)
allow(application.config).to receive_messages(
import!: nil, valid?: config_valid?, errors: config_errors
)
end

shared_examples :configures_application do
it "does not raise any errors" do
expect { apply_config! }.not_to raise_error
end

it "marks the application as configured" do
expect { apply_config! }
.to change { application.configured? }
Expand Down Expand Up @@ -255,48 +264,71 @@
end

context "when config has not already been applied" do
before do
application.config_path = config_path
application.config.database.adaptor = adaptor
end
context "and config is invalid" do
let(:config_valid?) { false }

context "and config path is not set" do
let(:config_path) { nil }
let(:config_errors) do
[Kangaru::Validation::Error.new(attribute:, type:)]
end

context "and database adaptor is not set" do
let(:adaptor) { nil }
let(:attribute) { :some_attribute }
let(:type) { :blank }

include_examples :configures_application
include_examples :does_not_set_up_database
include_examples :does_not_import_external_config
it "raises an error" do
expect { apply_config! }.to raise_error(
described_class::InvalidConfigError,
"Some attribute can't be blank"
)
end
end

context "and database adaptor is set" do
let(:adaptor) { :sqlite }
context "and config is valid" do
let(:valid?) { true }
let(:errors) { [] }

include_examples :configures_application
include_examples :sets_up_database
include_examples :does_not_import_external_config
before do
application.config_path = config_path
application.config.database.adaptor = adaptor
end
end

context "and config path is set" do
let(:config_path) { "/foo/bar/config.yml" }
context "and config path is not set" do
let(:config_path) { nil }

context "and database adaptor is not set" do
let(:adaptor) { nil }

include_examples :configures_application
include_examples :does_not_set_up_database
include_examples :does_not_import_external_config
end

context "and database adaptor is not set" do
let(:adaptor) { nil }
context "and database adaptor is set" do
let(:adaptor) { :sqlite }

include_examples :configures_application
include_examples :does_not_set_up_database
include_examples :imports_external_config
include_examples :configures_application
include_examples :sets_up_database
include_examples :does_not_import_external_config
end
end

context "and database adaptor is set" do
let(:adaptor) { :sqlite }
context "and config path is set" do
let(:config_path) { "/foo/bar/config.yml" }

context "and database adaptor is not set" do
let(:adaptor) { nil }

include_examples :configures_application
include_examples :does_not_set_up_database
include_examples :imports_external_config
end

context "and database adaptor is set" do
let(:adaptor) { :sqlite }

include_examples :configures_application
include_examples :sets_up_database
include_examples :imports_external_config
include_examples :configures_application
include_examples :sets_up_database
include_examples :imports_external_config
end
end
end
end
Expand Down

0 comments on commit fbe6879

Please sign in to comment.