Class: RSpec::Puppet::MatcherHelpers

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec-puppet/matcher_helpers.rb

Overview

A collection of static methods that simplify creating and building rodjek's RSpec::Puppet::*Matchers. With MatcherHelpers, you need call only its .get_matcher_for function with arguments appropriate to the matcher you desire. Otherwise, you have to know in advance which matcher you want and, at first, the relationship between method, matcher, and namespace just isn't always obvious.

Class Method Summary collapse

Class Method Details

.get_compile_matcher(method, args = [], tests = {}) ⇒ Object

Gets a matcher for compile tests.

Examples:

The class compiles with all dependencies, spelled out

matcher = RSpec::Puppet::MatcherHelpers.get_compile_matcher(
  :compile,
  nil,
  { :with_all_deps => nil }
)

The class compiles with all dependencies, simpler

matcher = RSpec::Puppet::MatcherHelpers.get_compile_matcher(
  :compile,
  nil,
  true
)

Parameters:

  • method (Symbol)

    The :compile matcher type.

  • args (Optional[Variant[Integer,Array[Integer]]]) (defaults to: [])

    IGNORED in this version! Should a future version of the compile matcher support constructor arguments, this will become useful.

  • tests (Optional[Hash[Variant[String,Symbol],Any]]) (defaults to: {})

    Set of unit tests to apply to the matcher, expressed as :method_call => value(s) tuples. Use nil as the value for method_calls that don't accept arguments.



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/rspec-puppet/matcher_helpers.rb', line 214

def self.get_compile_matcher(method, args = [], tests = {})
  matcher = RSpec::Puppet::ManifestMatchers::Compile.new

  if tests.kind_of?(Array)
    tests.each { |test| matcher.send(test.to_sym) }
  elsif tests.is_a?(Hash)
    tests.each do |k,v|
      if v.nil? || 'nil' == v.to_s
        matcher.send(k.to_sym)
      else
        matcher.send(k.to_sym, v)
      end
    end
  elsif tests.is_a?(String) || tests.is_a?(Symbol)
    matcher.send(tests)
  elsif !tests.nil?
    # Anything left is assumed to be a 'with_all_deps' test...
    if tests
      # ...as long as it is "truthy"
      matcher.send(:with_all_deps)
    end
  end

  matcher
end

.get_contain_matcher(method, args, tests = {}) ⇒ Object

Gets a matcher for :create_* and :contain_* tests.

Examples:

package { 'my-package': ensure => 'latest', provider => 'apt' }

# Using the all-in-one `with` test
matcher = RSpec::Puppet::MatcherHelpers.get_contain_matcher(
  :contain_package,
  [ 'my-package' ],
  { :with => {
    :ensure   => 'latest',
    :provider => 'apt' }
  }
)

# Using individual with_* tests
matcher = RSpec::Puppet::MatcherHelpers.get_contain_matcher(
  :contain_package,
  [ 'my-package' ],
  { :with_ensure   => 'latest',
    :with_provider => 'apt'
  }
)

Parameters:

  • method (Symbol)

    The full :create_* or :contain_* matcher type.

  • args (Array[Any])

    Must be at least an Array with one element and the first element must be the title of the resource under test. So, for package { 'my-package': ensure => 'latest', provider => 'apt' }, this must be set to [ "my-package" ].

  • tests (Optional[Hash[Variant[String,Symbol],Any]]) (defaults to: {})

    Set of unit tests to apply to the matcher, expressed as :method_call => value(s) tuples. Use nil as the value for method_calls that don't accept arguments.

Raises:

  • (ArgumentError)

    when a resource title is not supplied at args[0].



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/rspec-puppet/matcher_helpers.rb', line 101

