diff options
Diffstat (limited to 'spec/ruby/core/kernel/shared/load.rb')
| -rw-r--r-- | spec/ruby/core/kernel/shared/load.rb | 147 |
1 files changed, 112 insertions, 35 deletions
diff --git a/spec/ruby/core/kernel/shared/load.rb b/spec/ruby/core/kernel/shared/load.rb index b479b29399..20d23a623e 100644 --- a/spec/ruby/core/kernel/shared/load.rb +++ b/spec/ruby/core/kernel/shared/load.rb @@ -1,3 +1,6 @@ +main = self + +# The big difference is Kernel#load does not attempt to add an extension to the passed path, unlike Kernel#require describe :kernel_load, shared: true do before :each do CodeLoadingSpecs.spec_setup @@ -8,100 +11,141 @@ describe :kernel_load, shared: true do CodeLoadingSpecs.spec_cleanup end - it "loads a non-extensioned file as a Ruby source file" do - path = File.expand_path "load_fixture", CODE_LOADING_DIR - @object.load(path).should be_true - ScratchPad.recorded.should == [:no_ext] - end + describe "(path resolution)" do + # This behavior is specific to Kernel#load, it differs for Kernel#require + it "loads a non-extensioned file as a Ruby source file" do + path = File.expand_path "load_fixture", CODE_LOADING_DIR + @object.load(path).should == true + ScratchPad.recorded.should == [:no_ext] + end - it "loads a non .rb extensioned file as a Ruby source file" do - path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR - @object.load(path).should be_true - ScratchPad.recorded.should == [:no_rb_ext] - end + it "loads a non .rb extensioned file as a Ruby source file" do + path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR + @object.load(path).should == true + ScratchPad.recorded.should == [:no_rb_ext] + end - it "loads from the current working directory" do - Dir.chdir CODE_LOADING_DIR do - @object.load("load_fixture.rb").should be_true - ScratchPad.recorded.should == [:loaded] + it "loads from the current working directory" do + Dir.chdir CODE_LOADING_DIR do + @object.load("load_fixture.rb").should == true + ScratchPad.recorded.should == [:loaded] + end + end + + # This behavior is specific to Kernel#load, it differs for Kernel#require + it "does not look for a c-extension file when passed a path without extension (when no .rb is present)" do + path = File.join CODE_LOADING_DIR, "a", "load_fixture" + -> { @object.send(@method, path) }.should.raise(LoadError) end end it "loads a file that recursively requires itself" do path = File.expand_path "recursive_require_fixture.rb", CODE_LOADING_DIR -> { - @object.load(path).should be_true + @object.load(path).should == true }.should complain(/circular require considered harmful/, verbose: true) ScratchPad.recorded.should == [:loaded, :loaded] end it "loads a file that recursively loads itself" do path = File.expand_path "recursive_load_fixture.rb", CODE_LOADING_DIR - @object.load(path).should be_true + @object.load(path).should == true ScratchPad.recorded.should == [:loaded, :loaded] end it "loads a file each time the method is called" do - @object.load(@path).should be_true - @object.load(@path).should be_true + @object.load(@path).should == true + @object.load(@path).should == true ScratchPad.recorded.should == [:loaded, :loaded] end it "loads a file even when the name appears in $LOADED_FEATURES" do $LOADED_FEATURES << @path - @object.load(@path).should be_true + @object.load(@path).should == true ScratchPad.recorded.should == [:loaded] end it "loads a file that has been loaded by #require" do - @object.require(@path).should be_true - @object.load(@path).should be_true + @object.require(@path).should == true + @object.load(@path).should == true ScratchPad.recorded.should == [:loaded, :loaded] end it "loads file even after $LOAD_PATH change" do $LOAD_PATH << CODE_LOADING_DIR - @object.load("load_fixture.rb").should be_true + @object.load("load_fixture.rb").should == true $LOAD_PATH.unshift CODE_LOADING_DIR + "/gem" - @object.load("load_fixture.rb").should be_true + @object.load("load_fixture.rb").should == true ScratchPad.recorded.should == [:loaded, :loaded_gem] end it "does not cause #require with the same path to fail" do - @object.load(@path).should be_true - @object.require(@path).should be_true + @object.load(@path).should == true + @object.require(@path).should == true ScratchPad.recorded.should == [:loaded, :loaded] end it "does not add the loaded path to $LOADED_FEATURES" do saved_loaded_features = $LOADED_FEATURES.dup - @object.load(@path).should be_true + @object.load(@path).should == true $LOADED_FEATURES.should == saved_loaded_features end it "raises a LoadError if passed a non-extensioned path that does not exist but a .rb extensioned path does exist" do path = File.expand_path "load_ext_fixture", CODE_LOADING_DIR - lambda { @object.load(path) }.should raise_error(LoadError) + -> { @object.load(path) }.should.raise(LoadError) end describe "when passed true for 'wrap'" do it "loads from an existing path" do - path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR - @object.load(path, true).should be_true + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR + @object.load(path, true).should == true end it "sets the enclosing scope to an anonymous module" do - path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR @object.load(path, true) - Object.const_defined?(:LoadSpecWrap).should be_false + Object.const_defined?(:LoadSpecWrap).should == false + + wrap_module = ScratchPad.recorded[1] + wrap_module.should.instance_of?(Module) end it "allows referencing outside namespaces" do - path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR + @object.load(path, true) + + ScratchPad.recorded[0].should.equal?(String) + end + + it "sets self as a copy of the top-level main" do + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR + @object.load(path, true) + + top_level = ScratchPad.recorded[2] + top_level.to_s.should == "main" + top_level.method(:to_s).owner.should == top_level.singleton_class + top_level.should_not.equal?(main) + top_level.should.instance_of?(Object) + end + + it "includes modules included in main's singleton class in self's class" do + mod = Module.new + main.extend(mod) + + main_ancestors = main.singleton_class.ancestors[1..-1] + main_ancestors.first.should == mod + + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR @object.load(path, true) - ScratchPad.recorded.first.should be_an_instance_of(Class) + top_level = ScratchPad.recorded[2] + top_level_ancestors = top_level.singleton_class.ancestors[-main_ancestors.size..-1] + top_level_ancestors.should == main_ancestors + + wrap_module = ScratchPad.recorded[1] + top_level.singleton_class.ancestors.should == [top_level.singleton_class, wrap_module, *main_ancestors] end describe "with top-level methods" do @@ -115,11 +159,44 @@ describe :kernel_load, shared: true do end it "does not pollute the receiver" do - lambda { @object.send(:top_level_method) }.should raise_error(NameError) + -> { @object.send(:top_level_method) }.should.raise(NameError) end end end + describe "when passed a module for 'wrap'" do + it "sets the enclosing scope to the supplied module" do + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR + mod = Module.new + @object.load(path, mod) + + Object.const_defined?(:LoadSpecWrap).should == false + mod.const_defined?(:LoadSpecWrap).should == true + + wrap_module = ScratchPad.recorded[1] + wrap_module.should == mod + end + + it "makes constants and instance methods in the source file reachable with the supplied module" do + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR + mod = Module.new + @object.load(path, mod) + + mod::LOAD_WRAP_SPECS_TOP_LEVEL_CONSTANT.should == 1 + obj = Object.new + obj.extend(mod) + obj.send(:load_wrap_specs_top_level_method).should == :load_wrap_specs_top_level_method + end + + it "makes instance methods in the source file private" do + path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR + mod = Module.new + @object.load(path, mod) + + mod.private_instance_methods.include?(:load_wrap_specs_top_level_method).should == true + end + end + describe "(shell expansion)" do before :each do @env_home = ENV["HOME"] @@ -131,7 +208,7 @@ describe :kernel_load, shared: true do end it "expands a tilde to the HOME environment variable as the path to load" do - @object.require("~/load_fixture.rb").should be_true + @object.require("~/load_fixture.rb").should == true ScratchPad.recorded.should == [:loaded] end end |
