require "#{File.dirname __FILE__}/helper" require "vresource/class_loader" describe "ClassLoader" do ClassLoader = VResource::ClassLoader before :all do @original_dir = "#{File.dirname(__FILE__)}/class_loader_spec_data" @dir = "#{File.dirname(__FILE__)}/class_loader_spec" FileUtils.rm_r @dir if File.exist? @dir FileUtils.cp_r @original_dir, @dir @provider = VResource::FileSystemProvider.new(@dir) VResource.add_resource_provider @provider VResource.hook! end after :all do VResource.unhook! FileUtils.rm_r @dir if File.exist? @dir [:LoadCount, :ModuleA, :ScopeA].each{|c| Object.send :remove_const, c if Object.const_defined? c} end it "should load classes only one time" do class CustomObserver attr_reader :list def initialize @list = [] end def update_class klass @list << klass end end obs = CustomObserver.new ClassLoader.add_observer obs ::LoadCount ::LoadCount ClassLoader.delete_observers obs.list.inject(0){|count, klass| klass == ::LoadCount ? count + 1 : count}.should == 1 end it "should load classes from multiple directories" it "class should have the same name as package" do ::ModuleA::SameName ::ModuleA::SameName::SomeClass end it "infinity loop" do lambda{ModuleA::InfinityLoop}.should raise_error(/Class Name .+ doesn't correspond to File Name/) end it "core" do ::ModuleA::ModuleB::ClassC.new end module ::ModuleA class << self def anonymous ClassInsideAnonymousClass end end end it "Should works inside Anonymous Class" do ::ModuleA.anonymous end it "should raise exception if class isn't defined in scope" do ::ScopeA::ScopeA1 ClassLoader.error_on_defined_constant = true lambda{::ScopeA::ScopeB1}.should raise_error(/Class '.+' is not defined in the '.+' Namespace!/) end it "Class Reloading" do fname = "#{@dir}/ModuleA/ClassReloading.rb" File.write fname, %{\ class ClassReloading def test 1 end end} test = ::ModuleA::ClassReloading.new test.test.should == 1 File.write fname, %{\ class ClassReloading def test 2 end end} ClassLoader.reload_class(::ModuleA::ClassReloading.name) test.test.should == 2 end end