Skip to content

Commit

Permalink
Add infrastructure for testing custom facts
Browse files Browse the repository at this point in the history
This adds testing of custom facts by placing them in spec/facts, similar
to how classes have spec/classes and defines have spec/defines. The
subject is also set in the same way. It is possible to stub other facts
using a facts block and facts are properly cleared before and after a
run.
  • Loading branch information
ekohl committed Oct 31, 2022
1 parent 8532f22 commit a88d275
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/rspec-puppet/example.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'rspec-puppet/example/type_alias_example_group'
require 'rspec-puppet/example/provider_example_group'
require 'rspec-puppet/example/application_example_group'
require 'rspec-puppet/example/fact_example_group'

RSpec::configure do |c|

Expand All @@ -27,6 +28,7 @@ def c.rspec_puppet_include(group, type, file_path)
c.rspec_puppet_include RSpec::Puppet::TypeAliasExampleGroup, :type_alias, %w[spec type_aliases]
c.rspec_puppet_include RSpec::Puppet::ProviderExampleGroup, :provider, %w[spec providers]
c.rspec_puppet_include RSpec::Puppet::ApplicationExampleGroup, :application, %w[spec applications]
c.rspec_puppet_include RSpec::Puppet::FactExampleGroup, :define, %w[spec facts]

# Hook for each example group type to remove any caches or instance variables, since they will remain
# and cause a memory leak. Can't be assigned per type by :file_path, so check for its presence.
Expand Down
56 changes: 56 additions & 0 deletions lib/rspec-puppet/example/fact_example_group.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module RSpec::Puppet
# This module provides support for custom facts
module FactExampleGroup
def subject
setup_facter do
Facter.fact(self.class.top_level_description)
end
end

# TODO: proper matcher with a description
def have_value(value)
have_attributes(value: value)
end

def rspec_puppet_cleanup
Facter.clear
# TODO: clean LOAD_PATH again?
end

private

# TODO: duplicates adapter
def modulepath
if rspec_modulepath = RSpec.configuration.module_path
rspec_modulepath.split(File::PATH_SEPARATOR)
else
Puppet[:environmentpath].split(File::PATH_SEPARATOR).map do |path|
File.join(path, 'fixtures', 'modules')
end
end
end

def setup_facter
Dir.mktmpdir do |dir|
modulepath.map do |d|
Dir["#{d}/*/lib/facter"].entries.each do |entry|
$LOAD_PATH << File.expand_path(File.dirname(entry))
end
end

Facter.clear

if respond_to?(:facts)
allow(Facter).to receive(:value).and_call_original

facts.each do |fact, value|
# TODO: Facter.fact(fact).value?
allow(Facter).to receive(:value).with(fact.to_sym).and_return(value)
end
end

yield
end
end
end
end
26 changes: 26 additions & 0 deletions spec/facts/custom_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'spec_helper'

describe 'custom' do
it { is_expected.not_to be_nil }
it { is_expected.to have_value('bar') }

context 'with overridden' do
let(:facts) do
{
myfact: 'set',
}
end

it { is_expected.to have_value('foo') }
end

context 'with unrelated fact overridden' do
let(:facts) do
{
kernel: 'unix',
}
end

it { is_expected.to have_value('bar') }
end
end
3 changes: 3 additions & 0 deletions spec/fixtures/modules/custom_fact/lib/facter/custom.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Facter.add(:custom) do
setcode { Facter.value(:myfact) ? 'foo' : 'bar' }
end

0 comments on commit a88d275

Please sign in to comment.