Last active
October 4, 2021 07:17
-
-
Save hlindberg/8c250c54f5adb76679576ae5cffff868 to your computer and use it in GitHub Desktop.
An rspec sample showing some override and mocking of 4.x functions/function loading
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
# Example rspec_puppet function rspec test (i.e. subject is the function 'min') | |
# This works for other rspec subjects as well as a compiler is always involved. | |
# This kind of mocking can be required when it is not enough to simply override | |
# a function with another implementation (which can be done with a `let(:pre_condition) { 'function min($x, $y) { ... }'}` | |
# | |
# The main difficulty that this overcomes is the need to let the compiler initialize and | |
# create the context in which it will operate before making any mocks. | |
# | |
describe 'min' do | |
before(:each) { | |
# An instance of compiler is always used - this adds a wrapper around its creation | |
# - the wrapper creates the instance (as if the wrapper did not exists (m.call(*args)) | |
# - the wrapper loads a function (in this case the subject, but could load some other function | |
# the subject function is calling. | |
# - the loaded function is mocked to accept a call, and return absolute smallest possible number | |
# - the created compiler is returned | |
# | |
expect(Puppet::Parser::Compiler).to receive(:new).and_wrap_original do |m,*args| | |
the_compiler = m.call(*args) | |
the_function = the_compiler.loaders.private_environment_loader.load(:function, 'min') | |
expect(the_function).to receive(:call).and_return(-Float::INFINITY) | |
the_compiler | |
end | |
} | |
it { is_expected.to run.with_params(1, 2).and_return(-Float::INFINITY) } | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
require 'puppet/pops' | |
require 'puppet/loaders' | |
require 'puppet_spec/compiler' | |
describe 'a sample function test with override and mocks' do | |
after(:each) { Puppet::Pops::Loaders.clear } | |
let(:loaders) { Puppet::Pops::Loaders.new(Puppet::Node::Environment.create(:testing, [])) } | |
let(:loaded_func) { | |
loaders.private_environment_loader.load(:function, 'assert_type') | |
} | |
let(:dynamic_func) { | |
f = Puppet::Functions.create_function('test_echo') do | |
def test_echo(x) | |
x | |
end | |
end | |
f.new({}, loaders.private_environment_loader) | |
} | |
let(:dynamic_func2) { | |
f = Puppet::Functions.create_function('test_echo') do | |
def test_echo(x) | |
[x, x] | |
end | |
end | |
f.new({}, loaders.private_environment_loader) | |
} | |
it 'can mock an existing function' do | |
loaded_func.expects(:call).returns("I am mocked") | |
expect(loaded_func.call({}, Puppet::Pops::Types::PIntegerType::DEFAULT, 42)).to eq('I am mocked') | |
end | |
it 'can call a dynamically created function' do | |
expect(dynamic_func.call({}, 42)).to eq(42) | |
end | |
it 'can add a dynamically loaded function to the loaders and load it' do | |
loaders.private_environment_loader.add_entry(:function, 'test_echo', dynamic_func, nil) | |
f = loaders.private_environment_loader.load(:function, 'test_echo') | |
expect(f.call({}, 42)).to eq(42) | |
end | |
it 'can add a dynamically loaded function to the loaders, call it, replace it with another and call that' do | |
typed_name = Puppet::Pops::Loader::TypedName.new(:function, 'test_echo') | |
loaders.private_environment_loader.set_entry(typed_name, dynamic_func, nil) | |
f = loaders.private_environment_loader.load_typed(typed_name).value # load_typed returns a wrapper that contains meta data | |
expect(f.call({}, 42)).to eq(42) | |
# drop the loaded | |
loaders.private_environment_loader.remove_entry(typed_name) | |
# add/set new definition of the function | |
loaders.private_environment_loader.set_entry(typed_name, dynamic_func2) | |
f = loaders.private_environment_loader.load_typed(typed_name).value | |
expect(f.call({}, 42)).to eq([42, 42]) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
# Example use of rspec_puppet's `pre_condition` feature. This will define the function `myfunction` before | |
# there is an attempt to load that function from disk. Thus, the function definition in the pre_condition | |
# will win over the otherwise autoloaded function. | |
# This is a simple method of overriding - but requires that what is returned can be expressed in the Puppet | |
# language. | |
describe 'something' do | |
let(:pre_condition) { 'function myfunction() { return "the mocked return" }' } | |
it { # some test | |
} | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment