diff options
Diffstat (limited to 'spec/ruby/core/kernel/shared/require.rb')
| -rw-r--r-- | spec/ruby/core/kernel/shared/require.rb | 362 |
1 files changed, 222 insertions, 140 deletions
diff --git a/spec/ruby/core/kernel/shared/require.rb b/spec/ruby/core/kernel/shared/require.rb index b502476bc3..6272b00665 100644 --- a/spec/ruby/core/kernel/shared/require.rb +++ b/spec/ruby/core/kernel/shared/require.rb @@ -2,26 +2,26 @@ describe :kernel_require_basic, shared: true do describe "(path resolution)" do it "loads an absolute path" do path = File.expand_path "load_fixture.rb", CODE_LOADING_DIR - @object.send(@method, path).should be_true + @object.send(@method, path).should == true ScratchPad.recorded.should == [:loaded] end it "loads a non-canonical absolute path" do path = File.join CODE_LOADING_DIR, "..", "code", "load_fixture.rb" - @object.send(@method, path).should be_true + @object.send(@method, path).should == true ScratchPad.recorded.should == [:loaded] end it "loads a file defining many methods" do path = File.expand_path "methods_fixture.rb", CODE_LOADING_DIR - @object.send(@method, path).should be_true + @object.send(@method, path).should == true ScratchPad.recorded.should == [:loaded] end it "raises a LoadError if the file does not exist" do path = File.expand_path "nonexistent.rb", CODE_LOADING_DIR - File.exist?(path).should be_false - lambda { @object.send(@method, path) }.should raise_error(LoadError) + File.should_not.exist?(path) + -> { @object.send(@method, path) }.should.raise(LoadError) ScratchPad.recorded.should == [] end @@ -41,8 +41,8 @@ describe :kernel_require_basic, shared: true do end it "raises a LoadError" do - File.exist?(@path).should be_true - lambda { @object.send(@method, @path) }.should raise_error(LoadError) + File.should.exist?(@path) + -> { @object.send(@method, @path) }.should.raise(LoadError) end end end @@ -52,24 +52,24 @@ describe :kernel_require_basic, shared: true do path = File.expand_path "load_fixture.rb", CODE_LOADING_DIR name = mock("load_fixture.rb mock") name.should_receive(:to_str).and_return(path) - @object.send(@method, name).should be_true + @object.send(@method, name).should == true ScratchPad.recorded.should == [:loaded] end it "raises a TypeError if passed nil" do - lambda { @object.send(@method, nil) }.should raise_error(TypeError) + -> { @object.send(@method, nil) }.should.raise(TypeError) end - it "raises a TypeError if passed a Fixnum" do - lambda { @object.send(@method, 42) }.should raise_error(TypeError) + it "raises a TypeError if passed an Integer" do + -> { @object.send(@method, 42) }.should.raise(TypeError) end it "raises a TypeError if passed an Array" do - lambda { @object.send(@method, []) }.should raise_error(TypeError) + -> { @object.send(@method, []) }.should.raise(TypeError) end it "raises a TypeError if passed an object that does not provide #to_str" do - lambda { @object.send(@method, mock("not a filename")) }.should raise_error(TypeError) + -> { @object.send(@method, mock("not a filename")) }.should.raise(TypeError) end it "raises a TypeError if passed an object that has #to_s but not #to_str" do @@ -77,14 +77,14 @@ describe :kernel_require_basic, shared: true do name.stub!(:to_s).and_return("load_fixture.rb") $LOAD_PATH << "." Dir.chdir CODE_LOADING_DIR do - lambda { @object.send(@method, name) }.should raise_error(TypeError) + -> { @object.send(@method, name) }.should.raise(TypeError) end end it "raises a TypeError if #to_str does not return a String" do name = mock("#to_str returns nil") name.should_receive(:to_str).at_least(1).times.and_return(nil) - lambda { @object.send(@method, name) }.should raise_error(TypeError) + -> { @object.send(@method, name) }.should.raise(TypeError) end it "calls #to_path on non-String objects" do @@ -92,7 +92,7 @@ describe :kernel_require_basic, shared: true do name.stub!(:to_path).and_return("load_fixture.rb") $LOAD_PATH << "." Dir.chdir CODE_LOADING_DIR do - @object.send(@method, name).should be_true + @object.send(@method, name).should == true end ScratchPad.recorded.should == [:loaded] end @@ -101,7 +101,7 @@ describe :kernel_require_basic, shared: true do path = File.expand_path "load_fixture.rb", CODE_LOADING_DIR str = mock("load_fixture.rb mock") str.should_receive(:to_path).and_return(path) - @object.send(@method, str).should be_true + @object.send(@method, str).should == true ScratchPad.recorded.should == [:loaded] end @@ -111,21 +111,21 @@ describe :kernel_require_basic, shared: true do to_path = mock("load_fixture_rb #to_path mock") name.should_receive(:to_path).and_return(to_path) to_path.should_receive(:to_str).and_return(path) - @object.send(@method, name).should be_true + @object.send(@method, name).should == true ScratchPad.recorded.should == [:loaded] end # "http://redmine.ruby-lang.org/issues/show/2578" it "loads a ./ relative path from the current working directory with empty $LOAD_PATH" do Dir.chdir CODE_LOADING_DIR do - @object.send(@method, "./load_fixture.rb").should be_true + @object.send(@method, "./load_fixture.rb").should == true end ScratchPad.recorded.should == [:loaded] end it "loads a ../ relative path from the current working directory with empty $LOAD_PATH" do Dir.chdir CODE_LOADING_DIR do - @object.send(@method, "../code/load_fixture.rb").should be_true + @object.send(@method, "../code/load_fixture.rb").should == true end ScratchPad.recorded.should == [:loaded] end @@ -133,7 +133,7 @@ describe :kernel_require_basic, shared: true do it "loads a ./ relative path from the current working directory with non-empty $LOAD_PATH" do $LOAD_PATH << "an_irrelevant_dir" Dir.chdir CODE_LOADING_DIR do - @object.send(@method, "./load_fixture.rb").should be_true + @object.send(@method, "./load_fixture.rb").should == true end ScratchPad.recorded.should == [:loaded] end @@ -141,7 +141,7 @@ describe :kernel_require_basic, shared: true do it "loads a ../ relative path from the current working directory with non-empty $LOAD_PATH" do $LOAD_PATH << "an_irrelevant_dir" Dir.chdir CODE_LOADING_DIR do - @object.send(@method, "../code/load_fixture.rb").should be_true + @object.send(@method, "../code/load_fixture.rb").should == true end ScratchPad.recorded.should == [:loaded] end @@ -149,44 +149,52 @@ describe :kernel_require_basic, shared: true do it "loads a non-canonical path from the current working directory with non-empty $LOAD_PATH" do $LOAD_PATH << "an_irrelevant_dir" Dir.chdir CODE_LOADING_DIR do - @object.send(@method, "../code/../code/load_fixture.rb").should be_true + @object.send(@method, "../code/../code/load_fixture.rb").should == true end ScratchPad.recorded.should == [:loaded] end it "resolves a filename against $LOAD_PATH entries" do $LOAD_PATH << CODE_LOADING_DIR - @object.send(@method, "load_fixture.rb").should be_true + @object.send(@method, "load_fixture.rb").should == true + ScratchPad.recorded.should == [:loaded] + end + + it "accepts an Object with #to_path in $LOAD_PATH" do + obj = mock("to_path") + obj.should_receive(:to_path).at_least(:once).and_return(CODE_LOADING_DIR) + $LOAD_PATH << obj + @object.send(@method, "load_fixture.rb").should == true ScratchPad.recorded.should == [:loaded] end it "does not require file twice after $LOAD_PATH change" do $LOAD_PATH << CODE_LOADING_DIR - @object.require("load_fixture.rb").should be_true - $LOAD_PATH.unshift CODE_LOADING_DIR + "/gem" - @object.require("load_fixture.rb").should be_false + @object.require("load_fixture.rb").should == true + $LOAD_PATH.push CODE_LOADING_DIR + "/gem" + @object.require("load_fixture.rb").should == false ScratchPad.recorded.should == [:loaded] end it "does not resolve a ./ relative path against $LOAD_PATH entries" do $LOAD_PATH << CODE_LOADING_DIR - lambda do + -> do @object.send(@method, "./load_fixture.rb") - end.should raise_error(LoadError) + end.should.raise(LoadError) ScratchPad.recorded.should == [] end it "does not resolve a ../ relative path against $LOAD_PATH entries" do $LOAD_PATH << CODE_LOADING_DIR - lambda do + -> do @object.send(@method, "../code/load_fixture.rb") - end.should raise_error(LoadError) + end.should.raise(LoadError) ScratchPad.recorded.should == [] end it "resolves a non-canonical path against $LOAD_PATH entries" do $LOAD_PATH << File.dirname(CODE_LOADING_DIR) - @object.send(@method, "code/../code/load_fixture.rb").should be_true + @object.send(@method, "code/../code/load_fixture.rb").should == true ScratchPad.recorded.should == [:loaded] end @@ -195,7 +203,7 @@ describe :kernel_require_basic, shared: true do sep = File::Separator + File::Separator path = ["..", "code", "load_fixture.rb"].join(sep) Dir.chdir CODE_LOADING_DIR do - @object.send(@method, path).should be_true + @object.send(@method, path).should == true end ScratchPad.recorded.should == [:loaded] end @@ -204,20 +212,48 @@ end describe :kernel_require, shared: true do describe "(path resolution)" do + it "loads .rb file when passed absolute path without extension" do + path = File.expand_path "load_fixture", CODE_LOADING_DIR + @object.send(@method, path).should == true + # This should _not_ be [:no_ext] + ScratchPad.recorded.should == [:loaded] + end + + platform_is :linux, :darwin do + it "loads c-extension file when passed absolute path without extension when no .rb is present" do + # the error message is specific to what dlerror() returns + path = File.join CODE_LOADING_DIR, "a", "load_fixture" + -> { @object.send(@method, path) }.should.raise(LoadError) + end + end + + platform_is :darwin do + it "loads .bundle file when passed absolute path with .so" do + # the error message is specific to what dlerror() returns + path = File.join CODE_LOADING_DIR, "a", "load_fixture.so" + -> { @object.send(@method, path) }.should.raise(LoadError) + end + end + + it "does not try an extra .rb if the path already ends in .rb" do + path = File.join CODE_LOADING_DIR, "d", "load_fixture.rb" + -> { @object.send(@method, path) }.should.raise(LoadError) + end + # For reference see [ruby-core:24155] in which matz confirms this feature is # intentional for security reasons. it "does not load a bare filename unless the current working directory is in $LOAD_PATH" do Dir.chdir CODE_LOADING_DIR do - lambda { @object.require("load_fixture.rb") }.should raise_error(LoadError) + -> { @object.require("load_fixture.rb") }.should.raise(LoadError) ScratchPad.recorded.should == [] end end it "does not load a relative path unless the current working directory is in $LOAD_PATH" do Dir.chdir File.dirname(CODE_LOADING_DIR) do - lambda do + -> do @object.require("code/load_fixture.rb") - end.should raise_error(LoadError) + end.should.raise(LoadError) ScratchPad.recorded.should == [] end end @@ -225,10 +261,19 @@ describe :kernel_require, shared: true do it "loads a file that recursively requires itself" do path = File.expand_path "recursive_require_fixture.rb", CODE_LOADING_DIR -> { - @object.require(path).should be_true + @object.require(path).should == true }.should complain(/circular require considered harmful/, verbose: true) ScratchPad.recorded.should == [:loaded] end + + it "loads a file concurrently" do + path = File.expand_path "concurrent_require_fixture.rb", CODE_LOADING_DIR + ScratchPad.record(@object) + -> { + @object.require(path) + }.should_not complain(/circular require considered harmful/, verbose: true) + ScratchPad.recorded.join + end end describe "(non-extensioned path)" do @@ -239,16 +284,33 @@ describe :kernel_require, shared: true do end it "loads a .rb extensioned file when a C-extension file exists on an earlier load path" do - @object.require("load_fixture").should be_true + @object.require("load_fixture").should == true ScratchPad.recorded.should == [:loaded] end + + it "does not load a feature twice when $LOAD_PATH has been modified" do + $LOAD_PATH.replace [CODE_LOADING_DIR] + @object.require("load_fixture").should == true + $LOAD_PATH.replace [File.expand_path("b", CODE_LOADING_DIR), CODE_LOADING_DIR] + @object.require("load_fixture").should == false + end + + it "stores the missing path in a LoadError object" do + path = "abcd1234" + + -> { + @object.send(@method, path) + }.should.raise(LoadError) { |e| + e.path.should == path + } + end end describe "(file extensions)" do it "loads a .rb extensioned file when passed a non-extensioned path" do path = File.expand_path "load_fixture", CODE_LOADING_DIR - File.exist?(path).should be_true - @object.require(path).should be_true + File.should.exist?(path) + @object.require(path).should == true ScratchPad.recorded.should == [:loaded] end @@ -258,21 +320,21 @@ describe :kernel_require, shared: true do $LOADED_FEATURES << File.expand_path("load_fixture.so", CODE_LOADING_DIR) $LOADED_FEATURES << File.expand_path("load_fixture.dll", CODE_LOADING_DIR) path = File.expand_path "load_fixture", CODE_LOADING_DIR - @object.require(path).should be_true + @object.require(path).should == true ScratchPad.recorded.should == [:loaded] end it "does not load a C-extension file if a .rb extensioned file is already loaded" do $LOADED_FEATURES << File.expand_path("load_fixture.rb", CODE_LOADING_DIR) path = File.expand_path "load_fixture", CODE_LOADING_DIR - @object.require(path).should be_false + @object.require(path).should == false ScratchPad.recorded.should == [] end it "loads a .rb extensioned file when passed a non-.rb extensioned path" do path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR - File.exist?(path).should be_true - @object.require(path).should be_true + File.should.exist?(path) + @object.require(path).should == true ScratchPad.recorded.should == [:loaded] end @@ -282,14 +344,14 @@ describe :kernel_require, shared: true do $LOADED_FEATURES << File.expand_path("load_fixture.ext.so", CODE_LOADING_DIR) $LOADED_FEATURES << File.expand_path("load_fixture.ext.dll", CODE_LOADING_DIR) path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR - @object.require(path).should be_true + @object.require(path).should == true ScratchPad.recorded.should == [:loaded] end it "does not load a C-extension file if a complex-extensioned .rb file is already loaded" do $LOADED_FEATURES << File.expand_path("load_fixture.ext.rb", CODE_LOADING_DIR) path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR - @object.require(path).should be_false + @object.require(path).should == false ScratchPad.recorded.should == [] end end @@ -300,8 +362,8 @@ describe :kernel_require, shared: true do end it "stores an absolute path" do - @object.require(@path).should be_true - $LOADED_FEATURES.should include(@path) + @object.require(@path).should == true + $LOADED_FEATURES.should.include?(@path) end platform_is_not :windows do @@ -321,20 +383,35 @@ describe :kernel_require, shared: true do it "does not canonicalize the path and stores a path with symlinks" do symlink_path = "#{@symlink_to_code_dir}/load_fixture.rb" canonical_path = "#{CODE_LOADING_DIR}/load_fixture.rb" - @object.require(symlink_path).should be_true + @object.require(symlink_path).should == true ScratchPad.recorded.should == [:loaded] features = $LOADED_FEATURES.select { |path| path.end_with?('load_fixture.rb') } - features.should include(symlink_path) - features.should_not include(canonical_path) + features.should.include?(symlink_path) + features.should_not.include?(canonical_path) end it "stores the same path that __FILE__ returns in the required file" do symlink_path = "#{@symlink_to_code_dir}/load_fixture_and__FILE__.rb" - @object.require(symlink_path).should be_true + @object.require(symlink_path).should == true loaded_feature = $LOADED_FEATURES.last ScratchPad.recorded.should == [loaded_feature] end + + it "requires only once when a new matching file added to path" do + @object.require('load_fixture').should == true + ScratchPad.recorded.should == [:loaded] + + symlink_to_code_dir_two = tmp("codesymlinktwo") + File.symlink("#{CODE_LOADING_DIR}/b", symlink_to_code_dir_two) + begin + $LOAD_PATH.unshift(symlink_to_code_dir_two) + + @object.require('load_fixture').should == false + ensure + rm_r symlink_to_code_dir_two + end + end end describe "with symlinks in the required feature and $LOAD_PATH" do @@ -354,26 +431,13 @@ describe :kernel_require, shared: true do rm_r @dir, @symlink_to_dir end - ruby_version_is ""..."2.4.4" do - it "canonicalizes neither the entry in $LOAD_PATH nor the filename passed to #require" do - $LOAD_PATH.unshift(@symlink_to_dir) - @object.require("symfile").should be_true - loaded_feature = "#{@symlink_to_dir}/symfile.rb" - ScratchPad.recorded.should == [loaded_feature] - $".last.should == loaded_feature - $LOAD_PATH[0].should == @symlink_to_dir - end - end - - ruby_version_is "2.4.4" do - it "canonicalizes the entry in $LOAD_PATH but not the filename passed to #require" do - $LOAD_PATH.unshift(@symlink_to_dir) - @object.require("symfile").should be_true - loaded_feature = "#{@dir}/symfile.rb" - ScratchPad.recorded.should == [loaded_feature] - $".last.should == loaded_feature - $LOAD_PATH[0].should == @symlink_to_dir - end + it "canonicalizes the entry in $LOAD_PATH but not the filename passed to #require" do + $LOAD_PATH.unshift(@symlink_to_dir) + @object.require("symfile").should == true + loaded_feature = "#{@dir}/symfile.rb" + ScratchPad.recorded.should == [loaded_feature] + $".last.should == loaded_feature + $LOAD_PATH[0].should == @symlink_to_dir end end end @@ -381,20 +445,20 @@ describe :kernel_require, shared: true do it "does not store the path if the load fails" do $LOAD_PATH << CODE_LOADING_DIR saved_loaded_features = $LOADED_FEATURES.dup - lambda { @object.require("raise_fixture.rb") }.should raise_error(RuntimeError) + -> { @object.require("raise_fixture.rb") }.should.raise(RuntimeError) $LOADED_FEATURES.should == saved_loaded_features end it "does not load an absolute path that is already stored" do $LOADED_FEATURES << @path - @object.require(@path).should be_false + @object.require(@path).should == false ScratchPad.recorded.should == [] end it "does not load a ./ relative path that is already stored" do $LOADED_FEATURES << "./load_fixture.rb" Dir.chdir CODE_LOADING_DIR do - @object.require("./load_fixture.rb").should be_false + @object.require("./load_fixture.rb").should == false end ScratchPad.recorded.should == [] end @@ -402,7 +466,7 @@ describe :kernel_require, shared: true do it "does not load a ../ relative path that is already stored" do $LOADED_FEATURES << "../load_fixture.rb" Dir.chdir CODE_LOADING_DIR do - @object.require("../load_fixture.rb").should be_false + @object.require("../load_fixture.rb").should == false end ScratchPad.recorded.should == [] end @@ -410,27 +474,27 @@ describe :kernel_require, shared: true do it "does not load a non-canonical path that is already stored" do $LOADED_FEATURES << "code/../code/load_fixture.rb" $LOAD_PATH << File.dirname(CODE_LOADING_DIR) - @object.require("code/../code/load_fixture.rb").should be_false + @object.require("code/../code/load_fixture.rb").should == false ScratchPad.recorded.should == [] end it "respects being replaced with a new array" do prev = $LOADED_FEATURES.dup - @object.require(@path).should be_true - $LOADED_FEATURES.should include(@path) + @object.require(@path).should == true + $LOADED_FEATURES.should.include?(@path) $LOADED_FEATURES.replace(prev) - $LOADED_FEATURES.should_not include(@path) - @object.require(@path).should be_true - $LOADED_FEATURES.should include(@path) + $LOADED_FEATURES.should_not.include?(@path) + @object.require(@path).should == true + $LOADED_FEATURES.should.include?(@path) end it "does not load twice the same file with and without extension" do $LOAD_PATH << CODE_LOADING_DIR - @object.require("load_fixture.rb").should be_true - @object.require("load_fixture").should be_false + @object.require("load_fixture.rb").should == true + @object.require("load_fixture").should == false end describe "when a non-extensioned file is in $LOADED_FEATURES" do @@ -440,19 +504,19 @@ describe :kernel_require, shared: true do it "loads a .rb extensioned file when a non extensioned file is in $LOADED_FEATURES" do $LOAD_PATH << CODE_LOADING_DIR - @object.require("load_fixture").should be_true + @object.require("load_fixture").should == true ScratchPad.recorded.should == [:loaded] end it "loads a .rb extensioned file from a subdirectory" do $LOAD_PATH << File.dirname(CODE_LOADING_DIR) - @object.require("code/load_fixture").should be_true + @object.require("code/load_fixture").should == true ScratchPad.recorded.should == [:loaded] end it "returns false if the file is not found" do Dir.chdir File.dirname(CODE_LOADING_DIR) do - @object.require("load_fixture").should be_false + @object.require("load_fixture").should == false ScratchPad.recorded.should == [] end end @@ -460,7 +524,7 @@ describe :kernel_require, shared: true do it "returns false when passed a path and the file is not found" do $LOADED_FEATURES << "code/load_fixture" Dir.chdir CODE_LOADING_DIR do - @object.require("code/load_fixture").should be_false + @object.require("code/load_fixture").should == false ScratchPad.recorded.should == [] end end @@ -468,16 +532,16 @@ describe :kernel_require, shared: true do it "stores ../ relative paths as absolute paths" do Dir.chdir CODE_LOADING_DIR do - @object.require("../code/load_fixture.rb").should be_true + @object.require("../code/load_fixture.rb").should == true end - $LOADED_FEATURES.should include(@path) + $LOADED_FEATURES.should.include?(@path) end it "stores ./ relative paths as absolute paths" do Dir.chdir CODE_LOADING_DIR do - @object.require("./load_fixture.rb").should be_true + @object.require("./load_fixture.rb").should == true end - $LOADED_FEATURES.should include(@path) + $LOADED_FEATURES.should.include?(@path) end it "collapses duplicate path separators" do @@ -485,27 +549,27 @@ describe :kernel_require, shared: true do sep = File::Separator + File::Separator path = ["..", "code", "load_fixture.rb"].join(sep) Dir.chdir CODE_LOADING_DIR do - @object.require(path).should be_true + @object.require(path).should == true end - $LOADED_FEATURES.should include(@path) + $LOADED_FEATURES.should.include?(@path) end it "expands absolute paths containing .." do path = File.join CODE_LOADING_DIR, "..", "code", "load_fixture.rb" - @object.require(path).should be_true - $LOADED_FEATURES.should include(@path) + @object.require(path).should == true + $LOADED_FEATURES.should.include?(@path) end it "adds the suffix of the resolved filename" do $LOAD_PATH << CODE_LOADING_DIR - @object.require("load_fixture").should be_true - $LOADED_FEATURES.should include(@path) + @object.require("load_fixture").should == true + $LOADED_FEATURES.should.include?(@path) end it "does not load a non-canonical path for a file already loaded" do $LOADED_FEATURES << @path $LOAD_PATH << File.dirname(CODE_LOADING_DIR) - @object.require("code/../code/load_fixture.rb").should be_false + @object.require("code/../code/load_fixture.rb").should == false ScratchPad.recorded.should == [] end @@ -513,7 +577,7 @@ describe :kernel_require, shared: true do $LOADED_FEATURES << @path $LOAD_PATH << "an_irrelevant_dir" Dir.chdir CODE_LOADING_DIR do - @object.require("./load_fixture.rb").should be_false + @object.require("./load_fixture.rb").should == false end ScratchPad.recorded.should == [] end @@ -522,37 +586,35 @@ describe :kernel_require, shared: true do $LOADED_FEATURES << @path $LOAD_PATH << "an_irrelevant_dir" Dir.chdir CODE_LOADING_DIR do - @object.require("../code/load_fixture.rb").should be_false + @object.require("../code/load_fixture.rb").should == false end ScratchPad.recorded.should == [] end - ruby_version_is ""..."2.5" do - it "complex, enumerator, rational, thread and unicode_normalize are already required" do - provided = %w[complex enumerator rational thread unicode_normalize] - features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems') - provided.each { |feature| - features.should =~ /\b#{feature}\.(rb|so|jar)$/ - } + it "unicode_normalize is part of core and not $LOADED_FEATURES" do + features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems') + features.lines.each { |feature| + feature.should_not.include?("unicode_normalize") + } - code = provided.map { |f| "puts require #{f.inspect}\n" }.join - required = ruby_exe(code, options: '--disable-gems') - required.should == "false\n" * provided.size - end + -> { @object.require("unicode_normalize") }.should.raise(LoadError) end - ruby_version_is "2.5" do - it "complex, enumerator, rational and thread are already required" do - provided = %w[complex enumerator rational thread] - features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems') - provided.each { |feature| - features.should =~ /\b#{feature}\.(rb|so|jar)$/ - } - - code = provided.map { |f| "puts require #{f.inspect}\n" }.join - required = ruby_exe(code, options: '--disable-gems') - required.should == "false\n" * provided.size + it "does not load a file earlier on the $LOAD_PATH when other similar features were already loaded" do + Dir.chdir CODE_LOADING_DIR do + @object.send(@method, "../code/load_fixture").should == true end + ScratchPad.recorded.should == [:loaded] + + $LOAD_PATH.unshift "#{CODE_LOADING_DIR}/b" + # This loads because the above load was not on the $LOAD_PATH + @object.send(@method, "load_fixture").should == true + ScratchPad.recorded.should == [:loaded, :loaded] + + $LOAD_PATH.unshift "#{CODE_LOADING_DIR}/c" + # This does not load because the above load was on the $LOAD_PATH + @object.send(@method, "load_fixture").should == false + ScratchPad.recorded.should == [:loaded, :loaded] end end @@ -569,13 +631,13 @@ describe :kernel_require, shared: true do # "#3171" it "performs tilde expansion on a .rb file before storing paths in $LOADED_FEATURES" do - @object.require("~/load_fixture.rb").should be_true - $LOADED_FEATURES.should include(@path) + @object.require("~/load_fixture.rb").should == true + $LOADED_FEATURES.should.include?(@path) end it "performs tilde expansion on a non-extensioned file before storing paths in $LOADED_FEATURES" do - @object.require("~/load_fixture").should be_true - $LOADED_FEATURES.should include(@path) + @object.require("~/load_fixture").should == true + $LOADED_FEATURES.should.include?(@path) end end @@ -632,8 +694,8 @@ describe :kernel_require, shared: true do t1.join t2.join - t1_res.should be_true - t2_res.should be_false + t1_res.should == true + t2_res.should == false ScratchPad.recorded.should == [:con_pre, :con_post, :t2_post, :t1_post] end @@ -657,8 +719,8 @@ describe :kernel_require, shared: true do t1.join t2.join - t1_res.should be_true - t2_res.should be_true + t1_res.should == true + t2_res.should == true ScratchPad.recorded.should == [:con2_pre, :con3, :con2_post] end @@ -674,9 +736,9 @@ describe :kernel_require, shared: true do Thread.current[:wait_for] = t2 Thread.current[:con_raise] = true - lambda { + -> { @object.require(@path) - }.should raise_error(RuntimeError) + }.should.raise(RuntimeError) Thread.pass until fin ScratchPad.recorded << :t1_post @@ -697,7 +759,7 @@ describe :kernel_require, shared: true do t1.join t2.join - t2_res.should be_true + t2_res.should == true ScratchPad.recorded.should == [:con_pre, :con_pre, :con_post, :t2_post, :t1_post] end @@ -715,9 +777,9 @@ describe :kernel_require, shared: true do t1 = Thread.new do Thread.current[:con_raise] = true - lambda { + -> { @object.require(@path) - }.should raise_error(RuntimeError) + }.should.raise(RuntimeError) raised = true @@ -745,8 +807,8 @@ describe :kernel_require, shared: true do t1.join t2.join - t1_res.should be_false - t2_res.should be_true + t1_res.should == false + t2_res.should == true ScratchPad.recorded.should == [:con_pre, :con_pre, :con_post, :t2_post, :t1_post] end @@ -755,10 +817,30 @@ describe :kernel_require, shared: true do it "stores the missing path in a LoadError object" do path = "abcd1234" - lambda { + -> { @object.send(@method, path) - }.should raise_error(LoadError) { |e| + }.should.raise(LoadError) { |e| e.path.should == path } end + + platform_is :linux, :darwin do + it "does not store the missing path in a LoadError object when c-extension file exists but loading fails and passed absolute path without extension" do + # the error message is specific to what dlerror() returns + path = File.join CODE_LOADING_DIR, "a", "load_fixture" + -> { @object.send(@method, path) }.should.raise(LoadError) { |e| + e.path.should == nil + } + end + end + + platform_is :darwin do + it "does not store the missing path in a LoadError object when c-extension file exists but loading fails and passed absolute path with extension" do + # the error message is specific to what dlerror() returns + path = File.join CODE_LOADING_DIR, "a", "load_fixture.bundle" + -> { @object.send(@method, path) }.should.raise(LoadError) { |e| + e.path.should == nil + } + end + end end |