def self.get_contain_matcher(method, args, tests = {})
  # For this matcher, args[0] must be a String value that is the title for
  # the resource under test.
  if args.nil? || !args
    raise ArgumentError, "Contain/Create matchers require that the first argument be the title of the resource under test."
  elsif !args.kind_of?(Array)
    args = [ args.to_s ]
  end

  matcher = RSpec::Puppet::ManifestMatchers::CreateGeneric.new(
    method,
    args[0]
  )

  # Try to be lenient on the Hash requirement for tests
  if tests.kind_of?(Array)
    tests.each { |test| matcher.send(test.to_sym) }
  elsif tests.is_a?(Hash)
    tests.each do |k,v|
      if v.nil? || 'nil' == v.to_s
        matcher.send(k.to_sym)
      else
        # Enable content tests to specify arrays so that multiple discrete
        # contents can be searched.
        if k =~ /(with_|without_)?content/ && v.kind_of?(Array)
          v.each{ |l| matcher.send(k.to_sym, l) }
        else
          matcher.send(k.to_sym, v)
        end
      end
    end
  elsif !tests.nil?
    # Anything left is assumed to be an 'ensure' test
    matcher.send(:with_ensure, tests)
  end

  matcher
end

.get_count_matcher(method, args, tests = {}) ⇒ Object

Gets a matcher for have_*_resource_count tests.

Examples:

1 package expected (count as an Array element)

matcher = RSpec::Puppet::MatcherHelpers.get_count_matcher(
  :have_package_resource_count,
  [ 1 ]
)

12 files expected (count as a bare Integer)

matcher = RSpec::Puppet::MatcherHelpers.get_count_matcher(
  :have_file_resource_count,
  12
)

