spec/unit/util/collection_spec.rb in facter-1.6.18 vs spec/unit/util/collection_spec.rb in facter-1.7.0.rc1
- old
+ new
@@ -1,71 +1,53 @@
#! /usr/bin/env ruby
require 'spec_helper'
require 'facter/util/collection'
+require 'facter/util/nothing_loader'
describe Facter::Util::Collection do
- it "should have a method for adding facts" do
- Facter::Util::Collection.new.should respond_to(:add)
+ let(:external_loader) { Facter::Util::NothingLoader.new }
+ let(:internal_loader) do
+ load = Facter::Util::Loader.new
+ load.stubs(:load).returns nil
+ load.stubs(:load_all).returns nil
+ load
end
+ let(:collection) { Facter::Util::Collection.new(internal_loader, external_loader) }
- it "should have a method for returning a loader" do
- Facter::Util::Collection.new.should respond_to(:loader)
- end
+ it "should delegate its load_all method to its loader" do
+ internal_loader.expects(:load_all)
- it "should use an instance of the Loader class as its loader" do
- Facter::Util::Collection.new.loader.should be_instance_of(Facter::Util::Loader)
+ collection.load_all
end
- it "should cache its loader" do
- coll = Facter::Util::Collection.new
- coll.loader.should equal(coll.loader)
- end
-
- it "should have a method for loading all facts" do
- Facter::Util::Collection.new.should respond_to(:load_all)
- end
-
- it "should delegate its load_all method to its loader" do
- coll = Facter::Util::Collection.new
- coll.loader.expects(:load_all)
- coll.load_all
- end
-
describe "when adding facts" do
- before do
- @coll = Facter::Util::Collection.new
- end
-
it "should create a new fact if no fact with the same name already exists" do
- fact = mock 'fact'
- Facter::Util::Fact.expects(:new).with { |name, *args| name == :myname }.returns fact
-
- @coll.add(:myname)
+ collection.add(:myname)
+ collection.fact(:myname).name.should == :myname
end
it "should accept options" do
- @coll.add(:myname, :ldapname => "whatever") { }
+ collection.add(:myname, :ldapname => "whatever") { }
end
it "should set any appropriate options on the fact instances" do
# Use a real fact instance, because we're using respond_to?
fact = Facter::Util::Fact.new(:myname)
- fact.expects(:ldapname=).with("testing")
- Facter::Util::Fact.expects(:new).with(:myname).returns fact
- @coll.add(:myname, :ldapname => "testing")
+ collection.add(:myname, :ldapname => "testing")
+ collection.fact(:myname).ldapname.should == "testing"
end
it "should set appropriate options on the resolution instance" do
fact = Facter::Util::Fact.new(:myname)
Facter::Util::Fact.expects(:new).with(:myname).returns fact
resolve = Facter::Util::Resolution.new(:myname) {}
fact.expects(:add).returns resolve
- @coll.add(:myname, :timeout => "myval") {}
+ collection.add(:myname, :timeout => "myval") {}
end
it "should not pass fact-specific options to resolutions" do
fact = Facter::Util::Fact.new(:myname)
Facter::Util::Fact.expects(:new).with(:myname).returns fact
@@ -74,191 +56,185 @@
fact.expects(:add).returns resolve
fact.expects(:ldapname=).with("foo")
resolve.expects(:timeout=).with("myval")
- @coll.add(:myname, :timeout => "myval", :ldapname => "foo") {}
+ collection.add(:myname, :timeout => "myval", :ldapname => "foo") {}
end
it "should fail if invalid options are provided" do
- lambda { @coll.add(:myname, :foo => :bar) }.should raise_error(ArgumentError)
+ lambda { collection.add(:myname, :foo => :bar) }.should raise_error(ArgumentError)
end
describe "and a block is provided" do
it "should use the block to add a resolution to the fact" do
fact = mock 'fact'
Facter::Util::Fact.expects(:new).returns fact
fact.expects(:add)
- @coll.add(:myname) {}
+ collection.add(:myname) {}
end
it "should discard resolutions that throw an exception when added" do
lambda {
- @coll.add('yay') do
+ collection.add('yay') do
raise
setcode { 'yay' }
end
}.should_not raise_error
- @coll.value('yay').should be_nil
+ collection.value('yay').should be_nil
end
end
end
- it "should have a method for retrieving facts by name" do
- Facter::Util::Collection.new.should respond_to(:fact)
- end
-
describe "when retrieving facts" do
before do
- @coll = Facter::Util::Collection.new
-
- @fact = @coll.add("YayNess")
+ @fact = collection.add("YayNess")
end
it "should return the fact instance specified by the name" do
- @coll.fact("YayNess").should equal(@fact)
+ collection.fact("YayNess").should equal(@fact)
end
it "should be case-insensitive" do
- @coll.fact("yayness").should equal(@fact)
+ collection.fact("yayness").should equal(@fact)
end
it "should treat strings and symbols equivalently" do
- @coll.fact(:yayness).should equal(@fact)
+ collection.fact(:yayness).should equal(@fact)
end
it "should use its loader to try to load the fact if no fact can be found" do
- @coll.loader.expects(:load).with(:testing)
- @coll.fact("testing")
+ collection.internal_loader.expects(:load).with(:testing)
+ collection.fact("testing")
end
it "should return nil if it cannot find or load the fact" do
- @coll.loader.expects(:load).with(:testing)
- @coll.fact("testing").should be_nil
+ collection.internal_loader.expects(:load).with(:testing)
+ collection.fact("testing").should be_nil
end
end
- it "should have a method for returning a fact's value" do
- Facter::Util::Collection.new.should respond_to(:value)
- end
-
describe "when returning a fact's value" do
before do
- @coll = Facter::Util::Collection.new
- @fact = @coll.add("YayNess")
-
- @fact.stubs(:value).returns "result"
+ @fact = collection.add("YayNess", :value => "result")
end
- it "should use the 'fact' method to retrieve the fact" do
- @coll.expects(:fact).with(:yayness).returns @fact
- @coll.value(:yayness)
- end
-
it "should return the result of calling :value on the fact" do
- @fact.expects(:value).returns "result"
-
- @coll.value("YayNess").should == "result"
+ collection.value("YayNess").should == "result"
end
it "should be case-insensitive" do
- @coll.value("yayness").should_not be_nil
+ collection.value("yayness").should == "result"
end
it "should treat strings and symbols equivalently" do
- @coll.value(:yayness).should_not be_nil
+ collection.value(:yayness).should == "result"
end
end
it "should return the fact's value when the array index method is used" do
- @coll = Facter::Util::Collection.new
- @coll.expects(:value).with("myfact").returns "foo"
- @coll["myfact"].should == "foo"
+ collection.add("myfact", :value => "foo")
+
+ collection["myfact"].should == "foo"
end
it "should have a method for flushing all facts" do
- @coll = Facter::Util::Collection.new
- @fact = @coll.add("YayNess")
+ fact = collection.add("YayNess")
- @fact.expects(:flush)
+ fact.expects(:flush)
- @coll.flush
+ collection.flush
end
it "should have a method that returns all fact names" do
- @coll = Facter::Util::Collection.new
- @coll.add(:one)
- @coll.add(:two)
+ collection.add(:one)
+ collection.add(:two)
- @coll.list.sort { |a,b| a.to_s <=> b.to_s }.should == [:one, :two]
+ collection.list.sort { |a,b| a.to_s <=> b.to_s }.should == [:one, :two]
end
- it "should have a method for returning a hash of fact values" do
- Facter::Util::Collection.new.should respond_to(:to_hash)
- end
-
describe "when returning a hash of values" do
- before do
- @coll = Facter::Util::Collection.new
- @fact = @coll.add(:one)
- @fact.stubs(:value).returns "me"
- end
-
it "should return a hash of fact names and values with the fact names as strings" do
- @coll.to_hash.should == {"one" => "me"}
+ collection.add(:one, :value => "me")
+
+ collection.to_hash.should == {"one" => "me"}
end
it "should not include facts that did not return a value" do
- f = @coll.add(:two)
- f.stubs(:value).returns nil
- @coll.to_hash.should_not be_include(:two)
+ collection.add(:two, :value => nil)
+
+ collection.to_hash.should_not be_include(:two)
end
end
- it "should have a method for iterating over all facts" do
- Facter::Util::Collection.new.should respond_to(:each)
- end
-
- it "should include Enumerable" do
- Facter::Util::Collection.ancestors.should be_include(Enumerable)
- end
-
describe "when iterating over facts" do
before do
- @coll = Facter::Util::Collection.new
- @one = @coll.add(:one)
- @two = @coll.add(:two)
+ collection.add(:one, :value => "ONE")
+ collection.add(:two, :value => "TWO")
end
it "should yield each fact name and the fact value" do
- @one.stubs(:value).returns "ONE"
- @two.stubs(:value).returns "TWO"
facts = {}
- @coll.each do |fact, value|
+ collection.each do |fact, value|
facts[fact] = value
end
facts.should == {"one" => "ONE", "two" => "TWO"}
end
it "should convert the fact name to a string" do
- @one.stubs(:value).returns "ONE"
- @two.stubs(:value).returns "TWO"
facts = {}
- @coll.each do |fact, value|
+ collection.each do |fact, value|
fact.should be_instance_of(String)
end
end
it "should only yield facts that have values" do
- @one.stubs(:value).returns "ONE"
- @two.stubs(:value).returns nil
+ collection.add(:nil_fact, :value => nil)
facts = {}
- @coll.each do |fact, value|
+ collection.each do |fact, value|
facts[fact] = value
end
- facts.should_not be_include("two")
+ facts.should_not be_include("nil_fact")
+ end
+ end
+
+ describe "when no facts are loaded" do
+ it "should warn when no facts were loaded" do
+ Facter.expects(:warnonce).with("No facts loaded from #{internal_loader.search_path.join(File::PATH_SEPARATOR)}").once
+
+ collection.fact("one")
+ end
+ end
+
+ describe "external facts" do
+ let(:collection) { Facter::Util::Collection.new(internal_loader, SingleFactLoader.new(:test_fact, "fact value")) }
+
+ it "loads when a specific fact is requested" do
+ collection.fact(:test_fact).value.should == "fact value"
+ end
+
+ it "loads when facts are listed" do
+ collection.list.should == [:test_fact]
+ end
+
+ it "loads when all facts are iterated over" do
+ facts = []
+ collection.each { |fact_name, fact_value| facts << [fact_name, fact_value] }
+
+ facts.should == [["test_fact", "fact value"]]
+ end
+ end
+
+ class SingleFactLoader
+ def initialize(name, value)
+ @name = name
+ @value = value
+ end
+
+ def load(collection)
+ collection.add(@name, :value => @value)
end
end
end