From f80498a27d6b44f8a91e144fea188c57b0078861 Mon Sep 17 00:00:00 2001 From: alexeypetrushin Date: Mon, 27 Jun 2011 13:54:45 +0400 Subject: [PATCH] refactoring, removing config --- lib/micon/core.rb | 75 +++++++++++++++++++++------------------ spec/micelaneous_spec.rb | 57 ++++++++++++++++------------- spec/static_scope_spec.rb | 6 ++-- 3 files changed, 76 insertions(+), 62 deletions(-) diff --git a/lib/micon/core.rb b/lib/micon/core.rb index a2cb482..e5fe8ea 100644 --- a/lib/micon/core.rb +++ b/lib/micon/core.rb @@ -296,6 +296,7 @@ def initialize! # I intentially broke the Metadata incapsulation to provide better performance, don't refactor it. @registry = {} # @loaded_classes, @constants = {}, {} @metadata = Micon::Metadata.new(@registry) + @stack = {} @application, @custom_scopes = {}, {} @@ -333,44 +334,50 @@ def autoload_component_definition key, bang = true def create_object key, container = nil initializer, dependencies = @metadata.initializers[key] raise "no initializer for :#{key} component!" unless initializer - - dependencies.each{|d| self[d]} - @metadata.call_before key - - if container - unless o = container[key] - o = initializer.call - container[key] = o + + raise "component :#{key} used before it's initialization is finished!" if @stack.include? key + @stack[key] = true + begin + dependencies.each{|d| self[d]} + @metadata.call_before key + + if container + unless o = container[key] + o = initializer.call + container[key] = o + else + # complex case, there's an circular dependency, and the 'o' already has been + # initialized in dependecies or callbacks + # here's the sample case: + # + # app.register :environment, :application do + # p :environment + # 'environment' + # end + # + # app.register :conveyors, :application, depends_on: :environment do + # p :conveyors + # 'conveyors' + # end + # + # app.after :environment do + # app[:conveyors] + # end + # + # app[:conveyors] + + o = container[key] + end else - # complex case, there's an circular dependency, and the 'o' already has been - # initialized in dependecies or callbacks - # here's the sample case: - # - # app.register :environment, :application do - # p :environment - # 'environment' - # end - # - # app.register :conveyors, :application, depends_on: :environment do - # p :conveyors - # 'conveyors' - # end - # - # app.after :environment do - # app[:conveyors] - # end - # - # app[:conveyors] - - o = container[key] + o = initializer.call end - else - o = initializer.call + raise "initializer for component :#{key} returns nill!" unless o + ensure + @stack.delete key end - raise "initializer for component :#{key} returns nill!" unless o - + @metadata.call_after key, o - o + o end def name_hack namespace diff --git a/spec/micelaneous_spec.rb b/spec/micelaneous_spec.rb index abdb860..c48a140 100644 --- a/spec/micelaneous_spec.rb +++ b/spec/micelaneous_spec.rb @@ -3,13 +3,8 @@ describe "Micelaneous" do with_load_path "#{spec_dir}/autoload/lib" - before do - self.micon = Micon::Core.new - end - - after do - remove_constants :TheRouter, :TheRad - end + before{self.micon = Micon::Core.new} + after{remove_constants :TheRouter, :TheRad} describe "autoloading" do it "should autoload component definition" do @@ -22,27 +17,41 @@ # TheRad::TheView.should == "TheView" # end end - - it "should not initialize twice (from error)" do - check = mock - check.should_receive(:environment).once.ordered - check.should_receive(:router).once.ordered - - micon.register :environment do - check.environment - 'environment' + + describe "complex circullar dependencies" do + it "should not initialize twice (from error)" do + micon.register :kit do + micon[:kit] + 'kit' + end + lambda{micon[:kit]}.should raise_error(/component :kit used before it's initialization is finished/) end - micon.register :router, depends_on: :environment do - check.router - 'router' + it "should not initialize twice if called from dependency (from error)" do + micon.register :environment do + micon[:router] + 'environment' + end + + micon.register :router, depends_on: :environment do + 'router' + end + + -> {micon[:router]}.should raise_error(/component :router used before it's initialization is finished/) end - micon.after :environment do - # some code that needs :router - micon[:router] - end - micon[:router] + it "should allow to use circullar dependency in :after callback" do + check = mock + check.should_receive(:initialized).once + micon.register :kit do + check.initialized + 'kit' + end + micon.after :kit do + micon[:kit] + end + micon[:kit].should == 'kit' + end end it "helper method generation" do diff --git a/spec/static_scope_spec.rb b/spec/static_scope_spec.rb index 2fe0ce8..ae0cc3e 100644 --- a/spec/static_scope_spec.rb +++ b/spec/static_scope_spec.rb @@ -1,13 +1,11 @@ require 'spec_helper' describe "Application and Instance scopes" do - before do - self.micon = Micon::Core.new - end + before{self.micon = Micon::Core.new} it "dependencies" do micon.register(:another_object, depends_on: :the_object){"another_object"} - -> {micon[:another_object]}.should raise_error(/the_object/) + -> {micon[:another_object]}.should raise_error(/the_object.*not managed/) micon.register(:the_object){"the_object"} micon[:another_object] end