summaryrefslogtreecommitdiff
path: root/spec/bundler/bundler/plugin
diff options
context:
space:
mode:
authorhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-08 08:45:41 +0000
committerhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-08 08:45:41 +0000
commit8598f8c2dc78c6d1ae87cb6ae19c34ba2cb29241 (patch)
tree0bbd28f684e745cb212761b7c74fe08668f85cc8 /spec/bundler/bundler/plugin
parentf2e04b77aa8a363d7e36ce5a9cdb60714a537a3c (diff)
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
Diffstat (limited to 'spec/bundler/bundler/plugin')
-rw-r--r--spec/bundler/bundler/plugin/api/source_spec.rb83
-rw-r--r--spec/bundler/bundler/plugin/api_spec.rb84
-rw-r--r--spec/bundler/bundler/plugin/dsl_spec.rb39
-rw-r--r--spec/bundler/bundler/plugin/index_spec.rb179
-rw-r--r--spec/bundler/bundler/plugin/installer_spec.rb100
-rw-r--r--spec/bundler/bundler/plugin/source_list_spec.rb26
6 files changed, 511 insertions, 0 deletions
diff --git a/spec/bundler/bundler/plugin/api/source_spec.rb b/spec/bundler/bundler/plugin/api/source_spec.rb
new file mode 100644
index 0000000000..4dbb993b89
--- /dev/null
+++ b/spec/bundler/bundler/plugin/api/source_spec.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Bundler::Plugin::API::Source do
+ let(:uri) { "uri://to/test" }
+ let(:type) { "spec_type" }
+
+ subject(:source) do
+ klass = Class.new
+ klass.send :include, Bundler::Plugin::API::Source
+ klass.new("uri" => uri, "type" => type)
+ end
+
+ describe "attributes" do
+ it "allows access to uri" do
+ expect(source.uri).to eq("uri://to/test")
+ end
+
+ it "allows access to name" do
+ expect(source.name).to eq("spec_type at uri://to/test")
+ end
+ end
+
+ context "post_install" do
+ let(:installer) { double(:installer) }
+
+ before do
+ allow(Bundler::Source::Path::Installer).to receive(:new) { installer }
+ end
+
+ it "calls Path::Installer's post_install" do
+ expect(installer).to receive(:post_install).once
+
+ source.post_install(double(:spec))
+ end
+ end
+
+ context "install_path" do
+ let(:uri) { "uri://to/a/repository-name" }
+ let(:hash) { Digest::SHA1.hexdigest(uri) }
+ let(:install_path) { Pathname.new "/bundler/install/path" }
+
+ before do
+ allow(Bundler).to receive(:install_path) { install_path }
+ end
+
+ it "returns basename with uri_hash" do
+ expected = Pathname.new "#{install_path}/repository-name-#{hash[0..11]}"
+ expect(source.install_path).to eq(expected)
+ end
+ end
+
+ context "to_lock" do
+ it "returns the string with remote and type" do
+ expected = strip_whitespace <<-L
+ PLUGIN SOURCE
+ remote: #{uri}
+ type: #{type}
+ specs:
+ L
+
+ expect(source.to_lock).to eq(expected)
+ end
+
+ context "with additional options to lock" do
+ before do
+ allow(source).to receive(:options_to_lock) { { "first" => "option" } }
+ end
+
+ it "includes them" do
+ expected = strip_whitespace <<-L
+ PLUGIN SOURCE
+ remote: #{uri}
+ type: #{type}
+ first: option
+ specs:
+ L
+
+ expect(source.to_lock).to eq(expected)
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/plugin/api_spec.rb b/spec/bundler/bundler/plugin/api_spec.rb
new file mode 100644
index 0000000000..e40b9adb0f
--- /dev/null
+++ b/spec/bundler/bundler/plugin/api_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Bundler::Plugin::API do
+ context "plugin declarations" do
+ before do
+ stub_const "UserPluginClass", Class.new(Bundler::Plugin::API)
+ end
+
+ describe "#command" do
+ it "declares a command plugin with same class as handler" do
+ expect(Bundler::Plugin).
+ to receive(:add_command).with("meh", UserPluginClass).once
+
+ UserPluginClass.command "meh"
+ end
+
+ it "accepts another class as argument that handles the command" do
+ stub_const "NewClass", Class.new
+ expect(Bundler::Plugin).to receive(:add_command).with("meh", NewClass).once
+
+ UserPluginClass.command "meh", NewClass
+ end
+ end
+
+ describe "#source" do
+ it "declares a source plugin with same class as handler" do
+ expect(Bundler::Plugin).
+ to receive(:add_source).with("a_source", UserPluginClass).once
+
+ UserPluginClass.source "a_source"
+ end
+
+ it "accepts another class as argument that handles the command" do
+ stub_const "NewClass", Class.new
+ expect(Bundler::Plugin).to receive(:add_source).with("a_source", NewClass).once
+
+ UserPluginClass.source "a_source", NewClass
+ end
+ end
+
+ describe "#hook" do
+ it "accepts a block and passes it to Plugin module" do
+ foo = double("tester")
+ expect(foo).to receive(:called)
+
+ expect(Bundler::Plugin).to receive(:add_hook).with("post-foo").and_yield
+
+ Bundler::Plugin::API.hook("post-foo") { foo.called }
+ end
+ end
+ end
+
+ context "bundler interfaces provided" do
+ before do
+ stub_const "UserPluginClass", Class.new(Bundler::Plugin::API)
+ end
+
+ subject(:api) { UserPluginClass.new }
+
+ # A test of delegation
+ it "provides the Bundler's functions" do
+ expect(Bundler).to receive(:an_unkown_function).once
+
+ api.an_unkown_function
+ end
+
+ it "includes Bundler::SharedHelpers' functions" do
+ expect(Bundler::SharedHelpers).to receive(:an_unkown_helper).once
+
+ api.an_unkown_helper
+ end
+
+ context "#tmp" do
+ it "provides a tmp dir" do
+ expect(api.tmp("mytmp")).to be_directory
+ end
+
+ it "accepts multiple names for suffix" do
+ expect(api.tmp("myplugin", "download")).to be_directory
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/plugin/dsl_spec.rb b/spec/bundler/bundler/plugin/dsl_spec.rb
new file mode 100644
index 0000000000..cd15b6ea9d
--- /dev/null
+++ b/spec/bundler/bundler/plugin/dsl_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Bundler::Plugin::DSL do
+ DSL = Bundler::Plugin::DSL
+
+ subject(:dsl) { Bundler::Plugin::DSL.new }
+
+ before do
+ allow(Bundler).to receive(:root) { Pathname.new "/" }
+ end
+
+ describe "it ignores only the methods defined in Bundler::Dsl" do
+ it "doesn't raises error for Dsl methods" do
+ expect { dsl.install_if }.not_to raise_error
+ end
+
+ it "raises error for other methods" do
+ expect { dsl.no_method }.to raise_error(DSL::PluginGemfileError)
+ end
+ end
+
+ describe "source block" do
+ it "adds #source with :type to list and also inferred_plugins list" do
+ expect(dsl).to receive(:plugin).with("bundler-source-news").once
+
+ dsl.source("some_random_url", :type => "news") {}
+
+ expect(dsl.inferred_plugins).to eq(["bundler-source-news"])
+ end
+
+ it "registers a source type plugin only once for multiple declataions" do
+ expect(dsl).to receive(:plugin).with("bundler-source-news").and_call_original.once
+
+ dsl.source("some_random_url", :type => "news") {}
+ dsl.source("another_random_url", :type => "news") {}
+ end
+ end
+end
diff --git a/spec/bundler/bundler/plugin/index_spec.rb b/spec/bundler/bundler/plugin/index_spec.rb
new file mode 100644
index 0000000000..24b9a408ff
--- /dev/null
+++ b/spec/bundler/bundler/plugin/index_spec.rb
@@ -0,0 +1,179 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Bundler::Plugin::Index do
+ Index = Bundler::Plugin::Index
+
+ before do
+ gemfile ""
+ path = lib_path(plugin_name)
+ index.register_plugin("new-plugin", path.to_s, [path.join("lib").to_s], commands, sources, hooks)
+ end
+
+ let(:plugin_name) { "new-plugin" }
+ let(:commands) { [] }
+ let(:sources) { [] }
+ let(:hooks) { [] }
+
+ subject(:index) { Index.new }
+
+ describe "#register plugin" do
+ it "is available for retrieval" do
+ expect(index.plugin_path(plugin_name)).to eq(lib_path(plugin_name))
+ end
+
+ it "load_paths is available for retrival" do
+ expect(index.load_paths(plugin_name)).to eq([lib_path(plugin_name).join("lib").to_s])
+ end
+
+ it "is persistent" do
+ new_index = Index.new
+ expect(new_index.plugin_path(plugin_name)).to eq(lib_path(plugin_name))
+ end
+
+ it "load_paths are persistent" do
+ new_index = Index.new
+ expect(new_index.load_paths(plugin_name)).to eq([lib_path(plugin_name).join("lib").to_s])
+ end
+ end
+
+ describe "commands" do
+ let(:commands) { ["newco"] }
+
+ it "returns the plugins name on query" do
+ expect(index.command_plugin("newco")).to eq(plugin_name)
+ end
+
+ it "raises error on conflict" do
+ expect do
+ index.register_plugin("aplugin", lib_path("aplugin").to_s, lib_path("aplugin").join("lib").to_s, ["newco"], [], [])
+ end.to raise_error(Index::CommandConflict)
+ end
+
+ it "is persistent" do
+ new_index = Index.new
+ expect(new_index.command_plugin("newco")).to eq(plugin_name)
+ end
+ end
+
+ describe "source" do
+ let(:sources) { ["new_source"] }
+
+ it "returns the plugins name on query" do
+ expect(index.source_plugin("new_source")).to eq(plugin_name)
+ end
+
+ it "raises error on conflict" do
+ expect do
+ index.register_plugin("aplugin", lib_path("aplugin").to_s, lib_path("aplugin").join("lib").to_s, [], ["new_source"], [])
+ end.to raise_error(Index::SourceConflict)
+ end
+
+ it "is persistent" do
+ new_index = Index.new
+ expect(new_index.source_plugin("new_source")).to eq(plugin_name)
+ end
+ end
+
+ describe "hook" do
+ let(:hooks) { ["after-bar"] }
+
+ it "returns the plugins name on query" do
+ expect(index.hook_plugins("after-bar")).to include(plugin_name)
+ end
+
+ it "is persistent" do
+ new_index = Index.new
+ expect(new_index.hook_plugins("after-bar")).to eq([plugin_name])
+ end
+
+ context "that are not registered", :focused do
+ let(:file) { double("index-file") }
+
+ before do
+ index.hook_plugins("not-there")
+ allow(File).to receive(:open).and_yield(file)
+ end
+
+ it "should not save it with next registered hook" do
+ expect(file).to receive(:puts) do |content|
+ expect(content).not_to include("not-there")
+ end
+
+ index.register_plugin("aplugin", lib_path("aplugin").to_s, lib_path("aplugin").join("lib").to_s, [], [], [])
+ end
+ end
+ end
+
+ describe "global index" do
+ before do
+ Dir.chdir(tmp) do
+ Bundler::Plugin.reset!
+ path = lib_path("gplugin")
+ index.register_plugin("gplugin", path.to_s, [path.join("lib").to_s], [], ["glb_source"], [])
+ end
+ end
+
+ it "skips sources" do
+ new_index = Index.new
+ expect(new_index.source_plugin("glb_source")).to be_falsy
+ end
+ end
+
+ describe "after conflict" do
+ let(:commands) { ["foo"] }
+ let(:sources) { ["bar"] }
+ let(:hooks) { ["hoook"] }
+
+ shared_examples "it cleans up" do
+ it "the path" do
+ expect(index.installed?("cplugin")).to be_falsy
+ end
+
+ it "the command" do
+ expect(index.command_plugin("xfoo")).to be_falsy
+ end
+
+ it "the source" do
+ expect(index.source_plugin("xbar")).to be_falsy
+ end
+
+ it "the hook" do
+ expect(index.hook_plugins("xhoook")).to be_empty
+ end
+ end
+
+ context "on command conflict it cleans up" do
+ before do
+ expect do
+ path = lib_path("cplugin")
+ index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["xbar"], ["xhoook"])
+ end.to raise_error(Index::CommandConflict)
+ end
+
+ include_examples "it cleans up"
+ end
+
+ context "on source conflict it cleans up" do
+ before do
+ expect do
+ path = lib_path("cplugin")
+ index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["xfoo"], ["bar"], ["xhoook"])
+ end.to raise_error(Index::SourceConflict)
+ end
+
+ include_examples "it cleans up"
+ end
+
+ context "on command and source conflict it cleans up" do
+ before do
+ expect do
+ path = lib_path("cplugin")
+ index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["bar"], ["xhoook"])
+ end.to raise_error(Index::CommandConflict)
+ end
+
+ include_examples "it cleans up"
+ end
+ end
+end
diff --git a/spec/bundler/bundler/plugin/installer_spec.rb b/spec/bundler/bundler/plugin/installer_spec.rb
new file mode 100644
index 0000000000..e8d5941e33
--- /dev/null
+++ b/spec/bundler/bundler/plugin/installer_spec.rb
@@ -0,0 +1,100 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Bundler::Plugin::Installer do
+ subject(:installer) { Bundler::Plugin::Installer.new }
+
+ describe "cli install" do
+ it "uses Gem.sources when non of the source is provided" do
+ sources = double(:sources)
+ allow(Bundler).to receive_message_chain("rubygems.sources") { sources }
+
+ allow(installer).to receive(:install_rubygems).
+ with("new-plugin", [">= 0"], sources).once
+
+ installer.install("new-plugin", {})
+ end
+
+ describe "with mocked installers" do
+ let(:spec) { double(:spec) }
+ it "returns the installed spec after installing git plugins" do
+ allow(installer).to receive(:install_git).
+ and_return("new-plugin" => spec)
+
+ expect(installer.install(["new-plugin"], :git => "https://some.ran/dom")).
+ to eq("new-plugin" => spec)
+ end
+
+ it "returns the installed spec after installing rubygems plugins" do
+ allow(installer).to receive(:install_rubygems).
+ and_return("new-plugin" => spec)
+
+ expect(installer.install(["new-plugin"], :source => "https://some.ran/dom")).
+ to eq("new-plugin" => spec)
+ end
+ end
+
+ describe "with actual installers" do
+ before do
+ build_repo2 do
+ build_plugin "re-plugin"
+ build_plugin "ma-plugin"
+ end
+ end
+
+ context "git plugins" do
+ before do
+ build_git "ga-plugin", :path => lib_path("ga-plugin") do |s|
+ s.write "plugins.rb"
+ end
+ end
+
+ let(:result) do
+ installer.install(["ga-plugin"], :git => "file://#{lib_path("ga-plugin")}")
+ end
+
+ it "returns the installed spec after installing" do
+ spec = result["ga-plugin"]
+ expect(spec.full_name).to eq "ga-plugin-1.0"
+ end
+
+ it "has expected full gem path" do
+ rev = revision_for(lib_path("ga-plugin"))
+ expect(result["ga-plugin"].full_gem_path).
+ to eq(Bundler::Plugin.root.join("bundler", "gems", "ga-plugin-#{rev[0..11]}").to_s)
+ end
+ end
+
+ context "rubygems plugins" do
+ let(:result) do
+ installer.install(["re-plugin"], :source => "file://#{gem_repo2}")
+ end
+
+ it "returns the installed spec after installing " do
+ expect(result["re-plugin"]).to be_kind_of(Bundler::RemoteSpecification)
+ end
+
+ it "has expected full_gem)path" do
+ expect(result["re-plugin"].full_gem_path).
+ to eq(global_plugin_gem("re-plugin-1.0").to_s)
+ end
+ end
+
+ context "multiple plugins" do
+ let(:result) do
+ installer.install(["re-plugin", "ma-plugin"], :source => "file://#{gem_repo2}")
+ end
+
+ it "returns the installed spec after installing " do
+ expect(result["re-plugin"]).to be_kind_of(Bundler::RemoteSpecification)
+ expect(result["ma-plugin"]).to be_kind_of(Bundler::RemoteSpecification)
+ end
+
+ it "has expected full_gem)path" do
+ expect(result["re-plugin"].full_gem_path).to eq(global_plugin_gem("re-plugin-1.0").to_s)
+ expect(result["ma-plugin"].full_gem_path).to eq(global_plugin_gem("ma-plugin-1.0").to_s)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/bundler/bundler/plugin/source_list_spec.rb b/spec/bundler/bundler/plugin/source_list_spec.rb
new file mode 100644
index 0000000000..86cc4ac4ed
--- /dev/null
+++ b/spec/bundler/bundler/plugin/source_list_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Bundler::Plugin::SourceList do
+ SourceList = Bundler::Plugin::SourceList
+
+ before do
+ allow(Bundler).to receive(:root) { Pathname.new "/" }
+ end
+
+ subject(:source_list) { SourceList.new }
+
+ describe "adding sources uses classes for plugin" do
+ it "uses Plugin::Installer::Rubygems for rubygems sources" do
+ source = source_list.
+ add_rubygems_source("remotes" => ["https://existing-rubygems.org"])
+ expect(source).to be_instance_of(Bundler::Plugin::Installer::Rubygems)
+ end
+
+ it "uses Plugin::Installer::Git for git sources" do
+ source = source_list.
+ add_git_source("uri" => "git://existing-git.org/path.git")
+ expect(source).to be_instance_of(Bundler::Plugin::Installer::Git)
+ end
+ end
+end