1require 'rubygems/test_case'
2require 'rubygems'
3
4class TestGemRequire < Gem::TestCase
5
6  def setup
7    super
8
9    assert_raises LoadError do
10      save_loaded_features do
11        require 'test_gem_require_a'
12      end
13    end
14  end
15
16  def assert_require(path)
17    assert require(path), "'#{path}' was already required"
18  end
19
20  def test_require_is_not_lazy_with_exact_req
21    a1 = new_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb"
22    b1 = new_spec "b", "1", nil, "lib/b/c.rb"
23    b2 = new_spec "b", "2", nil, "lib/b/c.rb"
24
25    install_specs a1, b1, b2
26
27    save_loaded_features do
28      assert_require 'test_gem_require_a'
29      assert_equal %w(a-1 b-1), loaded_spec_names
30      assert_equal unresolved_names, []
31
32      assert_require "b/c"
33      assert_equal %w(a-1 b-1), loaded_spec_names
34    end
35  end
36
37  def test_require_is_lazy_with_inexact_req
38    a1 = new_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb"
39    b1 = new_spec "b", "1", nil, "lib/b/c.rb"
40    b2 = new_spec "b", "2", nil, "lib/b/c.rb"
41
42    install_specs a1, b1, b2
43
44    save_loaded_features do
45      assert_require 'test_gem_require_a'
46      assert_equal %w(a-1), loaded_spec_names
47      assert_equal unresolved_names, ["b (>= 1)"]
48
49      assert_require "b/c"
50      assert_equal %w(a-1 b-2), loaded_spec_names
51    end
52  end
53
54  def test_require_is_not_lazy_with_one_possible
55    a1 = new_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb"
56    b1 = new_spec "b", "1", nil, "lib/b/c.rb"
57
58    install_specs a1, b1
59
60    save_loaded_features do
61      assert_require 'test_gem_require_a'
62      assert_equal %w(a-1 b-1), loaded_spec_names
63      assert_equal unresolved_names, []
64
65      assert_require "b/c"
66      assert_equal %w(a-1 b-1), loaded_spec_names
67    end
68  end
69
70  def test_require_can_use_a_pathname_object
71    a1 = new_spec "a", "1", nil, "lib/test_gem_require_a.rb"
72
73    install_specs a1
74
75    save_loaded_features do
76      assert_require Pathname.new 'test_gem_require_a'
77      assert_equal %w(a-1), loaded_spec_names
78      assert_equal unresolved_names, []
79    end
80  end
81
82  def test_activate_via_require_respects_loaded_files
83    require 'benchmark' # stdlib
84    save_loaded_features do
85      a1 = new_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb"
86      b1 = new_spec "b", "1", nil, "lib/benchmark.rb"
87      b2 = new_spec "b", "2", nil, "lib/benchmark.rb"
88
89      install_specs a1, b1, b2
90
91      require 'test_gem_require_a'
92      assert_equal unresolved_names, ["b (>= 1)"]
93
94      refute require('benchmark'), "benchmark should have already been loaded"
95
96      # We detected that we should activate b-2, so we did so, but
97      # then original_require decided "I've already got benchmark.rb" loaded.
98      # This case is fine because our lazy loading is provided exactly
99      # the same behavior as eager loading would have.
100
101      assert_equal %w(a-1 b-2), loaded_spec_names
102    end
103  end
104
105  def test_already_activated_direct_conflict
106    save_loaded_features do
107      a1 = new_spec "a", "1", { "b" => "> 0" }
108      b1 = new_spec "b", "1", { "c" => ">= 1" }, "lib/ib.rb"
109      b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/ib.rb"
110      c1 = new_spec "c", "1", nil, "lib/d.rb"
111      c2 = new_spec("c", "2", nil, "lib/d.rb")
112
113      install_specs a1, b1, b2, c1, c2
114
115      a1.activate
116      c1.activate
117      assert_equal %w(a-1 c-1), loaded_spec_names
118      assert_equal ["b (> 0)"], unresolved_names
119
120      assert require("ib")
121
122      assert_equal %w(a-1 b-1 c-1), loaded_spec_names
123      assert_equal [], unresolved_names
124    end
125  end
126
127  def test_multiple_gems_with_the_same_path
128    save_loaded_features do
129      a1 = new_spec "a", "1", { "b" => "> 0", "x" => "> 0" }
130      b1 = new_spec "b", "1", { "c" => ">= 1" }, "lib/ib.rb"
131      b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/ib.rb"
132      x1 = new_spec "x", "1", nil, "lib/ib.rb"
133      x2 = new_spec "x", "2", nil, "lib/ib.rb"
134      c1 = new_spec "c", "1", nil, "lib/d.rb"
135      c2 = new_spec("c", "2", nil, "lib/d.rb")
136
137      install_specs a1, b1, b2, c1, c2, x1, x2
138
139      a1.activate
140      c1.activate
141      assert_equal %w(a-1 c-1), loaded_spec_names
142      assert_equal ["b (> 0)", "x (> 0)"], unresolved_names
143
144      e = assert_raises(Gem::LoadError) do
145        require("ib")
146      end
147
148      assert_equal "ib found in multiple gems: b, x", e.message
149    end
150  end
151
152  def test_unable_to_find_good_unresolved_version
153    save_loaded_features do
154      a1 = new_spec "a", "1", { "b" => "> 0" }
155      b1 = new_spec "b", "1", { "c" => ">= 2" }, "lib/ib.rb"
156      b2 = new_spec "b", "2", { "c" => ">= 3" }, "lib/ib.rb"
157
158      c1 = new_spec "c", "1", nil, "lib/d.rb"
159      c2 = new_spec "c", "2", nil, "lib/d.rb"
160      c3 = new_spec "c", "3", nil, "lib/d.rb"
161
162      install_specs a1, b1, b2, c1, c2, c3
163
164      a1.activate
165      c1.activate
166      assert_equal %w(a-1 c-1), loaded_spec_names
167      assert_equal ["b (> 0)"], unresolved_names
168
169      e = assert_raises(Gem::LoadError) do
170        require("ib")
171      end
172
173      assert_equal "unable to find a version of 'b' to activate", e.message
174    end
175  end
176
177  def test_default_gem_only
178    save_loaded_features do
179      default_gem_spec = new_default_spec("default", "2.0.0.0",
180                                          nil, "default/gem.rb")
181      install_default_specs(default_gem_spec)
182      assert_require "default/gem"
183      assert_equal %w(default-2.0.0.0), loaded_spec_names
184    end
185  end
186
187  def test_default_gem_and_normal_gem
188    save_loaded_features do
189      default_gem_spec = new_default_spec("default", "2.0.0.0",
190                                          nil, "default/gem.rb")
191      install_default_specs(default_gem_spec)
192      normal_gem_spec = new_spec("default", "3.0", nil,
193                                 "lib/default/gem.rb")
194      install_specs(normal_gem_spec)
195      assert_require "default/gem"
196      assert_equal %w(default-3.0), loaded_spec_names
197    end
198  end
199
200  def loaded_spec_names
201    Gem.loaded_specs.values.map(&:full_name).sort
202  end
203
204  def unresolved_names
205    Gem::Specification.unresolved_deps.values.map(&:to_s).sort
206  end
207
208  def save_loaded_features
209    old_loaded_features = $LOADED_FEATURES.dup
210    yield
211  ensure
212    $LOADED_FEATURES.replace old_loaded_features
213  end
214
215end
216