diff --git a/lib/vagrant/registry.rb b/lib/vagrant/registry.rb index 7fe02d096..df8147c9e 100644 --- a/lib/vagrant/registry.rb +++ b/lib/vagrant/registry.rb @@ -42,6 +42,22 @@ module Vagrant end end + # Merge one registry with another and return a completely new + # registry. Note that the result cache is completely busted, so + # any gets on the new registry will result in a cache miss. + def merge(other) + self.class.new.tap do |result| + result.merge!(self) + result.merge!(other) + end + end + + # Like #{merge} but merges into self. + def merge!(other) + @items.merge!(other.__internal_state[:items]) + self + end + # Converts this registry to a hash def to_hash result = {} @@ -51,5 +67,12 @@ module Vagrant result end + + def __internal_state + { + :items => @items, + :results_cache => @results_cache + } + end end end diff --git a/test/unit/vagrant/registry_test.rb b/test/unit/vagrant/registry_test.rb index 1c82117f6..2c1c00128 100644 --- a/test/unit/vagrant/registry_test.rb +++ b/test/unit/vagrant/registry_test.rb @@ -82,4 +82,47 @@ describe Vagrant::Registry do result["foo"].should == "foovalue" result["bar"].should == "barvalue" end + + describe "merging" do + it "should merge in another registry" do + one = described_class.new + two = described_class.new + + one.register("foo") { raise "BOOM!" } + two.register("bar") { raise "BAM!" } + + three = one.merge(two) + expect { three["foo"] }.to raise_error("BOOM!") + expect { three["bar"] }.to raise_error("BAM!") + end + + it "should NOT merge in the cache" do + one = described_class.new + two = described_class.new + + one.register("foo") { [] } + one["foo"] << 1 + + two.register("bar") { [] } + two["bar"] << 2 + + three = one.merge(two) + three["foo"].should == [] + three["bar"].should == [] + end + end + + describe "merge!" do + it "should merge into self" do + one = described_class.new + two = described_class.new + + one.register("foo") { "foo" } + two.register("bar") { "bar" } + + one.merge!(two) + one["foo"].should == "foo" + one["bar"].should == "bar" + end + end end