rspec-puppet 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -1
- data/README.md +93 -2
- data/lib/rspec-puppet/example.rb +5 -0
- data/lib/rspec-puppet/example/application_example_group.rb +19 -0
- data/lib/rspec-puppet/example/function_example_group.rb +79 -16
- data/lib/rspec-puppet/matchers/run.rb +5 -21
- data/lib/rspec-puppet/raw_string.rb +16 -0
- data/lib/rspec-puppet/setup.rb +1 -1
- data/lib/rspec-puppet/support.rb +68 -24
- metadata +4 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 1a4f52ea0428c49bc328570e7a71776b75b800b2
         | 
| 4 | 
            +
              data.tar.gz: 461fadebe1cd4756715a99d54fefdf51c020a17b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 8f79f8be40bf4e2c77e11ddf68130ea0fe97b8e629cf4768c2da1a15a096ed65fad3dff160208a36b9d221f652564956fc15113b56589562a8890c01a4678098
         | 
| 7 | 
            +
              data.tar.gz: bc64b10392874054ebf8cfe7712abc25874bfa3d44ebd3c6dced81d3eae7c99b359754dd3d74481dfc1851264ce347f8f76990e0022f8e653b622a77ade449d5
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,6 +2,25 @@ | |
| 2 2 | 
             
            All notable changes to this project will be documented in this file. This
         | 
