vaguerent/test/unit/vagrant/plugin/manager_test.rb

341 lines
9.7 KiB
Ruby

require "json"
require "pathname"
require "vagrant/plugin"
require "vagrant/plugin/manager"
require "vagrant/plugin/state_file"
require "vagrant/util/deep_merge"
require File.expand_path("../../../base", __FILE__)
describe Vagrant::Plugin::Manager do
include_context "unit"
let(:path) do
Pathname.new(Dir::Tmpname.create("vagrant-test-plugin-manager") {})
end
let(:bundler) { double("bundler") }
after do
path.unlink if path.file?
end
before do
allow(Vagrant::Bundler).to receive(:instance).and_return(bundler)
end
subject { described_class.new(path) }
describe "#globalize!" do
let(:plugins) { double("plugins") }
before do
allow(subject).to receive(:bundler_init)
allow(subject).to receive(:installed_plugins).and_return(plugins)
end
it "should init bundler with installed plugins" do
expect(subject).to receive(:bundler_init).with(plugins)
subject.globalize!
end
it "should return installed plugins" do
expect(subject.globalize!).to eq(plugins)
end
end
describe "#localize!" do
let(:env) { double("env", local_data_path: local_data_path) }
let(:local_data_path) { double("local_data_path") }
let(:plugins) { double("plugins") }
let(:state_file) { double("state_file", installed_plugins: plugins) }
before do
allow(Vagrant::Plugin::StateFile).to receive(:new).and_return(state_file)
allow(bundler).to receive(:environment_path=)
allow(local_data_path).to receive(:join).and_return(local_data_path)
allow(subject).to receive(:bundler_init)
end
context "without local data path defined" do
let(:local_data_path) { nil }
it "should not do any initialization" do
expect(subject).not_to receive(:bundler_init)
subject.localize!(env)
end
it "should return nil" do
expect(subject.localize!(env)).to be_nil
end
end
it "should run bundler initialization" do
expect(subject).to receive(:bundler_init).with(plugins)
subject.localize!(env)
end
it "should return plugins" do
expect(subject.localize!(env)).to eq(plugins)
end
end
describe "#bundler_init" do
let(:plugins) { {"plugin_name" => {}} }
before do
allow(Vagrant).to receive(:plugins_init?).and_return(true)
allow(bundler).to receive(:init!)
end
it "should init the bundler instance with plugins" do
expect(bundler).to receive(:init!).with(plugins)
subject.bundler_init(plugins)
end
it "should return nil" do
expect(subject.bundler_init(plugins)).to be_nil
end
context "with plugin init disabled" do
before { expect(Vagrant).to receive(:plugins_init?).and_return(false) }
it "should return nil" do
expect(subject.bundler_init(plugins)).to be_nil
end
it "should not init the bundler instance" do
expect(bundler).not_to receive(:init!).with(plugins)
subject.bundler_init(plugins)
end
end
end
describe "#install_plugin" do
it "installs the plugin and adds it to the state file" do
specs = Array.new(5) { Gem::Specification.new }
specs[3].name = "foo"
expect(bundler).to receive(:install).once.with(any_args) { |plugins, local|
expect(plugins).to have_key("foo")
expect(local).to be_falsey
}.and_return(specs)
expect(bundler).to receive(:clean)
result = subject.install_plugin("foo")
# It should return the spec of the installed plugin
expect(result).to eql(specs[3])
# It should've added the plugin to the state
expect(subject.installed_plugins).to have_key("foo")
end
it "masks GemNotFound with our error" do
expect(bundler).to receive(:install).and_raise(Gem::GemNotFoundException)
expect { subject.install_plugin("foo") }.
to raise_error(Vagrant::Errors::PluginGemNotFound)
end
it "masks bundler errors with our own error" do
expect(bundler).to receive(:install).and_raise(Gem::InstallError)
expect { subject.install_plugin("foo") }.
to raise_error(Vagrant::Errors::BundlerError)
end
it "can install a local gem" do
name = "foo.gem"
version = "1.0"
local_spec = Gem::Specification.new
local_spec.name = "bar"
local_spec.version = version
expect(bundler).to receive(:install_local).with(name, {}).
ordered.and_return(local_spec)
expect(bundler).not_to receive(:install)
expect(bundler).to receive(:clean)
subject.install_plugin(name)
plugins = subject.installed_plugins
expect(plugins).to have_key("bar")
expect(plugins["bar"]["gem_version"]).to eql("1.0")
end
describe "installation options" do
let(:specs) do
specs = Array.new(5) { Gem::Specification.new }
specs[3].name = "foo"
specs
end
before do
allow(bundler).to receive(:install).and_return(specs)
end
it "installs a version with constraints" do
expect(bundler).to receive(:install).once.with(any_args) { |plugins, local|
expect(plugins).to have_key("foo")
expect(plugins["foo"]["gem_version"]).to eql(">= 0.1.0")
expect(local).to be_falsey
}.and_return(specs)
expect(bundler).to receive(:clean)
subject.install_plugin("foo", version: ">= 0.1.0")
plugins = subject.installed_plugins
expect(plugins).to have_key("foo")
expect(plugins["foo"]["gem_version"]).to eql(">= 0.1.0")
end
it "installs with an exact version but doesn't constrain" do
expect(bundler).to receive(:install).once.with(any_args) { |plugins, local|
expect(plugins).to have_key("foo")
expect(plugins["foo"]["gem_version"]).to eql("0.1.0")
expect(local).to be_falsey
}.and_return(specs)
expect(bundler).to receive(:clean)
subject.install_plugin("foo", version: "0.1.0")
plugins = subject.installed_plugins
expect(plugins).to have_key("foo")
expect(plugins["foo"]["gem_version"]).to eql("0.1.0")
end
end
end
describe "#uninstall_plugin" do
it "removes the plugin from the state" do
sf = Vagrant::Plugin::StateFile.new(path)
sf.add_plugin("foo")
# Sanity
expect(subject.installed_plugins).to have_key("foo")
# Test
expect(bundler).to receive(:clean).once.with({})
# Remove it
subject.uninstall_plugin("foo")
expect(subject.installed_plugins).to_not have_key("foo")
end
it "masks bundler errors with our own error" do
sf = Vagrant::Plugin::StateFile.new(path)
sf.add_plugin("foo")
expect(bundler).to receive(:clean).and_raise(Gem::InstallError)
expect { subject.uninstall_plugin("foo") }.
to raise_error(Vagrant::Errors::BundlerError)
end
context "with a system file" do
let(:systems_path) { temporary_file }
before do
systems_path.unlink
allow(described_class).to receive(:system_plugins_file).and_return(systems_path)
sf = Vagrant::Plugin::StateFile.new(systems_path)
sf.add_plugin("foo", version: "0.2.0")
sf.add_plugin("bar")
end
it "uninstalls the user plugin if it exists" do
sf = Vagrant::Plugin::StateFile.new(path)
sf.add_plugin("bar")
# Test
expect(bundler).to receive(:clean).once.with(anything)
# Remove it
subject.uninstall_plugin("bar")
plugins = subject.installed_plugins
expect(plugins["foo"]["system"]).to be(true)
end
it "raises an error if uninstalling a system gem" do
expect { subject.uninstall_plugin("bar") }.
to raise_error(Vagrant::Errors::PluginUninstallSystem)
end
end
end
describe "#update_plugins" do
it "masks bundler errors with our own error" do
expect(bundler).to receive(:update).and_raise(Gem::InstallError)
expect { subject.update_plugins([]) }.
to raise_error(Vagrant::Errors::BundlerError)
end
end
context "without state" do
describe "#installed_plugins" do
it "is empty initially" do
expect(subject.installed_plugins).to be_empty
end
end
end
context "with state" do
before do
sf = Vagrant::Plugin::StateFile.new(path)
sf.add_plugin("foo", version: "0.1.0")
end
describe "#installed_plugins" do
it "has the plugins" do
plugins = subject.installed_plugins
expect(plugins.length).to eql(1)
expect(plugins).to have_key("foo")
end
end
describe "#installed_specs" do
it "has the plugins" do
# We just add "i18n" because it is a dependency of Vagrant and
# we know it will be there.
sf = Vagrant::Plugin::StateFile.new(path)
sf.add_plugin("i18n")
specs = subject.installed_specs
expect(specs.length).to eql(1)
expect(specs.first.name).to eql("i18n")
end
end
context "with system plugins" do
let(:systems_path) { temporary_file }
before do
systems_path.unlink
allow(described_class).to receive(:system_plugins_file).and_return(systems_path)
sf = Vagrant::Plugin::StateFile.new(systems_path)
sf.add_plugin("foo", version: "0.2.0")
sf.add_plugin("bar")
end
describe "#installed_plugins" do
it "has the plugins" do
plugins = subject.installed_plugins
expect(plugins.length).to eql(2)
expect(plugins).to have_key("foo")
expect(plugins["foo"]["gem_version"]).to eq("0.1.0")
expect(plugins["foo"]["system"]).to be_truthy
expect(plugins).to have_key("bar")
expect(plugins["bar"]["system"]).to be(true)
end
end
end
end
end