"Fossies" - the Fresh Open Source Software Archive 
Member "vagrant-2.2.14/test/unit/vagrant/bundler_test.rb" (20 Nov 2020, 28478 Bytes) of package /linux/misc/vagrant-2.2.14.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Ruby source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the latest
Fossies "Diffs" side-by-side code changes report for "bundler_test.rb":
2.2.13_vs_2.2.14.
1 require "tmpdir"
2 require_relative "../base"
3
4 require "vagrant/bundler"
5
6 describe Vagrant::Bundler::SolutionFile do
7 let(:plugin_path) { Pathname.new(tmpdir) + "plugin_file" }
8 let(:solution_path) { Pathname.new(tmpdir) + "solution_file" }
9 let(:tmpdir) { @tmpdir ||= Dir.mktmpdir("vagrant-bundler-test") }
10 let(:subject) {
11 described_class.new(
12 plugin_file: plugin_path,
13 solution_file: solution_path
14 )
15 }
16
17 after do
18 if @tmpdir
19 FileUtils.rm_rf(@tmpdir)
20 @tmpdir = nil
21 end
22 end
23
24 describe "#initialize" do
25 context "file paths" do
26 context "with solution_file not provided" do
27 let(:subject) { described_class.new(plugin_file: plugin_path) }
28
29 it "should set the plugin_file" do
30 expect(subject.plugin_file.to_s).to eq(plugin_path.to_s)
31 end
32
33 it "should set solution path to same directory" do
34 expect(subject.solution_file.to_s).to eq(plugin_path.to_s + ".sol")
35 end
36 end
37
38 context "with custom solution_file provided" do
39 let(:subject) { described_class.
40 new(plugin_file: plugin_path, solution_file: solution_path) }
41
42 it "should set the plugin file path" do
43 expect(subject.plugin_file.to_s).to eq(plugin_path.to_s)
44 end
45
46 it "should set the solution file path to given value" do
47 expect(subject.solution_file.to_s).to eq(solution_path.to_s)
48 end
49 end
50 end
51
52 context "initialization behavior" do
53 context "on creation" do
54 before { expect_any_instance_of(described_class).to receive(:load) }
55
56 it "should load solution file during initialization" do
57 subject
58 end
59 end
60
61 it "should be invalid by default" do
62 expect(subject.valid?).to be_falsey
63 end
64 end
65 end
66
67 describe "#dependency_list=" do
68 it "should accept a list of Gem::Dependency instances" do
69 list = ["dep1", "dep2"].map{ |x| Gem::Dependency.new(x) }
70 subject.dependency_list = list
71 expect(subject.dependency_list.map(&:dependency)).to eq(list)
72 end
73
74 it "should error if list includes instance not Gem::Dependency" do
75 list = ["dep1", "dep2"].map{ |x| Gem::Dependency.new(x) } << :invalid
76 expect{ subject.dependency_list = list }.to raise_error(TypeError)
77 end
78
79 it "should convert list into resolver dependency request" do
80 list = ["dep1", "dep2"].map{ |x| Gem::Dependency.new(x) }
81 subject.dependency_list = list
82 subject.dependency_list.each do |dep|
83 expect(dep).to be_a(Gem::Resolver::DependencyRequest)
84 end
85 end
86
87 it "should freeze the new dependency list" do
88 list = ["dep1", "dep2"].map{ |x| Gem::Dependency.new(x) }
89 subject.dependency_list = list
90 expect(subject.dependency_list).to be_frozen
91 end
92 end
93
94 describe "#delete!" do
95 context "when file does not exist" do
96 before { subject.solution_file.delete if subject.solution_file.exist? }
97
98 it "should return false" do
99 expect(subject.delete!).to be_falsey
100 end
101
102 it "should not exist" do
103 subject.delete!
104 expect(subject.solution_file.exist?).to be_falsey
105 end
106 end
107
108 context "when file does exist" do
109 before { subject.solution_file.write('x') }
110
111 it "should return true" do
112 expect(subject.delete!).to be_truthy
113 end
114
115 it "should not exist" do
116 expect(subject.solution_file.exist?).to be_truthy
117 subject.delete!
118 expect(subject.solution_file.exist?).to be_falsey
119 end
120 end
121 end
122
123 describe "store!" do
124 context "when plugin file does not exist" do
125 before { subject.plugin_file.delete if subject.plugin_file.exist? }
126
127 it "should return false" do
128 expect(subject.store!).to be_falsey
129 end
130
131 it "should not create a solution file" do
132 subject.store!
133 expect(subject.solution_file.exist?).to be_falsey
134 end
135 end
136
137 context "when plugin file does exist" do
138 before { subject.plugin_file.write("x") }
139
140 it "should return true" do
141 expect(subject.store!).to be_truthy
142 end
143
144 it "should create a solution file" do
145 expect(subject.solution_file.exist?).to be_falsey
146 subject.store!
147 expect(subject.solution_file.exist?).to be_truthy
148 end
149
150 context "stored file" do
151 let(:content) {
152 @content ||= JSON.load(subject.solution_file.read)
153 }
154 before { subject.store! }
155 after { @content = nil }
156
157 it "should store JSON hash" do
158 expect(content).to be_a(Hash)
159 end
160
161 it "should include dependencies key as array value" do
162 expect(content["dependencies"]).to be_a(Array)
163 end
164
165 it "should include checksum key as string value" do
166 expect(content["checksum"]).to be_a(String)
167 end
168
169 it "should include vagrant_version key as string value" do
170 expect(content["vagrant_version"]).to be_a(String)
171 end
172
173 it "should include vagrant_version key that matches current version" do
174 expect(content["vagrant_version"]).to eq(Vagrant::VERSION)
175 end
176 end
177 end
178 end
179
180 describe "behavior" do
181 context "when storing new solution set" do
182 let(:deps) { ["dep1", "dep2"].map{ |n| Gem::Dependency.new(n) } }
183
184 context "when plugin file does not exist" do
185 before { subject.solution_file.delete if subject.solution_file.exist? }
186
187 it "should not create a solution file" do
188 subject.dependency_list = deps
189 subject.store!
190 expect(subject.solution_file.exist?).to be_falsey
191 end
192 end
193
194 context "when plugin file does exist" do
195 before { subject.plugin_file.write("x") }
196
197 it "should create a solution file" do
198 subject.dependency_list = deps
199 subject.store!
200 expect(subject.solution_file.exist?).to be_truthy
201 end
202
203 it "should update solution file instance to valid" do
204 expect(subject.valid?).to be_falsey
205 subject.dependency_list = deps
206 subject.store!
207 expect(subject.valid?).to be_truthy
208 end
209
210 context "when solution file does exist" do
211 before do
212 subject.dependency_list = deps
213 subject.store!
214 end
215
216 it "should be a valid solution" do
217 subject = described_class.new(
218 plugin_file: plugin_path,
219 solution_file: solution_path
220 )
221 expect(subject.valid?).to be_truthy
222 end
223
224 it "should have expected dependency list" do
225 subject = described_class.new(
226 plugin_file: plugin_path,
227 solution_file: solution_path
228 )
229 expect(subject.dependency_list).to eq(deps)
230 end
231
232 context "when plugin file has been changed" do
233 before { subject.plugin_file.write("xy") }
234
235 it "should not be a valid solution" do
236 subject = described_class.new(
237 plugin_file: plugin_path,
238 solution_file: solution_path
239 )
240 expect(subject.valid?).to be_falsey
241 end
242
243 it "should have empty dependency list" do
244 subject = described_class.new(
245 plugin_file: plugin_path,
246 solution_file: solution_path
247 )
248 expect(subject.dependency_list).to be_empty
249 end
250 end
251 end
252 end
253 end
254 end
255
256 describe "#load" do
257 let(:plugin_file_exists) { false }
258 let(:solution_file_exists) { false }
259 let(:plugin_file_path) { "PLUGIN_FILE_PATH" }
260 let(:solution_file_path) { "SOLUTION_FILE_PATH" }
261 let(:plugin_file) { double("plugin-file") }
262 let(:solution_file) { double("solution-file") }
263
264 subject do
265 described_class.new(plugin_file: plugin_file_path, solution_file: solution_file_path)
266 end
267
268 before do
269 allow(Pathname).to receive(:new).with(plugin_file_path).and_return(plugin_file)
270 allow(Pathname).to receive(:new).with(solution_file_path).and_return(solution_file)
271 allow(plugin_file).to receive(:exist?).and_return(plugin_file_exists)
272 allow(solution_file).to receive(:exist?).and_return(solution_file_exists)
273 end
274
275 context "when plugin file and solution file do not exist" do
276 it "should not attempt to read the solution" do
277 expect_any_instance_of(described_class).not_to receive(:read_solution)
278 subject
279 end
280 end
281
282 context "when plugin file exists and solution file does not" do
283 let(:plugin_file_exists) { true }
284
285 it "should not attempt to read the solution" do
286 expect_any_instance_of(described_class).not_to receive(:read_solution)
287 subject
288 end
289 end
290
291 context "when solution file exists and plugin file does not" do
292 let(:solution_file_exists) { true }
293
294 it "should not attempt to read the solution" do
295 expect_any_instance_of(described_class).not_to receive(:read_solution)
296 subject
297 end
298 end
299
300 context "when solution file and plugin file exist" do
301 let(:plugin_file_exists) { true }
302 let(:solution_file_exists) { true }
303
304 let(:solution_file_contents) { "" }
305
306 before do
307 allow(solution_file).to receive(:read).and_return(solution_file_contents)
308 allow_any_instance_of(described_class).to receive(:plugin_file_checksum).and_return("VALID")
309 end
310
311 context "when solution file is empty" do
312 it "should return false" do
313 expect(subject.send(:load)).to be_falsey
314 end
315 end
316
317 context "when solution file contains invalid checksum" do
318 let(:solution_file_contents) { {checksum: "INVALID", vagrant_version: Vagrant::VERSION}.to_json }
319
320 it "should return false" do
321 expect(subject.send(:load)).to be_falsey
322 end
323 end
324
325 context "when solution file contains different Vagrant version" do
326 let(:solution_file_contents) { {checksum: "VALID", vagrant_version: "0.1"}.to_json }
327
328 it "should return false" do
329 expect(subject.send(:load)).to be_falsey
330 end
331 end
332
333 context "when solution file contains valid Vagrant version and valid checksum" do
334 let(:solution_file_contents) {
335 {checksum: "VALID", vagrant_version: Vagrant::VERSION, dependencies: file_dependencies}.to_json
336 }
337 let(:file_dependencies) { dependency_list.map{|d| [d.name, d.requirements_list]} }
338 let(:dependency_list) { [] }
339
340 it "should return true" do
341 expect(subject.send(:load)).to be_truthy
342 end
343
344 it "should be valid" do
345 expect(subject).to be_valid
346 end
347
348 context "when solution file contains dependency list" do
349 let(:dependency_list) { [
350 Gem::Dependency.new("dep1", "> 0"),
351 Gem::Dependency.new("dep2", "< 3")
352 ] }
353
354 it "should be valid" do
355 expect(subject).to be_valid
356 end
357
358 it "should convert list into dependency requests" do
359 subject.dependency_list.each do |d|
360 expect(d).to be_a(Gem::Resolver::DependencyRequest)
361 end
362 end
363
364 it "should include defined dependencies" do
365 expect(subject.dependency_list.first).to eq(dependency_list.first)
366 expect(subject.dependency_list.last).to eq(dependency_list.last)
367 end
368
369 it "should freeze the dependency list" do
370 expect(subject.dependency_list).to be_frozen
371 end
372 end
373 end
374 end
375 end
376
377 describe "#read_solution" do
378 let(:solution_file_contents) { "" }
379 let(:plugin_file_path) { "PLUGIN_FILE_PATH" }
380 let(:solution_file_path) { "SOLUTION_FILE_PATH" }
381 let(:plugin_file) { double("plugin-file") }
382 let(:solution_file) { double("solution-file") }
383
384 subject do
385 described_class.new(plugin_file: plugin_file_path, solution_file: solution_file_path)
386 end
387
388 before do
389 allow(Pathname).to receive(:new).with(plugin_file_path).and_return(plugin_file)
390 allow(Pathname).to receive(:new).with(solution_file_path).and_return(solution_file)
391 allow(plugin_file).to receive(:exist?).and_return(false)
392 allow(solution_file).to receive(:exist?).and_return(false)
393 allow(solution_file).to receive(:read).and_return(solution_file_contents)
394 end
395
396 it "should return nil when file contents are empty" do
397 expect(subject.send(:read_solution)).to be_nil
398 end
399
400 context "when file contents are hash" do
401 let(:solution_file_contents) { {checksum: "VALID"}.to_json }
402
403 it "should return a hash" do
404 expect(subject.send(:read_solution)).to be_a(Hash)
405 end
406
407 it "should return a hash with indifferent access" do
408 expect(subject.send(:read_solution)).to be_a(Vagrant::Util::HashWithIndifferentAccess)
409 end
410 end
411
412 context "when file contents are array" do
413 let(:solution_file_contents) { ["test"].to_json }
414
415 it "should return a hash" do
416 expect(subject.send(:read_solution)).to be_a(Hash)
417 end
418
419 it "should return a hash with indifferent access" do
420 expect(subject.send(:read_solution)).to be_a(Vagrant::Util::HashWithIndifferentAccess)
421 end
422 end
423
424 context "when file contents are null" do
425 let(:solution_file_contents) { "null" }
426
427 it "should return nil" do
428 expect(subject.send(:read_solution)).to be_nil
429 end
430 end
431
432 context "when file contents are invalid" do
433 let(:solution_file_contents) { "{2dfwef" }
434
435 it "should return nil" do
436 expect(subject.send(:read_solution)).to be_nil
437 end
438 end
439 end
440 end
441
442 describe Vagrant::Bundler do
443 include_context "unit"
444
445 let(:iso_env) { isolated_environment }
446 let(:env) { iso_env.create_vagrant_env }
447 let(:tmpdir) { @v_tmpdir ||= Pathname.new(Dir.mktmpdir("vagrant-bundler-test")) }
448
449 before do
450 @tmpdir = Dir.mktmpdir("vagrant-bundler-test")
451 @vh = ENV["VAGRANT_HOME"]
452 ENV["VAGRANT_HOME"] = @tmpdir
453 end
454
455 after do
456 ENV["VAGRANT_HOME"] = @vh
457 FileUtils.rm_rf(@tmpdir)
458 FileUtils.rm_rf(@v_tmpdir) if @v_tmpdir
459 end
460
461 it "should isolate gem path based on Ruby version" do
462 expect(subject.plugin_gem_path.to_s).to end_with(RUBY_VERSION)
463 end
464
465 it "should not have an env_plugin_gem_path by default" do
466 expect(subject.env_plugin_gem_path).to be_nil
467 end
468
469 describe "#initialize" do
470 it "should automatically set the plugin gem path" do
471 expect(subject.plugin_gem_path).not_to be_nil
472 end
473
474 it "should add current ruby version to plugin gem path suffix" do
475 expect(subject.plugin_gem_path.to_s).to end_with(RUBY_VERSION)
476 end
477
478 it "should freeze the plugin gem path" do
479 expect(subject.plugin_gem_path).to be_frozen
480 end
481 end
482
483 describe "#environment_path=" do
484 it "should error if not given Pathname" do
485 expect { subject.environment_path = :value }.
486 to raise_error(TypeError)
487 end
488
489 context "when set with Pathname" do
490 let(:env_path) { Pathname.new("/dev/null") }
491 before { subject.environment_path = env_path }
492
493 it "should set the environment_data_path" do
494 expect(subject.environment_data_path).to eq(env_path)
495 end
496
497 it "should set the env_plugin_gem_path" do
498 expect(subject.env_plugin_gem_path).not_to be_nil
499 end
500
501 it "should suffix current ruby version to env_plugin_gem_path" do
502 expect(subject.env_plugin_gem_path.to_s).to end_with(RUBY_VERSION)
503 end
504
505 it "should base env_plugin_gem_path on environment_path value" do
506 expect(subject.env_plugin_gem_path.to_s).to start_with(env_path.to_s)
507 end
508
509 it "should freeze the env_plugin_gem_path" do
510 expect(subject.env_plugin_gem_path).to be_frozen
511 end
512 end
513 end
514
515 describe "#load_solution_file" do
516 let(:local_opt) { nil }
517 let(:global_opt) { nil }
518 let(:options) { {local: local_opt, global: global_opt} }
519
520 it "should return nil when local and global options are blank" do
521 expect(subject.load_solution_file(options)).to be_nil
522 end
523
524 context "when environment data path is set" do
525 let(:env_path) { "/dev/null" }
526 before { subject.environment_path = Pathname.new(env_path) }
527
528 context "when local option is set" do
529 let(:local_opt) { tmpdir + "local" }
530
531 it "should return a SolutionFile instance" do
532 expect(subject.load_solution_file(options)).to be_a(Vagrant::Bundler::SolutionFile)
533 end
534
535 it "should be located in the environment data path" do
536 file = subject.load_solution_file(options)
537 expect(file.solution_file.to_s).to start_with(env_path)
538 end
539
540 it "should have a local.sol solution file" do
541 file = subject.load_solution_file(options)
542 expect(file.solution_file.to_s).to end_with("local.sol")
543 end
544
545 it "should have plugin file set to local value" do
546 file = subject.load_solution_file(options)
547 expect(file.plugin_file.to_s).to eq(local_opt.to_s)
548 end
549 end
550
551 context "when global option is set" do
552 let(:global_opt) { tmpdir + "global" }
553
554 it "should return a SolutionFile instance" do
555 expect(subject.load_solution_file(options)).to be_a(Vagrant::Bundler::SolutionFile)
556 end
557
558 it "should be located in the environment data path" do
559 file = subject.load_solution_file(options)
560 expect(file.solution_file.to_s).to start_with(env_path)
561 end
562
563 it "should have a global.sol solution file" do
564 file = subject.load_solution_file(options)
565 expect(file.solution_file.to_s).to end_with("global.sol")
566 end
567
568 it "should have plugin file set to global value" do
569 file = subject.load_solution_file(options)
570 expect(file.plugin_file.to_s).to eq(global_opt.to_s)
571 end
572 end
573
574 context "when local and global option is set" do
575 let(:global_opt) { tmpdir + "global" }
576 let(:local_opt) { tmpdir + "local" }
577
578 it "should return nil" do
579 expect(subject.load_solution_file(options)).to be_nil
580 end
581 end
582 end
583
584 context "when environment data path is unset" do
585 context "when local option is set" do
586 let(:local_opt) { tmpdir + "local" }
587
588 it "should return nil" do
589 expect(subject.load_solution_file(options)).to be_nil
590 end
591 end
592
593 context "when global option is set" do
594 let(:global_opt) { tmpdir + "global" }
595
596 it "should return a SolutionFile instance" do
597 expect(subject.load_solution_file(options)).to be_a(Vagrant::Bundler::SolutionFile)
598 end
599
600 it "should be located in the vagrant user data path" do
601 file = subject.load_solution_file(options)
602 expect(file.solution_file.to_s).to start_with(Vagrant.user_data_path.to_s)
603 end
604
605 it "should have a global.sol solution file" do
606 file = subject.load_solution_file(options)
607 expect(file.solution_file.to_s).to end_with("global.sol")
608 end
609
610 it "should have plugin file set to global value" do
611 file = subject.load_solution_file(options)
612 expect(file.plugin_file.to_s).to eq(global_opt.to_s)
613 end
614 end
615 end
616 end
617
618 describe "#deinit" do
619 it "should provide method for backwards compatibility" do
620 subject.deinit
621 end
622 end
623
624 describe "DEFAULT_GEM_SOURCES" do
625 it "should list hashicorp gemstore first" do
626 expect(described_class.const_get(:DEFAULT_GEM_SOURCES).first).to eq(
627 described_class.const_get(:HASHICORP_GEMSTORE))
628 end
629 end
630
631 describe "#init!" do
632 context "Gem.sources" do
633 before {
634 Gem.sources.clear
635 Gem.sources << "https://rubygems.org/" }
636
637 it "should add hashicorp gem store" do
638 subject.init!([])
639 expect(Gem.sources).to include(described_class.const_get(:HASHICORP_GEMSTORE))
640 end
641
642 it "should add hashicorp gem store to start of sources list" do
643 subject.init!([])
644 expect(Gem.sources.sources.first.uri.to_s).to eq(described_class.const_get(:HASHICORP_GEMSTORE))
645 end
646 end
647 end
648
649 describe "#install" do
650 let(:plugins){ {"my-plugin" => {"gem_version" => "> 0"}} }
651
652 it "should pass plugin information hash to internal install" do
653 expect(subject).to receive(:internal_install).with(plugins, any_args)
654 subject.install(plugins)
655 end
656
657 it "should not include any update plugins" do
658 expect(subject).to receive(:internal_install).with(anything, nil, any_args)
659 subject.install(plugins)
660 end
661
662 it "should flag local when local is true" do
663 expect(subject).to receive(:internal_install).with(any_args, env_local: true)
664 subject.install(plugins, true)
665 end
666
667 it "should not flag local when local is not set" do
668 expect(subject).to receive(:internal_install).with(any_args, env_local: false)
669 subject.install(plugins)
670 end
671 end
672
673 describe "#install_local" do
674 let(:plugin_source){ double("plugin_source", spec: plugin_spec) }
675 let(:plugin_spec){ double("plugin_spec", name: plugin_name, version: plugin_version) }
676 let(:plugin_name){ "PLUGIN_NAME" }
677 let(:plugin_version){ "1.0.0" }
678 let(:plugin_path){ "PLUGIN_PATH" }
679 let(:sources){ "SOURCES" }
680
681 before do
682 allow(Gem::Source::SpecificFile).to receive(:new).and_return(plugin_source)
683 allow(subject).to receive(:internal_install)
684 end
685
686 it "should return plugin gem specification" do
687 expect(subject.install_local(plugin_path)).to eq(plugin_spec)
688 end
689
690 it "should set custom sources" do
691 expect(subject).to receive(:internal_install) do |info, update, opts|
692 expect(info[plugin_name]["sources"]).to eq(sources)
693 end
694 subject.install_local(plugin_path, sources: sources)
695 end
696
697 it "should not set the update parameter" do
698 expect(subject).to receive(:internal_install) do |info, update, opts|
699 expect(update).to be_nil
700 end
701 subject.install_local(plugin_path)
702 end
703
704 it "should not set plugin as environment local by default" do
705 expect(subject).to receive(:internal_install) do |info, update, opts|
706 expect(opts[:env_local]).to be_falsey
707 end
708 subject.install_local(plugin_path)
709 end
710
711 it "should set if plugin is environment local" do
712 expect(subject).to receive(:internal_install) do |info, update, opts|
713 expect(opts[:env_local]).to be_truthy
714 end
715 subject.install_local(plugin_path, env_local: true)
716 end
717 end
718
719 describe "#update" do
720 let(:plugins){ :plugins }
721 let(:specific){ [] }
722
723 after{ subject.update(plugins, specific) }
724
725 it "should mark update as true" do
726 expect(subject).to receive(:internal_install) do |info, update, opts|
727 expect(update).to be_truthy
728 end
729 end
730
731 context "with specific plugins named" do
732 let(:specific){ ["PLUGIN_NAME"] }
733
734 it "should set update to specific names" do
735 expect(subject).to receive(:internal_install) do |info, update, opts|
736 expect(update[:gems]).to eq(specific)
737 end
738 end
739 end
740 end
741
742 describe "#vagrant_internal_specs" do
743 let(:vagrant_spec) { double("vagrant_spec", name: "vagrant", version: Gem::Version.new(Vagrant::VERSION),
744 activated?: vagrant_spec_activated, activate: nil, runtime_dependencies: vagrant_dep_specs) }
745 let(:spec_list) { [] }
746 let(:spec_dirs) { [] }
747 let(:spec_default_dir) { "/dev/null" }
748 let(:dir_spec_list) { [] }
749 let(:vagrant_spec_activated) { true }
750 let(:vagrant_dep_specs) { [] }
751
752 before do
753 allow(Gem::Specification).to receive(:find) { |&b| vagrant_spec if b.call(vagrant_spec) }
754 allow(Gem::Specification).to receive(:find_all).and_return(spec_list)
755 allow(Gem::Specification).to receive(:dirs).and_return(spec_dirs)
756 allow(Gem::Specification).to receive(:default_specifications_dir).and_return(spec_default_dir)
757 allow(Gem::Specification).to receive(:each_spec).and_return(dir_spec_list)
758 end
759
760 it "should return an empty list" do
761 expect(subject.send(:vagrant_internal_specs)).to eq([])
762 end
763
764 context "when vagrant specification is not activated" do
765 let(:vagrant_spec_activated) { false }
766
767 it "should activate the specification" do
768 expect(vagrant_spec).to receive(:activate)
769 subject.send(:vagrant_internal_specs)
770 end
771 end
772
773 context "when vagrant specification is not found" do
774 before { allow(Gem::Specification).to receive(:find).and_return(nil) }
775
776 it "should raise not found error" do
777 expect { subject.send(:vagrant_internal_specs) }.to raise_error(Vagrant::Errors::SourceSpecNotFound)
778 end
779 end
780
781 context "when run time dependencies are defined" do
782 let(:vagrant_dep_specs) { [double("spec", name: "vagrant-dep", requirement: double("spec-req", as_list: []))] }
783
784 it "should call #gem to activate the dependencies" do
785 expect(subject).to receive(:gem).with("vagrant-dep", any_args)
786 subject.send(:vagrant_internal_specs)
787 end
788 end
789
790 context "when bundler is not defined" do
791 before { expect(Object).to receive(:const_defined?).with(:Bundler).and_return(false) }
792
793 it "should load gem specification directories" do
794 expect(Gem::Specification).to receive(:dirs).and_return(spec_dirs)
795 subject.send(:vagrant_internal_specs)
796 end
797
798 context "when checking paths" do
799 let(:spec_dirs) { [double("spec-dir", start_with?: in_user_dir)] }
800 let(:in_user_dir) { true }
801 let(:user_dir) { double("user-dir") }
802
803 before { allow(Gem).to receive(:user_dir).and_return(user_dir) }
804
805 it "should check if path is within local user directory" do
806 expect(spec_dirs.first).to receive(:start_with?).with(user_dir).and_return(false)
807 subject.send(:vagrant_internal_specs)
808 end
809
810 context "when path is not within user directory" do
811 let(:in_user_dir) { false }
812
813 it "should use path when loading specs" do
814 expect(Gem::Specification).to receive(:each_spec) { |arg| expect(arg).to include(spec_dirs.first) }
815 subject.send(:vagrant_internal_specs)
816 end
817 end
818 end
819 end
820 end
821
822 describe Vagrant::Bundler::PluginSet do
823 let(:name) { "test-gem" }
824 let(:version) { "1.0.0" }
825 let(:directory) { @directory ||= Dir.mktmpdir("vagrant-bundler-test") }
826
827 after do
828 FileUtils.rm_rf(@directory) if @directory
829 @directory = nil
830 end
831
832 describe "#add_vendor_gem" do
833 context "when spec file does not exist" do
834 it "should raise a not found error" do
835 expect { subject.add_vendor_gem(name, directory) }.to raise_error(Gem::GemNotFoundException)
836 end
837 end
838
839 context "when spec file exists" do
840 before do
841 spec = Gem::Specification.new(name, version)
842 File.write(File.join(directory, "#{name}.gemspec"), spec.to_ruby)
843 end
844
845 it "should load the specification" do
846 expect(subject.add_vendor_gem(name, directory)).to be_a(Gem::Specification)
847 end
848
849 it "should set the full path in specification" do
850 spec = subject.add_vendor_gem(name, directory)
851 expect(spec.full_gem_path).to eq(directory)
852 end
853 end
854 end
855
856 describe "#find_all" do
857 let(:request) { Gem::Resolver::DependencyRequest.new(dependency, nil) }
858 let(:dependency) { Gem::Dependency.new("test-gem", requirement) }
859 let(:requirement) { Gem::Requirement.new(version) }
860
861 context "when specification is not included in set" do
862 it "should return empty array" do
863 expect(subject.find_all(request)).to eq([])
864 end
865 end
866
867 context "when specification is included in set" do
868 before do
869 spec = Gem::Specification.new(name, version)
870 File.write(File.join(directory, "#{name}.gemspec"), spec.to_ruby)
871 subject.add_vendor_gem(name, directory)
872 end
873
874 it "should return a vendor specification instance" do
875 expect(subject.find_all(request).first).to be_a(Gem::Resolver::VendorSpecification)
876 end
877 end
878 end
879 end
880 end