| 3 3 | 
             
            project adheres to [Semantic Versioning](http://semver.org/).
         | 
| 4 4 |  | 
| 5 | 
            +
            ## [2.5.0]
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Headline features are app management, nested hashes in params, and testing for "internal" functions.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Thanks to everyone who contributed: Leo Arnold, Matt Schuchard, and Si Wilkins
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ### Changed
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * Updates to the README
         | 
| 14 | 
            +
            * Improve Gemfile to work with older rubies
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            ### Added
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            * Add support for app management testing
         | 
| 19 | 
            +
            * Enable nested hashes in params
         | 
| 20 | 
            +
            * After refactoring the function test code, puppet 4 "internal" functions can now be tested too
         | 
| 21 | 
            +
            * Link functions and types on setup
         | 
| 22 | 
            +
            * Increased test coverage
         | 
| 23 | 
            +
             | 
| 5 24 | 
             
            ## [2.4.0]
         | 
| 6 25 |  | 
| 7 26 | 
             
            This release now supports testing exported resources in the same way that normal resources in the catalog are tested. Access them in your examples using `exported_resources`. See "Testing Exported Resources" in the README for examples.
         | 
| @@ -114,7 +133,8 @@ Thanks to Adrien Thebo, Alex Harvey, Brian, Dan Bode, Dominic Cleal, Javier Pala | |
| 114 133 | 
             
            ## 1.0.1 and earlier
         | 
| 115 134 | 
             
            For changelog of versions 1.0.1 and earlier, see http://rspec-puppet.com/changelog/
         | 
| 116 135 |  | 
| 117 | 
            -
            [2.x]: https://github.com/rodjek/rspec-puppet/compare/v2. | 
| 136 | 
            +
            [2.x]: https://github.com/rodjek/rspec-puppet/compare/v2.5.0...master
         | 
| 137 | 
            +
            [2.5.0]: https://github.com/rodjek/rspec-puppet/compare/v2.4.0...v2.5.0
         | 
| 118 138 | 
             
            [2.4.0]: https://github.com/rodjek/rspec-puppet/compare/v2.3.2...v2.4.0
         | 
| 119 139 | 
             
            [2.3.2]: https://github.com/rodjek/rspec-puppet/compare/v2.3.1...v2.3.2
         | 
| 120 140 | 
             
            [2.3.1]: https://github.com/rodjek/rspec-puppet/compare/v2.3.0...v2.3.1
         | 
    
        data/README.md
    CHANGED
    
    | @@ -37,6 +37,10 @@ structure and naming convention. | |
| 37 37 | 
             
                       |     |
         | 
| 38 38 | 
             
                       |     +-- <define_name>_spec.rb
         | 
| 39 39 | 
             
                       |
         | 
| 40 | 
            +
                       +-- applications
         | 
| 41 | 
            +
                       |     |
         | 
| 42 | 
            +
                       |     +-- <application_name>_spec.rb
         | 
| 43 | 
            +
                       |
         | 
| 40 44 | 
             
                       +-- functions
         | 
| 41 45 | 
             
                       |     |
         | 
| 42 46 | 
             
                       |     +-- <function_name>_spec.rb
         | 
| @@ -64,6 +68,10 @@ describe 'mydefine', :type => :define do | |
| 64 68 | 
             
              ...
         | 
| 65 69 | 
             
            end
         | 
| 66 70 |  | 
| 71 | 
            +
            describe 'myapplication', :type => :application do
         | 
| 72 | 
            +
              ...
         | 
| 73 | 
            +
            end
         | 
| 74 | 
            +
             | 
| 67 75 | 
             
            describe 'myfunction', :type => :puppet_function do
         | 
| 68 76 | 
             
              ...
         | 
| 69 77 | 
             
            end
         | 
| @@ -77,7 +85,7 @@ describe 'myhost.example.com', :type => :host do | |
| 77 85 | 
             
            end
         | 
| 78 86 | 
             
            ```
         | 
| 79 87 |  | 
| 80 | 
            -
            ## Defined Types &  | 
| 88 | 
            +
            ## Defined Types, Classes & Applications
         | 
| 81 89 |  | 
| 82 90 | 
             
            ### Matchers
         | 
| 83 91 |  | 
| @@ -354,16 +362,45 @@ let(:title) { 'foo' } | |
| 354 362 |  | 
| 355 363 | 
             
            #### Specifying the parameters to pass to a resources or parameterised class
         | 
| 356 364 |  | 
| 365 | 
            +
            Parameters of a defined type, class or application can be passed defining `:params` in a let,
         | 
| 366 | 
            +
            and passing it a hash as seen below.
         | 
| 367 | 
            +
             | 
| 357 368 | 
             
            ```ruby
         | 
| 358 369 | 
             
            let(:params) { {:ensure => 'present', ...} }
         | 
| 359 370 | 
             
            ```
         | 
| 360 371 |  | 
| 361 | 
            -
             | 
| 372 | 
            +
            For passing Puppet's `undef` as a paremeter value, you can simply use `:undef` and it will
         | 
| 373 | 
            +
            be translated to `undef` when compiling. For example:
         | 
| 362 374 |  | 
| 363 375 | 
             
            ```ruby
         | 
| 364 376 | 
             
            let(:params) { {:user => :undef, ...} }
         | 
| 365 377 | 
             
            ```
         | 
| 366 378 |  | 
| 379 | 
            +
            For references to nodes or resources as seen when using `require` or `before` properties,
         | 
| 380 | 
            +
            or an `application` resource you can pass the string as an argument to the `ref` helper:
         | 
| 381 | 
            +
             | 
| 382 | 
            +
            ```ruby
         | 
| 383 | 
            +
            let(:params) { :require => ref('Package', 'sudoku') }
         | 
| 384 | 
            +
            ```
         | 
| 385 | 
            +
             | 
| 386 | 
            +
            Which translates to:
         | 
| 387 | 
            +
             | 
| 388 | 
            +
            ```puppet
         | 
| 389 | 
            +
            mydefine { 'mytitle': require => Package['sudoku'] }
         | 
| 390 | 
            +
            ```
         | 
| 391 | 
            +
             | 
| 392 | 
            +
            Another example, for an application setup (when using `app_management`):
         | 
| 393 | 
            +
             | 
| 394 | 
            +
            ```ruby
         | 
| 395 | 
            +
            let(:params) { { :nodes => { ref('Node', 'dbnode') => ref('Myapp::Mycomponent', 'myapp') } } }
         | 
| 396 | 
            +
            ```
         | 
| 397 | 
            +
             | 
| 398 | 
            +
            Will translate to:
         | 
| 399 | 
            +
             | 
| 400 | 
            +
            ```puppet
         | 
| 401 | 
            +
            site { myapp { 'myimpl': nodes => { Node['dbnode'] => Myapp::Mycomponent['myimpl'] } } }
         | 
| 402 | 
            +
            ```
         | 
| 403 | 
            +
             | 
| 367 404 | 
             
            #### Specifying the FQDN of the test node
         | 
| 368 405 |  | 
| 369 406 | 
             
            If the manifest you're testing expects to run on host with a particular name,
         | 
| @@ -450,6 +487,46 @@ You can also use `exported_resources` directly in a test: | |
| 450 487 | 
             
            it { expect(exported_resources).to contain_file('foo') }
         | 
| 451 488 | 
             
            ```
         | 
| 452 489 |  | 
| 490 | 
            +
            #### Testing applications
         | 
| 491 | 
            +
             | 
| 492 | 
            +
            Applications in some ways behave as defined resources, but are more complex so
         | 
| 493 | 
            +
            require a number of elements already documented above to be combined for testing.
         | 
| 494 | 
            +
             | 
| 495 | 
            +
            A full example of the simplest rspec test for a single component application:
         | 
| 496 | 
            +
             | 
| 497 | 
            +
            ```ruby
         | 
| 498 | 
            +
            require 'spec_helper'
         | 
| 499 | 
            +
             | 
| 500 | 
            +
            describe 'orch_app' do
         | 
| 501 | 
            +
              let(:node) { 'my_node' }
         | 
| 502 | 
            +
              let(:title) { 'my_awesome_app' }
         | 
| 503 | 
            +
              let(:params) do
         | 
| 504 | 
            +
                {
         | 
| 505 | 
            +
                  :nodes => {
         | 
| 506 | 
            +
                    ref('Node', node) => ref('Orch_app::Db', title),
         | 
| 507 | 
            +
                  }
         | 
| 508 | 
            +
                }
         | 
| 509 | 
            +
              end
         | 
| 510 | 
            +
             | 
| 511 | 
            +
              it { should compile }
         | 
| 512 | 
            +
              it { should contain_orch_app(title) }
         | 
| 513 | 
            +
            end
         | 
| 514 | 
            +
            ```
         | 
| 515 | 
            +
             | 
| 516 | 
            +
            Each piece is required:
         | 
| 517 | 
            +
             | 
| 518 | 
            +
            * You must turn on app_management during testing for the handling to work
         | 
| 519 | 
            +
            * The `:node` definition is required to be set so later on you can reference it in the `:nodes` argument within `:params`
         | 
| 520 | 
            +
            * Applications act like defined resources, and each require a `:title` to be defined
         | 
| 521 | 
            +
            * The `:nodes` key in `:params` requires the use of node reference mappings to resource
         | 
| 522 | 
            +
              mappings. The `ref` keyword allows you to provide these (a normal string will not work).
         | 
| 523 | 
            +
             | 
| 524 | 
            +
            Beyond these requirements, the very basic `should compile` test and other matchers
         | 
| 525 | 
            +
            as you would expect will work the same as classes and defined resources.
         | 
| 526 | 
            +
             | 
| 527 | 
            +
            **Note:** for the moment, cross-node support is not available and will return an error.
         | 
| 528 | 
            +
            Ensure you model your tests to be single-node for the time being.
         | 
| 529 | 
            +
             | 
| 453 530 | 
             
            ## Functions
         | 
| 454 531 |  | 
| 455 532 | 
             
            ### Matchers
         | 
| @@ -554,6 +631,20 @@ before(:each) { scope.expects(:lookupvar).with('some_variable').returns('some_va | |
| 554 631 | 
             
            it { is_expected.to run.with_params('...').and_return('...') }
         | 
| 555 632 | 
             
            ```
         | 
| 556 633 |  | 
| 634 | 
            +
            Note that this does not work when testing manifests which use custom functions. Instead,
         | 
| 635 | 
            +
            you'll need to create a replacement function directly.
         | 
| 636 | 
            +
             | 
| 637 | 
            +
            ```ruby
         | 
| 638 | 
            +
            before(:each) do
         | 
| 639 | 
            +
                Puppet::Parser::Functions.newfunction(:custom_function, :type => :rvalue) { |args|
         | 
| 640 | 
            +
                    raise ArgumentError, 'expected foobar' unless args[0] == 'foobar'
         | 
| 641 | 
            +
                    'expected value'
         | 
| 642 | 
            +
                }
         | 
| 643 | 
            +
            end
         | 
| 644 | 
            +
             | 
| 645 | 
            +
            ```
         | 
| 646 | 
            +
             | 
| 647 | 
            +
             | 
| 557 648 | 
             
            ## Hiera integration
         | 
| 558 649 |  | 
| 559 650 | 
             
            ### Configuration
         | 
    
        data/lib/rspec-puppet/example.rb
    CHANGED
    
    | @@ -5,6 +5,7 @@ require 'rspec-puppet/example/function_example_group' | |
| 5 5 | 
             
            require 'rspec-puppet/example/host_example_group'
         | 
| 6 6 | 
             
            require 'rspec-puppet/example/type_example_group'
         | 
| 7 7 | 
             
            require 'rspec-puppet/example/provider_example_group'
         | 
| 8 | 
            +
            require 'rspec-puppet/example/application_example_group'
         | 
| 8 9 |  | 
| 9 10 | 
             
            RSpec::configure do |c|
         | 
| 10 11 |  | 
| @@ -31,6 +32,9 @@ RSpec::configure do |c| | |
| 31 32 | 
             
                c.include RSpec::Puppet::ProviderExampleGroup, :type => :provider, :example_group => {
         | 
| 32 33 | 
             
                  :file_path => c.escaped_path(%w[spec providers])
         | 
| 33 34 | 
             
                }
         | 
| 35 | 
            +
                c.include RSpec::Puppet::ApplicationExampleGroup, :type => :application, :example_group => {
         | 
| 36 | 
            +
                  :file_path => c.escaped_path(%w[spec applications])
         | 
| 37 | 
            +
                }
         | 
| 34 38 | 
             
              else
         | 
| 35 39 | 
             
                c.include RSpec::Puppet::DefineExampleGroup, :type => :define, :file_path => c.escaped_path(%w[spec defines])
         | 
| 36 40 | 
             
                c.include RSpec::Puppet::ClassExampleGroup, :type => :class, :file_path => c.escaped_path(%w[spec classes])
         | 
| @@ -38,6 +42,7 @@ RSpec::configure do |c| | |
| 38 42 | 
             
                c.include RSpec::Puppet::HostExampleGroup, :type => :host, :file_path => c.escaped_path(%w[spec hosts])
         | 
| 39 43 | 
             
                c.include RSpec::Puppet::TypeExampleGroup, :type => :type, :file_path => c.escaped_path(%w[spec types])
         | 
| 40 44 | 
             
                c.include RSpec::Puppet::ProviderExampleGroup, :type => :provider, :file_path => c.escaped_path(%w[spec providers])
         | 
| 45 | 
            +
                c.include RSpec::Puppet::ApplicationExampleGroup, :type => :application, :file_path => c.escaped_path(%w[spec applications])
         | 
| 41 46 | 
             
              end
         | 
| 42 47 |  | 
| 43 48 | 
             
              # Hook for each example group type to remove any caches or instance variables, since they will remain
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module RSpec::Puppet
         | 
| 2 | 
            +
              # This module provides support for the application type
         | 
| 3 | 
            +
              module ApplicationExampleGroup
         | 
| 4 | 
            +
                include RSpec::Puppet::ManifestMatchers
         | 
| 5 | 
            +
                include RSpec::Puppet::Support
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def catalogue
         | 
| 8 | 
            +
                  @catalogue ||= load_catalogue(:application)
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def exported_resources
         | 
| 12 | 
            +
                  lambda { load_catalogue(:application, true) }
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def rspec_puppet_cleanup
         | 
| 16 | 
            +
                  @catalogue = nil
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -4,27 +4,87 @@ module RSpec::Puppet | |
| 4 4 | 
             
                include RSpec::Puppet::ManifestMatchers
         | 
| 5 5 | 
             
                include RSpec::Puppet::Support
         | 
| 6 6 |  | 
| 7 | 
            +
                class V4FunctionWrapper
         | 
| 8 | 
            +
                  attr_reader :func, :func_name
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def initialize(name, func, overrides)
         | 
| 11 | 
            +
                    @func_name = name
         | 
| 12 | 
            +
                    @func = func
         | 
| 13 | 
            +
                    @overrides = overrides
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # This method is used by the `run` matcher to trigger the function execution, and provides a uniform interface across all puppet versions.
         | 
| 17 | 
            +
                  def execute(*args)
         | 
| 18 | 
            +
                    Puppet.override(@overrides, "rspec-test scope") do
         | 
| 19 | 
            +
                      @func.call(@overrides[:global_scope], *args)
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  # compatibility alias for existing tests
         | 
| 24 | 
            +
                  def call(scope, *args)
         | 
| 25 | 
            +
                    RSpec.deprecate("subject.call", :replacement => "is_expected.to run.with().and_raise_error(), or execute()")
         | 
| 26 | 
            +
                    execute(*args)
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                class V3FunctionWrapper
         | 
| 31 | 
            +
                  attr_accessor :func_name
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def initialize(name, func)
         | 
| 34 | 
            +
                    @func_name = name
         | 
| 35 | 
            +
                    @func = func
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  # This method is used by the `run` matcher to trigger the function execution, and provides a uniform interface across all puppet versions.
         | 
| 39 | 
            +
                  def execute(*args)
         | 
| 40 | 
            +
                    if args.nil?
         | 
| 41 | 
            +
                      @func.call
         | 
| 42 | 
            +
                    else
         | 
| 43 | 
            +
                      @func.call(args)
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # This method was formerly used by the `run` matcher to trigger the function execution, and provides puppet versions dependant interface.
         | 
| 48 | 
            +
                  def call(*args)
         | 
| 49 | 
            +
                    RSpec.deprecate("subject.call", :replacement => "is_expected.to run.with().and_raise_error(), or execute()")
         | 
| 50 | 
            +
                    if args.nil?
         | 
| 51 | 
            +
                      @func.call
         | 
| 52 | 
            +
                    else
         | 
| 53 | 
            +
                      @func.call(*args)
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                # (at least) rspec 3.5 doesn't seem to memoize `subject` when called from
         | 
| 59 | 
            +
                # a before(:each) hook, so we need to memoize it ourselves.
         | 
| 7 60 | 
             
                def subject
         | 
| 8 | 
            -
                   | 
| 61 | 
            +
                  @subject ||= find_function
         | 
| 62 | 
            +
                end
         | 
| 9 63 |  | 
| 10 | 
            -
             | 
| 64 | 
            +
                def find_function
         | 
| 65 | 
            +
                  function_name = self.class.top_level_description.downcase
         | 
| 11 66 |  | 
| 12 | 
            -
                   | 
| 67 | 
            +
                  with_vardir do
         | 
| 13 68 | 
             
                    env = adapter.current_environment
         | 
| 14 | 
            -
                    loader = Puppet::Pops::Loaders.new(env)
         | 
| 15 | 
            -
                    func = loader.private_environment_loader.load(:function,function_name)
         | 
| 16 | 
            -
                    return func if func
         | 
| 17 | 
            -
                  end
         | 
| 18 69 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 70 | 
            +
                    if Puppet.version.to_f >= 4.0
         | 
| 71 | 
            +
                      context_overrides = compiler.context_overrides
         | 
| 72 | 
            +
                      func = nil
         | 
| 73 | 
            +
                      Puppet.override(context_overrides, "rspec-test scope") do
         | 
| 74 | 
            +
                        loader = Puppet::Pops::Loaders.new(env)
         | 
| 75 | 
            +
                        func = V4FunctionWrapper.new(function_name, loader.private_environment_loader.load(:function, function_name), context_overrides)
         | 
| 76 | 
            +
                        @scope = context_overrides[:global_scope]
         | 
| 77 | 
            +
                      end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                      return func if func.func
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                    if Puppet::Parser::Functions.function(function_name)
         | 
| 83 | 
            +
                      V3FunctionWrapper.new(function_name, scope.method("function_#{function_name}".intern))
         | 
| 84 | 
            +
                    else
         | 
| 85 | 
            +
                      nil
         | 
| 86 | 
            +
                    end
         | 
| 25 87 | 
             
                  end
         | 
| 26 | 
            -
                  FileUtils.rm_rf(vardir) if File.directory?(vardir)
         | 
| 27 | 
            -
                  scope.method("function_#{function_name}".intern)
         | 
| 28 88 | 
             
                end
         | 
| 29 89 |  | 
| 30 90 | 
             
                def scope
         | 
| @@ -36,6 +96,7 @@ module RSpec::Puppet | |
| 36 96 | 
             
                end
         | 
| 37 97 |  | 
| 38 98 | 
             
                def rspec_puppet_cleanup
         | 
| 99 | 
            +
                  @subject = nil
         | 
| 39 100 | 
             
                  @catalogue = nil
         | 
| 40 101 | 
             
                  @compiler = nil
         | 
| 41 102 | 
             
                  @scope = nil
         | 
| @@ -71,7 +132,9 @@ module RSpec::Puppet | |
| 71 132 | 
             
                end
         | 
| 72 133 |  | 
| 73 134 | 
             
                def build_scope(compiler, node_name)
         | 
| 74 | 
            -
                  if Puppet.version  | 
| 135 | 
            +
                  if Puppet.version.to_f >= 4.0
         | 
| 136 | 
            +
                    return compiler.context_overrides[:global_scope]
         | 
| 137 | 
            +
                  elsif Puppet.version =~ /^2\.[67]/
         | 
| 75 138 | 
             
                    # loadall should only be necessary prior to 3.x
         | 
| 76 139 | 
             
                    # Please note, loadall needs to happen first when creating a scope, otherwise
         | 
| 77 140 | 
             
                    # you might receive undefined method `function_*' errors
         | 
| @@ -3,23 +3,11 @@ module RSpec::Puppet | |
| 3 3 | 
             
                class Run
         | 
| 4 4 | 
             
                  def matches?(func_obj)
         | 
| 5 5 | 
             
                    @func_obj = func_obj
         | 
| 6 | 
            -
                    if @params
         | 
| 7 | 
            -
                      if Puppet.version.to_f >= 4.0 and ! @func_obj.respond_to?(:receiver)
         | 
| 8 | 
            -
                        @func = lambda { func_obj.call({}, *@params) }
         | 
| 9 | 
            -
                      else
         | 
| 10 | 
            -
                        @func = lambda { func_obj.call(@params) }
         | 
| 11 | 
            -
                      end
         | 
| 12 | 
            -
                    else
         | 
| 13 | 
            -
                      if Puppet.version.to_f >= 4.0 and ! @func_obj.respond_to?(:receiver)
         | 
| 14 | 
            -
                        @func = lambda { func_obj.call({}) }
         | 
| 15 | 
            -
                      else
         | 
| 16 | 
            -
                        @func = lambda { func_obj.call }
         | 
| 17 | 
            -
                      end
         | 
| 18 | 
            -
                    end
         | 
| 19 6 |  | 
| 20 7 | 
             
                    @has_returned = false
         | 
| 21 8 | 
             
                    begin
         | 
| 22 | 
            -
                       | 
| 9 | 
            +
                      # `*nil` does not evaluate to "no params" on ruby 1.8 :-(
         | 
| 10 | 
            +
                      @actual_return = @params.nil? ? @func_obj.execute : @func_obj.execute(*@params)
         | 
| 23 11 | 
             
                      @has_returned = true
         | 
| 24 12 | 
             
                    rescue Exception => e
         | 
| 25 13 | 
             
                      @actual_error = e
         | 
| @@ -113,11 +101,7 @@ module RSpec::Puppet | |
| 113 101 |  | 
| 114 102 | 
             
                  private
         | 
| 115 103 | 
             
                  def func_name
         | 
| 116 | 
            -
                     | 
| 117 | 
            -
                      @func_name ||= @func_obj.class.name
         | 
| 118 | 
            -
                    else
         | 
| 119 | 
            -
                      @func_name ||= @func_obj.name.to_s.gsub(/^function_/, '')
         | 
| 120 | 
            -
                    end
         | 
| 104 | 
            +
                    @func_obj.func_name
         | 
| 121 105 | 
             
                  end
         | 
| 122 106 |  | 
| 123 107 | 
             
                  def func_params
         | 
| @@ -129,9 +113,9 @@ module RSpec::Puppet | |
| 129 113 | 
             
                      ''
         | 
| 130 114 | 
             
                    elsif @actual_error
         | 
| 131 115 | 
             
                      if @has_expected_return
         | 
| 132 | 
            -
                        " instead of raising #{@actual_error.class.inspect}(#{@actual_error})"
         | 
| 116 | 
            +
                        " instead of raising #{@actual_error.class.inspect}(#{@actual_error})\n#{@actual_error.backtrace.join("\n")}"
         | 
| 133 117 | 
             
                      else
         | 
| 134 | 
            -
                        " instead of #{@actual_error.class.inspect}(#{@actual_error})"
         | 
| 118 | 
            +
                        " instead of #{@actual_error.class.inspect}(#{@actual_error})\n#{@actual_error.backtrace.join("\n")}"
         | 
| 135 119 | 
             
                      end
         | 
| 136 120 | 
             
                    else # function has returned
         | 
| 137 121 | 
             
                      if @has_expected_error
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            module RSpec::Puppet
         | 
| 2 | 
            +
              # A raw string object, that is used by helpers to allow consumers to return non-quoted strings
         | 
| 3 | 
            +
              # as part of their params section.
         | 
| 4 | 
            +
              class RawString
         | 
| 5 | 
            +
                # Create a new RawString object
         | 
| 6 | 
            +
                # @param [String] value string to wrap
         | 
| 7 | 
            +
                def initialize(value)
         | 
| 8 | 
            +
                  @value = value
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                # @return [String] raw string
         | 
| 12 | 
            +
                def inspect
         | 
| 13 | 
            +
                  @value
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
    
        data/lib/rspec-puppet/setup.rb
    CHANGED
    
    | @@ -34,7 +34,7 @@ module RSpec::Puppet | |
| 34 34 |  | 
| 35 35 | 
             
                  safe_touch('spec/fixtures/manifests/site.pp')
         | 
| 36 36 |  | 
| 37 | 
            -
                  %w(data manifests lib files templates).each do |dir|
         | 
| 37 | 
            +
                  %w(data manifests lib files templates functions types).each do |dir|
         | 
| 38 38 | 
             
                    if File.exist? dir
         | 
| 39 39 | 
             
                      safe_make_symlink("../../../../#{dir}", "spec/fixtures/modules/#{module_name}/#{dir}")
         | 
| 40 40 | 
             
                    end
         | 
    
        data/lib/rspec-puppet/support.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            require 'rspec-puppet/cache'
         | 
| 2 2 | 
             
            require 'rspec-puppet/adapters'
         | 
| 3 | 
            +
            require 'rspec-puppet/raw_string'
         | 
| 3 4 |  | 
| 4 5 | 
             
            module RSpec::Puppet
         | 
| 5 6 | 
             
              module Support
         | 
| @@ -15,26 +16,25 @@ module RSpec::Puppet | |
| 15 16 | 
             
                end
         | 
| 16 17 |  | 
| 17 18 | 
             
                def load_catalogue(type, exported = false)
         | 
| 18 | 
            -
                   | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
                     | 
| 22 | 
            -
             | 
| 23 | 
            -
                     | 
| 24 | 
            -
                  end
         | 
| 19 | 
            +
                  with_vardir do
         | 
| 20 | 
            +
                    if Puppet.version.to_f >= 4.0 or Puppet[:parser] == 'future'
         | 
| 21 | 
            +
                      code = [pre_cond, test_manifest(type)].compact.join("\n")
         | 
| 22 | 
            +
                    else
         | 
| 23 | 
            +
                      code = [import_str, pre_cond, test_manifest(type)].compact.join("\n")
         | 
| 24 | 
            +
                    end
         | 
| 25 25 |  | 
| 26 | 
            -
             | 
| 26 | 
            +
                    node_name = nodename(type)
         | 
| 27 27 |  | 
| 28 | 
            -
             | 
| 28 | 
            +
                    hiera_config_value = self.respond_to?(:hiera_config) ? hiera_config : nil
         | 
| 29 29 |  | 
| 30 | 
            -
             | 
| 30 | 
            +
                    catalogue = build_catalog(node_name, facts_hash(node_name), hiera_config_value, code, exported)
         | 
| 31 31 |  | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 32 | 
            +
                    test_module = class_name.split('::').first
         | 
| 33 | 
            +
                    RSpec::Puppet::Coverage.add_filter(type.to_s, self.class.description)
         | 
| 34 | 
            +
                    RSpec::Puppet::Coverage.add_from_catalog(catalogue, test_module)
         | 
| 35 35 |  | 
| 36 | 
            -
             | 
| 37 | 
            -
                   | 
| 36 | 
            +
                    catalogue
         | 
| 37 | 
            +
                  end
         | 
| 38 38 | 
             
                end
         | 
| 39 39 |  | 
| 40 40 | 
             
                def import_str
         | 
| @@ -68,6 +68,12 @@ module RSpec::Puppet | |
| 68 68 | 
             
                    else
         | 
| 69 69 | 
             
                      "class { '#{class_name}': #{param_str} }"
         | 
| 70 70 | 
             
                    end
         | 
| 71 | 
            +
                  elsif type == :application
         | 
| 72 | 
            +
                    if self.respond_to? :params
         | 
| 73 | 
            +
                      "site { #{class_name} { '#{title}': #{param_str} } }"
         | 
| 74 | 
            +
                    else
         | 
| 75 | 
            +
                      raise ArgumentException, "You need to provide params for an application"
         | 
| 76 | 
            +
                    end
         | 
| 71 77 | 
             
                  elsif type == :define
         | 
| 72 78 | 
             
                    if self.respond_to? :params
         | 
| 73 79 | 
             
                      "#{class_name} { '#{title}': #{param_str} }"
         | 
| @@ -81,7 +87,7 @@ module RSpec::Puppet | |
| 81 87 |  | 
| 82 88 | 
             
                def nodename(type)
         | 
| 83 89 | 
             
                  return node if self.respond_to?(:node)
         | 
| 84 | 
            -
                  if [:class, :define, :function].include? type
         | 
| 90 | 
            +
                  if [:class, :define, :function, :application].include? type
         | 
| 85 91 | 
             
                    Puppet[:certname]
         | 
| 86 92 | 
             
                  else
         | 
| 87 93 | 
             
                    class_name
         | 
| @@ -123,14 +129,28 @@ module RSpec::Puppet | |
| 123 129 | 
             
                end
         | 
| 124 130 |  | 
| 125 131 | 
             
                def param_str
         | 
| 126 | 
            -
                  params | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 132 | 
            +
                  param_str_from_hash(params)
         | 
| 133 | 
            +
                end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                def str_from_value(value)
         | 
| 136 | 
            +
                  case value
         | 
| 137 | 
            +
                  when Hash
         | 
| 138 | 
            +
                    kvs = value.collect do |k,v|
         | 
| 139 | 
            +
                      "#{str_from_value(k)} => #{str_from_value(v)}"
         | 
| 140 | 
            +
                    end.join(", ")
         | 
| 141 | 
            +
                    "{ #{kvs} }"
         | 
| 142 | 
            +
                  when :undef
         | 
| 143 | 
            +
                    'undef'  # verbatim undef keyword
         | 
| 144 | 
            +
                  else
         | 
| 145 | 
            +
                    escape_special_chars(value.inspect)
         | 
| 146 | 
            +
                  end
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                def param_str_from_hash(params_hash)
         | 
| 150 | 
            +
                  # the param_str has special quoting rules, because the top-level keys are the Puppet
         | 
| 151 | 
            +
                  # params, which may not be quoted
         | 
| 152 | 
            +
                  params_hash.collect do |k,v|
         | 
| 153 | 
            +
                    "#{k.to_s} => #{str_from_value(v)}"
         | 
| 134 154 | 
             
                  end.join(', ')
         | 
| 135 155 | 
             
                end
         | 
| 136 156 |  | 
| @@ -138,6 +158,11 @@ module RSpec::Puppet | |
| 138 158 | 
             
                  vardir = Dir.mktmpdir
         | 
| 139 159 | 
             
                  Puppet[:vardir] = vardir
         | 
| 140 160 |  | 
| 161 | 
            +
                  # Enable app_management by default for Puppet versions that support it
         | 
| 162 | 
            +
                  if Puppet.version.to_f >= 4.3
         | 
| 163 | 
            +
                    Puppet[:app_management] = true
         | 
| 164 | 
            +
                  end
         | 
| 165 | 
            +
             | 
| 141 166 | 
             
                  adapter.modulepath.map do |d|
         | 
| 142 167 | 
             
                    Dir["#{d}/*/lib"].entries
         | 
| 143 168 | 
             
                  end.flatten.each do |lib|
         | 
| @@ -147,6 +172,15 @@ module RSpec::Puppet | |
| 147 172 | 
             
                  vardir
         | 
| 148 173 | 
             
                end
         | 
| 149 174 |  | 
| 175 | 
            +
                def with_vardir
         | 
| 176 | 
            +
                  begin
         | 
| 177 | 
            +
                    vardir = setup_puppet
         | 
| 178 | 
            +
                    return yield(vardir) if block_given?
         | 
| 179 | 
            +
                  ensure
         | 
| 180 | 
            +
                    FileUtils.rm_rf(vardir) if File.directory?(vardir)
         | 
| 181 | 
            +
                  end
         | 
| 182 | 
            +
                end
         | 
| 183 | 
            +
             | 
| 150 184 | 
             
                def build_catalog_without_cache(nodename, facts_val, hiera_config_val, code, exported)
         | 
| 151 185 |  | 
| 152 186 | 
             
                  # If we're going to rebuild the catalog, we should clear the cached instance
         | 
| @@ -206,6 +240,16 @@ module RSpec::Puppet | |
| 206 240 | 
             
                  end
         | 
| 207 241 | 
             
                end
         | 
| 208 242 |  | 
| 243 | 
            +
                # Helper to return a resource/node reference, so it gets translated in params to a raw string
         | 
| 244 | 
            +
                # without quotes.
         | 
| 245 | 
            +
                #
         | 
| 246 | 
            +
                # @param [String] type reference type
         | 
| 247 | 
            +
                # @param [String] title reference title
         | 
| 248 | 
            +
                # @return [RSpec::Puppet::RawString] return a new RawString with the type/title populated correctly
         | 
| 249 | 
            +
                def ref(type, title)
         | 
| 250 | 
            +
                  return RSpec::Puppet::RawString.new("#{type}['#{title}']")
         | 
| 251 | 
            +
                end
         | 
| 252 | 
            +
             | 
| 209 253 | 
             
                # @!attribute [r] adapter
         | 
| 210 254 | 
             
                #   @api private
         | 
| 211 255 | 
             
                #   @return [Class < RSpec::Puppet::Adapters::Base]
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rspec-puppet
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.5.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Tim Sharpe
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-10-25 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rspec
         | 
| @@ -40,6 +40,7 @@ files: | |
| 40 40 | 
             
            - lib/rspec-puppet/coverage.rb
         | 
| 41 41 | 
             
            - lib/rspec-puppet/errors.rb
         | 
| 42 42 | 
             
            - lib/rspec-puppet/example.rb
         | 
| 43 | 
            +
            - lib/rspec-puppet/example/application_example_group.rb
         | 
| 43 44 | 
             
            - lib/rspec-puppet/example/class_example_group.rb
         | 
| 44 45 | 
             
            - lib/rspec-puppet/example/define_example_group.rb
         | 
| 45 46 | 
             
            - lib/rspec-puppet/example/function_example_group.rb
         | 
| @@ -56,6 +57,7 @@ files: | |
| 56 57 | 
             
            - lib/rspec-puppet/matchers/run.rb
         | 
| 57 58 | 
             
            - lib/rspec-puppet/matchers/type_matchers.rb
         | 
| 58 59 | 
             
            - lib/rspec-puppet/rake_task.rb
         | 
| 60 | 
            +
            - lib/rspec-puppet/raw_string.rb
         | 
| 59 61 | 
             
            - lib/rspec-puppet/setup.rb
         | 
| 60 62 | 
             
            - lib/rspec-puppet/spec_helper.rb
         | 
| 61 63 | 
             
            - lib/rspec-puppet/support.rb
         |