diff --git a/lib/puppet/functions/assert_type.rb b/lib/puppet/functions/assert_type.rb new file mode 100644 index 000000000..9b2ce2d15 --- /dev/null +++ b/lib/puppet/functions/assert_type.rb @@ -0,0 +1,16 @@ +# Returns the give value if it is an instance of the given type, and raises an error otherwise. +# +Puppet::Functions.create_function(:assert_type) do + dispatch :assert_type do + param type_type(), 'type' + param optional(object()), 'value' + end + + def assert_type(type, value) + unless Puppet::Pops::Types::TypeCalculator.instance?(type,value) + inferred_type = Puppet::Pops::Types::TypeCalculator.infer(value) + raise ArgumentError, "assert_type(): Expected type #{type} does not match actual: #{inferred_type}" + end + value + end +end diff --git a/spec/unit/functions/assert_type_spec.rb b/spec/unit/functions/assert_type_spec.rb new file mode 100644 index 000000000..76d3222a6 --- /dev/null +++ b/spec/unit/functions/assert_type_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' +require 'puppet/pops' +require 'puppet/loaders' + +describe 'the assert_type function' do + + after(:all) { Puppet::Pops::Loaders.clear } + let(:func) do + loaders = Puppet::Pops::Loaders.new() + loaders.puppet_system_loader.load(:function, 'assert_type') + end + it 'asserts compliant type by returning the value' do +# loaders = Puppet::Pops::Loaders.new() +# func = loaders.puppet_system_loader.load(:function, 'assert_type') + expect(func.call({}, type(String), 'hello world')).to eql('hello world') + end + + it 'asserts non compliant type by raising an error' do + expect do + func.call({}, type(Integer), 'hello world') + end.to raise_error(ArgumentError, /does not match actual/) + end + + it 'checks that first argument is a type' do + expect do + func.call({}, 10, 10) + end.to raise_error(ArgumentError, Regexp.new(Regexp.escape( +"function 'assert_type' called with mis-matched arguments +expected: + assert_type(Type type, Optional[Object] value) - arg count {2} +actual: + assert_type(Integer, Integer) - arg count {2}"))) + end + + it 'allows the second arg to be undef/nil)' do + expect do + func.call({}, optional(String), nil) + end.to_not raise_error(ArgumentError) + end + + def optional(type_ref) + Puppet::Pops::Types::TypeFactory.optional(type(type_ref)) + end + + def type(type_ref) + Puppet::Pops::Types::TypeFactory.type_of(type_ref) + end +end