1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/spec/bundler/runtime/require_spec.rb
hsbt 8598f8c2dc Merge bundler to standard libraries.
rubygems 2.7.x depends bundler-1.15.x. This is preparation for
  rubygems and bundler migration.

  * lib/bundler.rb, lib/bundler/*: files of bundler-1.15.4
  * spec/bundler/*: rspec examples of bundler-1.15.4. I applied patches.
    * https://github.com/bundler/bundler/pull/6007
    * Exclude not working examples on ruby repository.
    * Fake ruby interpriter instead of installed ruby.
  * Makefile.in: Added test task named `test-bundler`. This task is only
    working macOS/linux yet. I'm going to support Windows environment later.
  * tool/sync_default_gems.rb: Added sync task for bundler.

  [Feature #12733][ruby-core:77172]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59779 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-09-08 08:45:41 +00:00

442 lines
11 KiB
Ruby

# frozen_string_literal: true
require "spec_helper"
RSpec.describe "Bundler.require" do
before :each do
build_lib "one", "1.0.0" do |s|
s.write "lib/baz.rb", "puts 'baz'"
s.write "lib/qux.rb", "puts 'qux'"
end
build_lib "two", "1.0.0" do |s|
s.write "lib/two.rb", "puts 'two'"
s.add_dependency "three", "= 1.0.0"
end
build_lib "three", "1.0.0" do |s|
s.write "lib/three.rb", "puts 'three'"
s.add_dependency "seven", "= 1.0.0"
end
build_lib "four", "1.0.0" do |s|
s.write "lib/four.rb", "puts 'four'"
end
build_lib "five", "1.0.0", :no_default => true do |s|
s.write "lib/mofive.rb", "puts 'five'"
end
build_lib "six", "1.0.0" do |s|
s.write "lib/six.rb", "puts 'six'"
end
build_lib "seven", "1.0.0" do |s|
s.write "lib/seven.rb", "puts 'seven'"
end
build_lib "eight", "1.0.0" do |s|
s.write "lib/eight.rb", "puts 'eight'"
end
build_lib "nine", "1.0.0" do |s|
s.write "lib/nine.rb", "puts 'nine'"
end
build_lib "ten", "1.0.0" do |s|
s.write "lib/ten.rb", "puts 'ten'"
end
gemfile <<-G
path "#{lib_path}"
gem "one", :group => :bar, :require => %w[baz qux]
gem "two"
gem "three", :group => :not
gem "four", :require => false
gem "five"
gem "six", :group => "string"
gem "seven", :group => :not
gem "eight", :require => true, :group => :require_true
env "BUNDLER_TEST" => "nine" do
gem "nine", :require => true
end
gem "ten", :install_if => lambda { ENV["BUNDLER_TEST"] == "ten" }
G
end
it "requires the gems" do
# default group
run "Bundler.require"
expect(out).to eq("two")
# specific group
run "Bundler.require(:bar)"
expect(out).to eq("baz\nqux")
# default and specific group
run "Bundler.require(:default, :bar)"
expect(out).to eq("baz\nqux\ntwo")
# specific group given as a string
run "Bundler.require('bar')"
expect(out).to eq("baz\nqux")
# specific group declared as a string
run "Bundler.require(:string)"
expect(out).to eq("six")
# required in resolver order instead of gemfile order
run("Bundler.require(:not)")
expect(out.split("\n").sort).to eq(%w(seven three))
# test require: true
run "Bundler.require(:require_true)"
expect(out).to eq("eight")
end
it "allows requiring gems with non standard names explicitly" do
run "Bundler.require ; require 'mofive'"
expect(out).to eq("two\nfive")
end
it "allows requiring gems which are scoped by env" do
ENV["BUNDLER_TEST"] = "nine"
run "Bundler.require"
expect(out).to eq("two\nnine")
end
it "allows requiring gems which are scoped by install_if" do
ENV["BUNDLER_TEST"] = "ten"
run "Bundler.require"
expect(out).to eq("two\nten")
end
it "raises an exception if a require is specified but the file does not exist" do
gemfile <<-G
path "#{lib_path}"
gem "two", :require => 'fail'
G
load_error_run <<-R, "fail"
Bundler.require
R
expect(err).to eq_err("ZOMG LOAD ERROR")
end
it "displays a helpful message if the required gem throws an error" do
build_lib "faulty", "1.0.0" do |s|
s.write "lib/faulty.rb", "raise RuntimeError.new(\"Gem Internal Error Message\")"
end
gemfile <<-G
path "#{lib_path}"
gem "faulty"
G
run "Bundler.require"
expect(err).to match("error while trying to load the gem 'faulty'")
expect(err).to match("Gem Internal Error Message")
end
it "doesn't swallow the error when the library has an unrelated error" do
build_lib "loadfuuu", "1.0.0" do |s|
s.write "lib/loadfuuu.rb", "raise LoadError.new(\"cannot load such file -- load-bar\")"
end
gemfile <<-G
path "#{lib_path}"
gem "loadfuuu"
G
cmd = <<-RUBY
begin
Bundler.require
rescue LoadError => e
$stderr.puts "ZOMG LOAD ERROR: \#{e.message}"
end
RUBY
run(cmd)
expect(err).to eq_err("ZOMG LOAD ERROR: cannot load such file -- load-bar")
end
describe "with namespaced gems" do
before :each do
build_lib "jquery-rails", "1.0.0" do |s|
s.write "lib/jquery/rails.rb", "puts 'jquery/rails'"
end
lib_path("jquery-rails-1.0.0/lib/jquery-rails.rb").rmtree
end
it "requires gem names that are namespaced" do
gemfile <<-G
path '#{lib_path}'
gem 'jquery-rails'
G
run "Bundler.require"
expect(out).to eq("jquery/rails")
end
it "silently passes if the require fails" do
build_lib "bcrypt-ruby", "1.0.0", :no_default => true do |s|
s.write "lib/brcrypt.rb", "BCrypt = '1.0.0'"
end
gemfile <<-G
path "#{lib_path}"
gem "bcrypt-ruby"
G
cmd = <<-RUBY
require 'bundler'
Bundler.require
RUBY
ruby(cmd)
expect(err).to lack_errors
end
it "does not mangle explicitly given requires" do
gemfile <<-G
path "#{lib_path}"
gem 'jquery-rails', :require => 'jquery-rails'
G
load_error_run <<-R, "jquery-rails"
Bundler.require
R
expect(err).to eq_err("ZOMG LOAD ERROR")
end
it "handles the case where regex fails" do
build_lib "load-fuuu", "1.0.0" do |s|
s.write "lib/load-fuuu.rb", "raise LoadError.new(\"Could not open library 'libfuuu-1.0': libfuuu-1.0: cannot open shared object file: No such file or directory.\")"
end
gemfile <<-G
path "#{lib_path}"
gem "load-fuuu"
G
cmd = <<-RUBY
begin
Bundler.require
rescue LoadError => e
$stderr.puts "ZOMG LOAD ERROR" if e.message.include?("Could not open library 'libfuuu-1.0'")
end
RUBY
run(cmd)
expect(err).to eq_err("ZOMG LOAD ERROR")
end
it "doesn't swallow the error when the library has an unrelated error" do
build_lib "load-fuuu", "1.0.0" do |s|
s.write "lib/load/fuuu.rb", "raise LoadError.new(\"cannot load such file -- load-bar\")"
end
lib_path("load-fuuu-1.0.0/lib/load-fuuu.rb").rmtree
gemfile <<-G
path "#{lib_path}"
gem "load-fuuu"
G
cmd = <<-RUBY
begin
Bundler.require
rescue LoadError => e
$stderr.puts "ZOMG LOAD ERROR: \#{e.message}"
end
RUBY
run(cmd)
expect(err).to eq_err("ZOMG LOAD ERROR: cannot load such file -- load-bar")
end
end
describe "using bundle exec" do
it "requires the locked gems" do
bundle "exec ruby -e 'Bundler.require'"
expect(out).to eq("two")
bundle "exec ruby -e 'Bundler.require(:bar)'"
expect(out).to eq("baz\nqux")
bundle "exec ruby -e 'Bundler.require(:default, :bar)'"
expect(out).to eq("baz\nqux\ntwo")
end
end
describe "order" do
before(:each) do
build_lib "one", "1.0.0" do |s|
s.write "lib/one.rb", <<-ONE
if defined?(Two)
Two.two
else
puts "two_not_loaded"
end
puts 'one'
ONE
end
build_lib "two", "1.0.0" do |s|
s.write "lib/two.rb", <<-TWO
module Two
def self.two
puts 'module_two'
end
end
puts 'two'
TWO
end
end
it "works when the gems are in the Gemfile in the correct order" do
gemfile <<-G
path "#{lib_path}"
gem "two"
gem "one"
G
run "Bundler.require"
expect(out).to eq("two\nmodule_two\none")
end
describe "a gem with different requires for different envs" do
before(:each) do
build_gem "multi_gem", :to_system => true do |s|
s.write "lib/one.rb", "puts 'ONE'"
s.write "lib/two.rb", "puts 'TWO'"
end
install_gemfile <<-G
gem "multi_gem", :require => "one", :group => :one
gem "multi_gem", :require => "two", :group => :two
G
end
it "requires both with Bundler.require(both)" do
run "Bundler.require(:one, :two)"
expect(out).to eq("ONE\nTWO")
end
it "requires one with Bundler.require(:one)" do
run "Bundler.require(:one)"
expect(out).to eq("ONE")
end
it "requires :two with Bundler.require(:two)" do
run "Bundler.require(:two)"
expect(out).to eq("TWO")
end
end
it "fails when the gems are in the Gemfile in the wrong order" do
gemfile <<-G
path "#{lib_path}"
gem "one"
gem "two"
G
run "Bundler.require"
expect(out).to eq("two_not_loaded\none\ntwo")
end
describe "with busted gems" do
it "should be busted" do
build_gem "busted_require", :to_system => true do |s|
s.write "lib/busted_require.rb", "require 'no_such_file_omg'"
end
install_gemfile <<-G
gem "busted_require"
G
load_error_run <<-R, "no_such_file_omg"
Bundler.require
R
expect(err).to eq_err("ZOMG LOAD ERROR")
end
end
end
it "does not load rubygems gemspecs that are used", :rubygems => ">= 2.5.2" do
install_gemfile! <<-G
source "file://#{gem_repo1}"
gem "rack"
G
run! <<-R
path = File.join(Gem.dir, "specifications", "rack-1.0.0.gemspec")
contents = File.read(path)
contents = contents.lines.to_a.insert(-2, "\n raise 'broken gemspec'\n").join
File.open(path, "w") do |f|
f.write contents
end
R
run! <<-R
Bundler.require
puts "WIN"
R
expect(out).to eq("WIN")
end
it "does not load git gemspecs that are used", :rubygems => ">= 2.5.2" do
build_git "foo"
install_gemfile! <<-G
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
run! <<-R
path = Gem.loaded_specs["foo"].loaded_from
contents = File.read(path)
contents = contents.lines.to_a.insert(-2, "\n raise 'broken gemspec'\n").join
File.open(path, "w") do |f|
f.write contents
end
R
run! <<-R
Bundler.require
puts "WIN"
R
expect(out).to eq("WIN")
end
end
RSpec.describe "Bundler.require with platform specific dependencies" do
it "does not require the gems that are pinned to other platforms" do
install_gemfile <<-G
source "file://#{gem_repo1}"
platforms :#{not_local_tag} do
gem "fail", :require => "omgomg"
end
gem "rack", "1.0.0"
G
run "Bundler.require"
expect(err).to lack_errors
end
it "requires gems pinned to multiple platforms, including the current one" do
install_gemfile <<-G
source "file://#{gem_repo1}"
platforms :#{not_local_tag}, :#{local_tag} do
gem "rack", :require => "rack"
end
G
run "Bundler.require; puts RACK"
expect(out).to eq("1.0.0")
expect(err).to lack_errors
end
end