Parameters:

  • method (Symbol)

    The full :have_*_resource_count matcher type.

  • args (Variant[Integer,Array[Integer]])

    May be either an Integer or an Array with exactly one element that is an Integer. This is the number of the expected resource counted.

  • tests (Optional[Hash[Variant[String,Symbol],Any]]) (defaults to: {})

    IGNORED in this version! Should this matcher ever later support additional tests, this will become the set of unit tests to apply to the matcher, expressed as :method_call => value(s)tuples. Usenil` as the value for method_calls that don't accept arguments.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/rspec-puppet/matcher_helpers.rb', line 163

def self.get_count_matcher(method, args, tests = {})
  # This constructor is backward from all the rest and a bit qwirky in that
  # it inexplicably expects method to be an Array and args to be an Integer
  # rather than an Array like all the other matchers.  Further, this one
  # expects to receive method twice, as the first and third parameters or
  # part of method as the first and the whole method as the third or nil as
  # the first and method as the third.  Quite qwirky, indeed!  This helper
  # will steer clear of this qwirkiness by simply passing nil as the first
  # and ensuring that args can be cast as an Integer.
  begin
    if args.kind_of?(Array)
      # Assume the first element of an args array is the intended count
      count = args[0].to_i
    else
      count = args.to_i
    end
  rescue
    raise ArgumentError, "The argument to Count matchers must be a single Integer value."
  end

  RSpec::Puppet::ManifestMatchers::CountGeneric.new(
    nil,
    count,
    method
  )
end

.get_function_matcher(method, args = [], tests = []) ⇒ Object

Gets a matcher for function (:run) tests.

Examples:

Test a function that strips known extensions off file-names

matcher = RSpec::Puppet::MatcherHelpers.get_function_matcher(
  :run,
  nil,
  [ '/some/arbitrary/path.ext', 'ext' ]
)

Parameters:

  • method (Symbol)

    The :run matcher type.

  • args (Optional[Variant[Integer,Array[Integer]]]) (defaults to: [])

    IGNORED in this version! Should a future version of the compile matcher support constructor arguments, this will become useful.

  • tests (Optional[Variant[Symbol,String,Array[Any],Hash[Any,Any]]]) (defaults to: [])

    Set of unit tests to apply to the matcher. Many forms of expressing these tests is supported, though the best fit is Array[Any], which is passed as-is to the function under test as its parameters.



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/rspec-puppet/matcher_helpers.rb', line 257

def self.get_function_matcher(method, args = [], tests = [])
  matcher = RSpec::Puppet::FunctionMatchers::Run.new

  if tests.is_a?(Hash)
    tests.each do |k,v|
      if v.nil? || 'nil' == v.to_s
        matcher.send(k.to_sym)
      else
        matcher.send(k.to_sym, v)
      end
    end
  elsif tests.is_a?(String) || tests.is_a?(Symbol)
    matcher.send(tests)
  elsif !tests.nil?
    # Anything left is assumed to be a 'with_params' test, which expects an
    # Array.
    if tests.kind_of?(Array)
      matcher.send(:with_params, tests)
    else
      matcher.send(:with_params, [tests])
    end
  end

  matcher
end

.get_matcher_for(method, args, tests = {}) ⇒ Object

Attempts to create and return an appropriate RSpec::Puppet::*Matcher for a known matching method and its arguments. If tests are provided and the matcher supports them, the matcher will be built up with the tests.

Parameters:

  • method (Variant[String,Symbol])

    A recognizable RSpec::Puppet matcher; one of: contain_, create_, have_*_count, compile, run, or be_valid_type (where * is a known resource type).

  • args (Array[Any])

    Arguments to pass to the matcher during construction, if it accepts any.

  • tests (Optional[Hash[Variant[String,Symbol],Any]]) (defaults to: {})

    Set of unit tests to apply to the matcher, expressed as :method_call => value(s) tuples. Use nil as the value for method_calls that don't accept arguments.

Returns:

  • (Object)

    An RSpec::Puppet matcher that knows how to handle method and is loaded with tests.

Raises:

  • (NameError)

    when method is unrecognizable.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rspec-puppet/matcher_helpers.rb', line 27

def self.get_matcher_for(method, args, tests = {})
  method_str = method.nil? ? 'nil' : method.to_s
  method_sym = method.nil? ? :nil : method.to_sym

  case method_str
  when /^(contain|create)_.+$/
    matcher = RSpec::Puppet::MatcherHelpers.get_contain_matcher(
      method_sym,
      args,
      tests
    )
  when /^have_.+_count$/
    matcher = RSpec::Puppet::MatcherHelpers.get_count_matcher(
      method_sym,
      args,
      tests
    )
  when 'compile'
    matcher = RSpec::Puppet::MatcherHelpers.get_compile_matcher(
      method_sym,
      args,
      tests
    )
  when 'run'
    matcher = RSpec::Puppet::MatcherHelpers.get_function_matcher(
      method_sym,
      args,
      tests
    )
  when 'be_valid_type'
    matcher = RSpec::Puppet::MatcherHelpers.get_type_matcher(
      method_sym,
      args,
      tests
    )
  else
    raise NameError, "Unknown matcher method:  #{method_str}.  See http://rspec-puppet.com/matchers/ for valid matchers."
  end

  matcher
end

.get_type_matcher(method, args = [], tests = {}) ⇒ Object

Gets a matcher for custom type (:be_valid_type) tests.

Examples:

With a particular provider (simple)

matcher = RSpec::Puppet::MatcherHelpers.get_type_matcher(
  :be_valid_type,
  nil,
  :apt
)

With a particular provider (spelled out)

matcher = RSpec::Puppet::MatcherHelpers.get_type_matcher(
  :be_valid_type,
  nil,
  { :with_provider => :apt }
)

Parameters:

  • method (Symbol)

    The :be_valid_type matcher type.

  • args (Optional[Variant[Integer,Array[Integer]]]) (defaults to: [])

    IGNORED in this version! Should a future version of RSpec::Puppet::TypeMatchers::CreateGeneric support constructor arguments, this will become useful.

  • tests (Optional[Hash[Variant[String,Symbol],Any]]) (defaults to: {})

    Set of unit tests to apply to the matcher, expressed as :method_call => value(s) tuples. Use nil as the value for method_calls that don't accept arguments.



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/rspec-puppet/matcher_helpers.rb', line 308

def self.get_type_matcher(method, args = [], tests = {})
  matcher = RSpec::Puppet::TypeMatchers::CreateGeneric.new(
    method,
    args
  )

  if tests.kind_of?(Array)
    tests.each { |test| matcher.send(test.to_sym) }
  elsif tests.is_a?(Hash)
    tests.each do |k,v|
      if v.nil? || 'nil' == v.to_s
        matcher.send(k.to_sym)
      else
        matcher.send(k.to_sym, v)
      end
    end
  elsif !tests.nil?
    # Anything left is assumed to be a 'with_provider' test
    matcher.send(:with_provider, tests)
  end

  matcher
end