From 57b1e05d118c1c6cb2609fd9e7f7195ec104b4b9 Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Tue, 7 Jan 2025 06:27:48 -0700 Subject: [PATCH] Add eager loading during finalization (#276) * Add eager_loading as opton to Container#finalize! Default is false for now * Change eager_load: true by default * Inline conditional * Make spec file for eager loading --------- Co-authored-by: Nikita Shilnikov --- lib/dry/system/container.rb | 4 ++- .../auto_registration/eager_loading_spec.rb | 31 +++++++++++++++++++ .../auto_registration/memoize_spec.rb | 4 +++ spec/unit/container/configuration_spec.rb | 24 ++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 spec/integration/container/auto_registration/eager_loading_spec.rb diff --git a/lib/dry/system/container.rb b/lib/dry/system/container.rb index c84c29018..223cb6c57 100644 --- a/lib/dry/system/container.rb +++ b/lib/dry/system/container.rb @@ -314,7 +314,7 @@ def finalized? # @return [self] frozen container # # @api public - def finalize!(freeze: true, &) + def finalize!(freeze: true, eager_load: true, &) return self if finalized? configured! @@ -327,6 +327,8 @@ def finalize!(freeze: true, &) manifest_registrar.finalize! importer.finalize! + keys.each { |key| resolve(key) } if eager_load + @__finalized__ = true self.freeze if freeze diff --git a/spec/integration/container/auto_registration/eager_loading_spec.rb b/spec/integration/container/auto_registration/eager_loading_spec.rb new file mode 100644 index 000000000..a70997126 --- /dev/null +++ b/spec/integration/container/auto_registration/eager_loading_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +RSpec.describe "Eager loading during finalization" do + it "raises error when component cannot be found, due to missing inflection" do + class Test::Container < Dry::System::Container + configure do |config| + config.root = SPEC_ROOT.join("fixtures").realpath + + config.component_dirs.add "components" do |dir| + dir.namespaces.add "test", key: nil + end + end + end + expect { Test::Container.finalize! }.to raise_error(Dry::System::ComponentNotLoadableError) + end + + it "does not raise error when constant can be found" do + class Test::Container < Dry::System::Container + configure do |config| + config.root = SPEC_ROOT.join("fixtures").realpath + + config.component_dirs.add "components" do |dir| + dir.namespaces.add "test", key: nil + end + + config.inflector = Dry::Inflector.new { |i| i.acronym("ABC") } + end + end + expect { Test::Container.finalize! }.to_not raise_error + end +end diff --git a/spec/integration/container/auto_registration/memoize_spec.rb b/spec/integration/container/auto_registration/memoize_spec.rb index 5a96dfc62..af051f823 100644 --- a/spec/integration/container/auto_registration/memoize_spec.rb +++ b/spec/integration/container/auto_registration/memoize_spec.rb @@ -17,6 +17,8 @@ class Test::Container < Dry::System::Container dir.namespaces.add "test", key: nil dir.memoize = true end + + config.inflector = Dry::Inflector.new { |i| i.acronym("ABC") } end end end @@ -52,6 +54,8 @@ class Test::Container < Dry::System::Container !component.key.match?(/bar/) end end + + config.inflector = Dry::Inflector.new { |i| i.acronym("ABC") } end end end diff --git a/spec/unit/container/configuration_spec.rb b/spec/unit/container/configuration_spec.rb index c67a902e7..5249e72f6 100644 --- a/spec/unit/container/configuration_spec.rb +++ b/spec/unit/container/configuration_spec.rb @@ -175,5 +175,29 @@ def hooks_trace .from([]) .to [:after_configure] end + + it "raises error for undefined constant (due to inflector missing acronym)" do + expect { + container.configure do |config| + config.root = SPEC_ROOT.join("fixtures").realpath + config.component_dirs.add "components" do |dir| + dir.namespaces.add "test", key: nil + end + end + container.finalize! + }.to raise_error(Dry::System::ComponentNotLoadableError) + end + + it "does not raises error for undefined constant when eager_load is false" do + expect { + container.configure do |config| + config.root = SPEC_ROOT.join("fixtures").realpath + config.component_dirs.add "components" do |dir| + dir.namespaces.add "test", key: nil + end + end + container.finalize!(eager_load: false) + }.to_not raise_error + end end end