Guest#capability? for testing for capabilities

This commit is contained in:
Mitchell Hashimoto 2013-04-03 22:03:03 -07:00
parent 52f3847b0a
commit 06a9968ec4
2 changed files with 82 additions and 12 deletions

View File

@ -19,11 +19,19 @@ module Vagrant
class Guest
attr_reader :chain
def initialize(machine, guests)
@logger = Log4r::Logger.new("vagrant::guest")
@chain = []
@guests = guests
@machine = machine
# The name of the guest OS. This is available after {#detect!} is
# called.
#
# @return [Symbol]
attr_reader :name
def initialize(machine, guests, capabilities)
@logger = Log4r::Logger.new("vagrant::guest")
@capabilities = capabilities
@chain = []
@guests = guests
@machine = machine
@name = nil
end
# This will detect the proper guest OS for the machine and set up
@ -63,15 +71,18 @@ module Vagrant
if guest.detect?(@machine)
@logger.info("Detected: #{name}!")
@chain << guest
@chain << [name, guest]
@name = name
# Build the proper chain of parents if there are any.
# This allows us to do "inheritence" of capabilities later
if guest_info[1]
parent_info = @guests[guest_info[1]]
parent_name = guest_info[1]
parent_info = @guests[parent_name]
while parent_info
@chain << parent_info[0].new
parent_info = @guests[parent_info[1]]
@chain << [parent_name, parent_info[0].new]
parent_name = parent_info[1]
parent_info = @guests[parent_name]
end
end
@ -89,6 +100,18 @@ module Vagrant
raise Errors::GuestNotDetected if @chain.empty?
end
# Tests whether the guest has the named capability.
#
# @return [Boolean]
def capability?(cap_name)
@chain.each do |guest_name, guest|
caps = @capabilities[guest_name]
return true if caps && caps.has_key?(cap_name)
end
false
end
# This returns whether the guest is ready to work. If this returns
# `false`, then {#detect!} should be called in order to detect the
# guest OS.

View File

@ -5,10 +5,22 @@ require File.expand_path("../../base", __FILE__)
describe Vagrant::Guest do
include_context "unit"
let(:capabilities) { {} }
let(:guests) { {} }
let(:machine) { double("machine") }
subject { described_class.new(machine, guests) }
subject { described_class.new(machine, guests, capabilities) }
# This registers a capability with a specific guest
def register_capability(guest, capability)
cap = Class.new do
define_method(capability) do
end
end
capabilities[guest] ||= {}
capabilities[guest][capability] = cap.new
end
# This registers a guest with the class.
#
@ -29,6 +41,37 @@ describe Vagrant::Guest do
guests[name] = [guest, parent]
end
describe "#capability?" do
before :each do
register_guest(:foo, nil, true)
register_guest(:bar, :foo, true)
subject.detect!
end
it "doesn't have unknown capabilities" do
subject.capability?(:what_is_this_i_dont_even).should_not be
end
it "doesn't have capabilities registered to other guests" do
register_capability(:baz, :test)
subject.capability?(:test).should_not be
end
it "has capability of detected guest" do
register_capability(:bar, :test)
subject.capability?(:test).should be
end
it "has capability of parent guests" do
register_capability(:foo, :test)
subject.capability?(:test).should be
end
end
describe "#detect!" do
it "detects the first match" do
register_guest(:foo, nil, false)
@ -36,8 +79,10 @@ describe Vagrant::Guest do
register_guest(:baz, nil, false)
subject.detect!
subject.name.should == :bar
subject.chain.length.should == 1
subject.chain[0].name.should == :bar
subject.chain[0][0].should == :bar
subject.chain[0][1].name.should == :bar
end
it "detects those with the most parents first" do
@ -48,8 +93,10 @@ describe Vagrant::Guest do
register_guest(:bar2, :foo2, true)
subject.detect!
subject.name.should == :baz
subject.chain.length.should == 3
subject.chain.map(&:name).should == [:baz, :bar, :foo]
subject.chain.map(&:first).should == [:baz, :bar, :foo]
subject.chain.map { |x| x[1] }.map(&:name).should == [:baz, :bar, :foo]
end
it "raises an exception if no guest can be detected" do