pact 1.51.0 → 1.55.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 +41 -0
- data/lib/pact/cli.rb +3 -0
- data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +9 -6
- data/lib/pact/pact_broker/pact_selection_description.rb +0 -1
- data/lib/pact/provider/configuration/pact_verification_from_broker.rb +49 -7
- data/lib/pact/provider/rspec.rb +23 -12
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +68 -14
- data/lib/pact/provider/test_methods.rb +5 -1
- data/lib/pact/tasks/verification_task.rb +6 -0
- data/lib/pact/utils/string.rb +35 -0
- data/lib/pact/version.rb +1 -1
- data/pact.gemspec +2 -2
- metadata +14 -8
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 54f6d8684eb57457977a86f79a9e2aace62f2fe63ef1e3896e8beee31586b0fe
         | 
| 4 | 
            +
              data.tar.gz: 292f5bdfe8cf126faaaab4a1792b1e68a21484f32a311fc9a5053f9a64f00f04
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 2501e2bb9ea36e185d45816d1944718fca0b0ebab315f7c51557553f85c809c96cb2a20d09096a326be108eafef352e6d41d2cc018369b3422f162bcc8fe7696
         | 
| 7 | 
            +
              data.tar.gz: d08e959aa8220f31b0fc8e60b82e9dda9f367f04604db7d26bdef16304b8862f45679e9333e49646d157e292ca03ef98fd94cb221723c7aee988539d0cc8540d
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,44 @@ | |
| 1 | 
            +
            <a name="v1.55.0"></a>
         | 
| 2 | 
            +
            ### v1.55.0 (2020-09-26)
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            #### Features
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            * add consumer_version_selectors to pact verification DSL, and convert consumer_version_tags to selectors	 ([39e6c4a](/../../commit/39e6c4a))
         | 
| 7 | 
            +
            * allow verification task to set just a pact_helper without a URI	 ([303077d](/../../commit/303077d))
         | 
| 8 | 
            +
            * split pending and failed rerun commands into separate sections	 ([f839391](/../../commit/f839391))
         | 
| 9 | 
            +
            * update output during verification so the pact info shows before the describe blocks of the pact that is being verified	 ([15ec231](/../../commit/15ec231))
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            <a name="v1.54.0"></a>
         | 
| 12 | 
            +
            ### v1.54.0 (2020-09-12)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            #### Features
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            * use pb relation in preference to beta relation when fetching pacts for verification	 ([7563fcf](/../../commit/7563fcf))
         | 
| 17 | 
            +
            * allow include_wip_pacts_since to use a Date, DateTime or Time	 ([dd35366](/../../commit/dd35366))
         | 
| 18 | 
            +
            * add support for include_wip_pacts_since	 ([f2247b8](/../../commit/f2247b8))
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            <a name="v1.53.0"></a>
         | 
| 21 | 
            +
            ### v1.53.0 (2020-09-11)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            #### Features
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            * add support for the enable_pending flag	 ([16866f4](/../../commit/16866f4))
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            <a name="v1.52.0"></a>
         | 
| 28 | 
            +
            ### v1.52.0 (2020-09-10)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            #### Features
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            * support webdav http methods	 ([fa1d712](/../../commit/fa1d712))
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            <a name="v1.51.1"></a>
         | 
| 35 | 
            +
            ### v1.51.1 (2020-08-12)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            #### Bug Fixes
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            * update thor dependency (#218)	 ([bf3ce69](/../../commit/bf3ce69))
         | 
| 40 | 
            +
            * bump rake dependency per CVE-2020-8130 (#219)	 ([09feaa6](/../../commit/09feaa6))
         | 
| 41 | 
            +
             | 
| 1 42 | 
             
            <a name="v1.51.0"></a>
         | 
| 2 43 | 
             
            ### v1.51.0 (2020-06-24)
         | 
| 3 44 |  | 
    
        data/lib/pact/cli.rb
    CHANGED
    
    | @@ -4,6 +4,9 @@ require 'pact/provider/configuration' | |
| 4 4 |  | 
| 5 5 | 
             
            module Pact
         | 
| 6 6 | 
             
              class CLI < Thor
         | 
| 7 | 
            +
                def self.exit_on_failure? # Thor 1.0 deprecation guard
         | 
| 8 | 
            +
                  false
         | 
| 9 | 
            +
                end
         | 
| 7 10 |  | 
| 8 11 | 
             
                desc 'verify', "Verify a pact"
         | 
| 9 12 | 
             
                method_option :pact_helper, aliases: "-h", desc: "Pact helper file", :required => true
         | 
| @@ -12,7 +12,8 @@ module Pact | |
| 12 12 | 
             
                  include PactSelectionDescription
         | 
| 13 13 | 
             
                  attr_reader :provider, :consumer_version_selectors, :provider_version_tags, :broker_base_url, :http_client_options, :http_client, :options
         | 
| 14 14 |  | 
| 15 | 
            -
                  PACTS_FOR_VERIFICATION_RELATION = ' | 
| 15 | 
            +
                  PACTS_FOR_VERIFICATION_RELATION = 'pb:provider-pacts-for-verification'.freeze
         | 
| 16 | 
            +
                  PACTS_FOR_VERIFICATION_RELATION_BETA = 'beta:provider-pacts-for-verification'.freeze
         | 
| 16 17 | 
             
                  PACTS = 'pacts'.freeze
         | 
| 17 18 | 
             
                  HREF = 'href'.freeze
         | 
| 18 19 | 
             
                  LINKS = '_links'.freeze
         | 
| @@ -22,7 +23,7 @@ module Pact | |
| 22 23 | 
             
                  def initialize(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options = {})
         | 
| 23 24 | 
             
                    @provider = provider
         | 
| 24 25 | 
             
                    @consumer_version_selectors = consumer_version_selectors || []
         | 
| 25 | 
            -
                    @provider_version_tags = provider_version_tags | 
| 26 | 
            +
                    @provider_version_tags = [*provider_version_tags]
         | 
| 26 27 | 
             
                    @http_client_options = http_client_options
         | 
| 27 28 | 
             
                    @broker_base_url = broker_base_url
         | 
| 28 29 | 
             
                    @http_client = Pact::Hal::HttpClient.new(http_client_options)
         | 
| @@ -34,13 +35,15 @@ module Pact | |
| 34 35 | 
             
                  end
         | 
| 35 36 |  | 
| 36 37 | 
             
                  def call
         | 
| 37 | 
            -
                    if index.can?(PACTS_FOR_VERIFICATION_RELATION)
         | 
| 38 | 
            +
                    if index.can?(PACTS_FOR_VERIFICATION_RELATION) || index.can?(PACTS_FOR_VERIFICATION_RELATION_BETA)
         | 
| 38 39 | 
             
                      log_message
         | 
| 39 40 | 
             
                      pacts_for_verification
         | 
| 40 41 | 
             
                    else
         | 
| 42 | 
            +
                      old_selectors = consumer_version_selectors.collect do | selector |
         | 
| 43 | 
            +
                        { name: selector[:tag], all: !selector[:latest], fallback: selector[:fallbackTag]}
         | 
| 44 | 
            +
                      end
         | 
| 41 45 | 
             
                      # Fall back to old method of fetching pacts
         | 
| 42 | 
            -
                       | 
| 43 | 
            -
                      FetchPacts.call(provider, consumer_version_tags, broker_base_url, http_client_options)
         | 
| 46 | 
            +
                      FetchPacts.call(provider, old_selectors, broker_base_url, http_client_options)
         | 
| 44 47 | 
             
                    end
         | 
| 45 48 | 
             
                  end
         | 
| 46 49 |  | 
| @@ -63,7 +66,7 @@ module Pact | |
| 63 66 |  | 
| 64 67 | 
             
                  def pacts_for_verification_entity
         | 
| 65 68 | 
             
                    index
         | 
| 66 | 
            -
                      ._link(PACTS_FOR_VERIFICATION_RELATION)
         | 
| 69 | 
            +
                      ._link(PACTS_FOR_VERIFICATION_RELATION, PACTS_FOR_VERIFICATION_RELATION_BETA)
         | 
| 67 70 | 
             
                      .expand(provider: provider)
         | 
| 68 71 | 
             
                      .post!(query)
         | 
| 69 72 | 
             
                  end
         | 
| @@ -7,7 +7,6 @@ module Pact | |
| 7 7 | 
             
                    if consumer_version_selectors.any?
         | 
| 8 8 | 
             
                      desc = consumer_version_selectors.collect do |selector|
         | 
| 9 9 | 
             
                        all_or_latest = !selector[:latest] ? "all for tag" : "latest for tag"
         | 
| 10 | 
            -
                        # TODO support fallback
         | 
| 11 10 | 
             
                        fallback = selector[:fallback] || selector[:fallbackTag]
         | 
| 12 11 | 
             
                        name = fallback ? "#{selector[:tag]} (or #{fallback} if not found)" : selector[:tag]
         | 
| 13 12 | 
             
                        "#{all_or_latest} #{name}"
         | 
| @@ -2,6 +2,7 @@ require 'pact/shared/dsl' | |
| 2 2 | 
             
            require 'pact/provider/world'
         | 
| 3 3 | 
             
            require 'pact/pact_broker/fetch_pact_uris_for_verification'
         | 
| 4 4 | 
             
            require 'pact/errors'
         | 
| 5 | 
            +
            require 'pact/utils/string'
         | 
| 5 6 |  | 
| 6 7 | 
             
            module Pact
         | 
| 7 8 | 
             
              module Provider
         | 
| @@ -14,12 +15,15 @@ module Pact | |
| 14 15 | 
             
                    # in parent scope, it will clash with these ones,
         | 
| 15 16 | 
             
                    # so put an underscore in front of the name to be safer.
         | 
| 16 17 |  | 
| 17 | 
            -
                    attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_verbose
         | 
| 18 | 
            +
                    attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose, :_consumer_version_selectors
         | 
| 18 19 |  | 
| 19 20 | 
             
                    def initialize(provider_name, provider_version_tags)
         | 
| 20 21 | 
             
                      @_provider_name = provider_name
         | 
| 21 22 | 
             
                      @_provider_version_tags = provider_version_tags
         | 
| 22 23 | 
             
                      @_consumer_version_tags = []
         | 
| 24 | 
            +
                      @_consumer_version_selectors = []
         | 
| 25 | 
            +
                      @_enable_pending = false
         | 
| 26 | 
            +
                      @_include_wip_pacts_since = nil
         | 
| 23 27 | 
             
                      @_verbose = false
         | 
| 24 28 | 
             
                    end
         | 
| 25 29 |  | 
| @@ -33,6 +37,22 @@ module Pact | |
| 33 37 | 
             
                        self._consumer_version_tags = *consumer_version_tags
         | 
| 34 38 | 
             
                      end
         | 
| 35 39 |  | 
| 40 | 
            +
                      def consumer_version_selectors consumer_version_selectors
         | 
| 41 | 
            +
                        self._consumer_version_selectors = *consumer_version_selectors
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                      def enable_pending enable_pending
         | 
| 45 | 
            +
                        self._enable_pending = enable_pending
         | 
| 46 | 
            +
                      end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      def include_wip_pacts_since since
         | 
| 49 | 
            +
                        self._include_wip_pacts_since = if since.respond_to?(:xmlschema)
         | 
| 50 | 
            +
                          since.xmlschema
         | 
| 51 | 
            +
                        else
         | 
| 52 | 
            +
                          since
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
             | 
| 36 56 | 
             
                      def verbose verbose
         | 
| 37 57 | 
             
                        self._verbose = verbose
         | 
| 38 58 | 
             
                      end
         | 
| @@ -51,19 +71,41 @@ module Pact | |
| 51 71 | 
             
                        consumer_version_selectors,
         | 
| 52 72 | 
             
                        _provider_version_tags,
         | 
| 53 73 | 
             
                        _pact_broker_base_url,
         | 
| 54 | 
            -
                        _basic_auth_options.merge(verbose: _verbose)
         | 
| 74 | 
            +
                        _basic_auth_options.merge(verbose: _verbose),
         | 
| 75 | 
            +
                        { include_pending_status: _enable_pending, include_wip_pacts_since: _include_wip_pacts_since }
         | 
| 55 76 | 
             
                      )
         | 
| 56 77 |  | 
| 57 78 | 
             
                      Pact.provider_world.add_pact_uri_source fetch_pacts
         | 
| 58 79 | 
             
                    end
         | 
| 59 80 |  | 
| 60 81 | 
             
                    def consumer_version_selectors
         | 
| 61 | 
            -
                       | 
| 82 | 
            +
                      convert_tags_to_selectors + convert_consumer_version_selectors
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                    def convert_tags_to_selectors
         | 
| 62 86 | 
             
                      _consumer_version_tags.collect do | tag |
         | 
| 63 | 
            -
                         | 
| 64 | 
            -
                           | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 87 | 
            +
                        if tag.is_a?(Hash)
         | 
| 88 | 
            +
                          {
         | 
| 89 | 
            +
                            tag: tag.fetch(:name),
         | 
| 90 | 
            +
                            latest: !tag[:all],
         | 
| 91 | 
            +
                            fallbackTag: tag[:fallback]
         | 
| 92 | 
            +
                          }
         | 
| 93 | 
            +
                        elsif tag.is_a?(String)
         | 
| 94 | 
            +
                          {
         | 
| 95 | 
            +
                            tag: tag,
         | 
| 96 | 
            +
                            latest: true
         | 
| 97 | 
            +
                          }
         | 
| 98 | 
            +
                        else
         | 
| 99 | 
            +
                          raise Pact::Error.new("The value supplied for consumer_version_tags must be a String or a Hash. Found #{tag.class}")
         | 
| 100 | 
            +
                        end
         | 
| 101 | 
            +
                      end
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                    def convert_consumer_version_selectors
         | 
| 105 | 
            +
                      _consumer_version_selectors.collect do | selector |
         | 
| 106 | 
            +
                        selector.each_with_object({}) do | (key, value), new_selector |
         | 
| 107 | 
            +
                          new_selector[Pact::Utils::String.camelcase(key.to_s).to_sym] = value
         | 
| 108 | 
            +
                        end
         | 
| 67 109 | 
             
                      end
         | 
| 68 110 | 
             
                    end
         | 
| 69 111 |  | 
    
        data/lib/pact/provider/rspec.rb
    CHANGED
    
    | @@ -24,28 +24,34 @@ module Pact | |
| 24 24 | 
             
                    def honour_pactfile pact_source, pact_json, options
         | 
| 25 25 | 
             
                      pact_uri = pact_source.uri
         | 
| 26 26 | 
             
                      Pact.configuration.output_stream.puts "INFO: Reading pact at #{pact_uri}"
         | 
| 27 | 
            -
                      if pact_uri.metadata[:notices]
         | 
| 28 | 
            -
                        pact_uri.metadata[:notices].before_verification_notices_text.each do | text |
         | 
| 29 | 
            -
                          Pact.configuration.output_stream.puts("DEBUG: #{text}")
         | 
| 30 | 
            -
                        end
         | 
| 31 | 
            -
                      end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                      Pact.configuration.output_stream.puts "DEBUG: Filtering interactions by: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
         | 
| 34 27 | 
             
                      consumer_contract = Pact::ConsumerContract.from_json(pact_json)
         | 
| 35 28 | 
             
                      suffix = pact_uri.metadata[:pending] ? " [PENDING]": ""
         | 
| 29 | 
            +
             | 
| 36 30 | 
             
                      ::RSpec.describe "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}#{suffix}", pactfile_uri: pact_uri do
         | 
| 37 | 
            -
                        honour_consumer_contract consumer_contract, options.merge( | 
| 31 | 
            +
                        honour_consumer_contract consumer_contract, options.merge(
         | 
| 32 | 
            +
                          pact_json: pact_json,
         | 
| 33 | 
            +
                          pact_uri: pact_uri,
         | 
| 34 | 
            +
                          pact_source: pact_source,
         | 
| 35 | 
            +
                          consumer_contract: consumer_contract,
         | 
| 36 | 
            +
                          criteria: options[:criteria]
         | 
| 37 | 
            +
                          )
         | 
| 38 38 | 
             
                      end
         | 
| 39 39 | 
             
                    end
         | 
| 40 40 |  | 
| 41 41 | 
             
                    def honour_consumer_contract consumer_contract, options = {}
         | 
| 42 | 
            -
                      describe_consumer_contract consumer_contract, options.merge(consumer: consumer_contract.consumer.name)
         | 
| 42 | 
            +
                      describe_consumer_contract consumer_contract, options.merge(consumer: consumer_contract.consumer.name, pact_context: InteractionContext.new)
         | 
| 43 43 | 
             
                    end
         | 
| 44 44 |  | 
| 45 45 | 
             
                    private
         | 
| 46 46 |  | 
| 47 47 | 
             
                    def describe_consumer_contract consumer_contract, options
         | 
| 48 | 
            -
                      consumer_interactions(consumer_contract, options). | 
| 48 | 
            +
                      consumer_interactions(consumer_contract, options).tap{ |interactions|
         | 
| 49 | 
            +
                        if interactions.empty?
         | 
| 50 | 
            +
                          # If there are no interactions, the documentation formatter never fires to print this out,
         | 
| 51 | 
            +
                          # so print it out here.
         | 
| 52 | 
            +
                          Pact.configuration.output_stream.puts "DEBUG: All interactions for #{options[:pact_uri]} have been filtered out by criteria: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
                      }.each do |interaction|
         | 
| 49 55 | 
             
                        describe_interaction_with_provider_state interaction, options
         | 
| 50 56 | 
             
                      end
         | 
| 51 57 | 
             
                    end
         | 
| @@ -54,7 +60,7 @@ module Pact | |
| 54 60 | 
             
                      if options[:criteria].nil?
         | 
| 55 61 | 
             
                        consumer_contract.interactions
         | 
| 56 62 | 
             
                      else
         | 
| 57 | 
            -
                        consumer_contract.find_interactions | 
| 63 | 
            +
                        consumer_contract.find_interactions(options[:criteria])
         | 
| 58 64 | 
             
                      end
         | 
| 59 65 | 
             
                    end
         | 
| 60 66 |  | 
| @@ -84,14 +90,19 @@ module Pact | |
| 84 90 | 
             
                        pact_uri: options[:pact_uri],
         | 
| 85 91 | 
             
                        pact_source: options[:pact_source],
         | 
| 86 92 | 
             
                        pact_ignore_failures: options[:pact_uri].metadata[:pending] || options[:ignore_failures],
         | 
| 87 | 
            -
                        pact_consumer_contract: options[:consumer_contract]
         | 
| 93 | 
            +
                        pact_consumer_contract: options[:consumer_contract],
         | 
| 94 | 
            +
                        pact_criteria: options[:criteria]
         | 
| 88 95 | 
             
                      }
         | 
| 89 96 |  | 
| 90 97 | 
             
                      describe description_for(interaction), metadata do
         | 
| 91 98 |  | 
| 92 99 | 
             
                        interaction_context = InteractionContext.new
         | 
| 100 | 
            +
                        pact_context = options[:pact_context]
         | 
| 93 101 |  | 
| 94 102 | 
             
                        before do | example |
         | 
| 103 | 
            +
                          pact_context.run_once :before do
         | 
| 104 | 
            +
                            ::RSpec.configuration.reporter.message "THIS IS A PACT"
         | 
| 105 | 
            +
                          end
         | 
| 95 106 | 
             
                          interaction_context.run_once :before do
         | 
| 96 107 | 
             
                            Pact.configuration.logger.info "Running example '#{Pact::RSpec.full_description(example)}'"
         | 
| 97 108 | 
             
                            set_up_provider_states interaction.provider_states, options[:consumer]
         | 
| @@ -24,6 +24,25 @@ module Pact | |
| 24 24 |  | 
| 25 25 | 
             
                    C = ::Term::ANSIColor
         | 
| 26 26 |  | 
| 27 | 
            +
                    def example_group_started(notification)
         | 
| 28 | 
            +
                      if @group_level == 0
         | 
| 29 | 
            +
                        Pact.configuration.output_stream.puts
         | 
| 30 | 
            +
                        pact_uri = notification.group.metadata[:pactfile_uri]
         | 
| 31 | 
            +
                        ::RSpec.configuration.failure_color = pact_uri.metadata[:pending] ? :yellow : :red
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                        if pact_uri.metadata[:notices]
         | 
| 34 | 
            +
                          pact_uri.metadata[:notices].before_verification_notices_text.each do | text |
         | 
| 35 | 
            +
                            Pact.configuration.output_stream.puts("DEBUG: #{text}")
         | 
| 36 | 
            +
                          end
         | 
| 37 | 
            +
                        end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                        criteria = notification.group.metadata[:pact_criteria]
         | 
| 40 | 
            +
                        Pact.configuration.output_stream.puts "DEBUG: Filtering interactions by: #{criteria}" if criteria && criteria.any?
         | 
| 41 | 
            +
                      end
         | 
| 42 | 
            +
                      super
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 27 46 | 
             
                    def dump_summary(summary)
         | 
| 28 47 | 
             
                      output.puts "\n" + colorized_totals_line(summary)
         | 
| 29 48 | 
             
                      return if summary.failure_count == 0
         | 
| @@ -35,11 +54,15 @@ module Pact | |
| 35 54 | 
             
                    private
         | 
| 36 55 |  | 
| 37 56 | 
             
                    def interactions_count(summary)
         | 
| 38 | 
            -
                      summary.examples.collect{ |e| e | 
| 57 | 
            +
                      summary.examples.collect{ |e| interaction_unique_key(e) }.uniq.size
         | 
| 39 58 | 
             
                    end
         | 
| 40 59 |  | 
| 41 60 | 
             
                    def failed_interactions_count(summary)
         | 
| 42 | 
            -
                      summary. | 
| 61 | 
            +
                      failed_interaction_examples(summary).size
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    def pending_interactions_count(summary)
         | 
| 65 | 
            +
                      pending_interaction_examples(summary).size
         | 
| 43 66 | 
             
                    end
         | 
| 44 67 |  | 
| 45 68 | 
             
                    def ignore_failures?(summary)
         | 
| @@ -47,16 +70,14 @@ module Pact | |
| 47 70 | 
             
                    end
         | 
| 48 71 |  | 
| 49 72 | 
             
                    def failure_title summary
         | 
| 50 | 
            -
                       | 
| 51 | 
            -
                        "#{failed_interactions_count(summary)} pending"
         | 
| 52 | 
            -
                      else
         | 
| 53 | 
            -
                        ::RSpec::Core::Formatters::Helpers.pluralize(failed_interactions_count(summary), "failure")
         | 
| 54 | 
            -
                      end
         | 
| 73 | 
            +
                      ::RSpec::Core::Formatters::Helpers.pluralize(failed_interactions_count(summary), "failure")
         | 
| 55 74 | 
             
                    end
         | 
| 56 75 |  | 
| 57 76 | 
             
                    def totals_line summary
         | 
| 58 77 | 
             
                      line = ::RSpec::Core::Formatters::Helpers.pluralize(interactions_count(summary), "interaction")
         | 
| 59 78 | 
             
                      line << ", " << failure_title(summary)
         | 
| 79 | 
            +
                      pending_count = pending_interactions_count(summary)
         | 
| 80 | 
            +
                      line << ", " << "#{pending_count} pending" if pending_count > 0
         | 
| 60 81 | 
             
                      line
         | 
| 61 82 | 
             
                    end
         | 
| 62 83 |  | 
| @@ -69,12 +90,17 @@ module Pact | |
| 69 90 | 
             
                    end
         | 
| 70 91 |  | 
| 71 92 | 
             
                    def print_rerun_commands summary
         | 
| 72 | 
            -
                      if  | 
| 93 | 
            +
                      if pending_interactions_count(summary) > 0
         | 
| 94 | 
            +
                        set_rspec_failure_color(:yellow)
         | 
| 73 95 | 
             
                        output.puts("\nPending interactions: (Failures listed here are expected and do not affect your suite's status)\n\n")
         | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 96 | 
            +
                        interaction_rerun_commands(pending_interaction_examples(summary)).each do | message |
         | 
| 97 | 
            +
                          output.puts(message)
         | 
| 98 | 
            +
                        end
         | 
| 76 99 | 
             
                      end
         | 
| 77 | 
            -
             | 
| 100 | 
            +
             | 
| 101 | 
            +
                      set_rspec_failure_color(:red)
         | 
| 102 | 
            +
                      output.puts("\nFailed interactions:\n\n")
         | 
| 103 | 
            +
                      interaction_rerun_commands(failed_interaction_examples(summary)).each do | message |
         | 
| 78 104 | 
             
                        output.puts(message)
         | 
| 79 105 | 
             
                      end
         | 
| 80 106 | 
             
                    end
         | 
| @@ -85,10 +111,34 @@ module Pact | |
| 85 111 | 
             
                      end
         | 
| 86 112 | 
             
                    end
         | 
| 87 113 |  | 
| 88 | 
            -
                    def  | 
| 89 | 
            -
                      summary. | 
| 114 | 
            +
                    def pending_interaction_examples(summary)
         | 
| 115 | 
            +
                      one_failed_example_per_interaction(summary).select do | example |
         | 
| 116 | 
            +
                        example.metadata[:pactfile_uri].metadata[:pending]
         | 
| 117 | 
            +
                      end
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                    def failed_interaction_examples(summary)
         | 
| 121 | 
            +
                      one_failed_example_per_interaction(summary).select do | example |
         | 
| 122 | 
            +
                        !example.metadata[:pactfile_uri].metadata[:pending]
         | 
| 123 | 
            +
                      end
         | 
| 124 | 
            +
                    end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    def one_failed_example_per_interaction(summary)
         | 
| 127 | 
            +
                      summary.failed_examples.group_by{| e| interaction_unique_key(e)}.values.collect(&:first)
         | 
| 128 | 
            +
                    end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                    def interaction_rerun_commands examples
         | 
| 131 | 
            +
                      examples.collect do |example|
         | 
| 90 132 | 
             
                        interaction_rerun_command_for example
         | 
| 91 | 
            -
                      end. | 
| 133 | 
            +
                      end.compact
         | 
| 134 | 
            +
                    end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                    def interaction_unique_key(example)
         | 
| 137 | 
            +
                      # pending is just to make the counting easier, it isn't required for the unique key
         | 
| 138 | 
            +
                      {
         | 
| 139 | 
            +
                        pactfile_uri: example.metadata[:pactfile_uri],
         | 
| 140 | 
            +
                        index: example.metadata[:pact_interaction].index,
         | 
| 141 | 
            +
                      }
         | 
| 92 142 | 
             
                    end
         | 
| 93 143 |  | 
| 94 144 | 
             
                    def interaction_rerun_command_for example
         | 
| @@ -137,6 +187,10 @@ module Pact | |
| 137 187 | 
             
                    def executing_with_ruby?
         | 
| 138 188 | 
             
                      ENV['PACT_EXECUTING_LANGUAGE'] == 'ruby'
         | 
| 139 189 | 
             
                    end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                    def set_rspec_failure_color color
         | 
| 192 | 
            +
                      ::RSpec.configuration.failure_color = color
         | 
| 193 | 
            +
                    end
         | 
| 140 194 | 
             
                  end
         | 
| 141 195 | 
             
                end
         | 
| 142 196 | 
             
              end
         | 
| @@ -21,7 +21,11 @@ module Pact | |
| 21 21 |  | 
| 22 22 | 
             
                    logger.info "Sending #{request.method.upcase} request to path: \"#{request.path}\" with headers: #{request.headers}, see debug logs for body"
         | 
| 23 23 | 
             
                    logger.debug "body :#{request.body}"
         | 
| 24 | 
            -
                    response = self. | 
| 24 | 
            +
                    response = if self.respond_to?(:custom_request)
         | 
| 25 | 
            +
                      self.custom_request(request.method.upcase, *args)
         | 
| 26 | 
            +
                    else
         | 
| 27 | 
            +
                      self.send(request.method.downcase, *args)
         | 
| 28 | 
            +
                    end
         | 
| 25 29 | 
             
                    logger.info "Received response with status: #{response.status}, headers: #{response.headers}, see debug logs for body"
         | 
| 26 30 | 
             
                    logger.debug "body: #{response.body}"
         | 
| 27 31 | 
             
                  end
         | 
| @@ -31,6 +31,7 @@ module Pact | |
| 31 31 | 
             
                attr_reader :pact_spec_configs
         | 
| 32 32 | 
             
                attr_accessor :rspec_opts
         | 
| 33 33 | 
             
                attr_accessor :ignore_failures
         | 
| 34 | 
            +
                attr_accessor :_pact_helper
         | 
| 34 35 |  | 
| 35 36 | 
             
                def initialize(name)
         | 
| 36 37 | 
             
                  @rspec_opts = nil
         | 
| @@ -41,6 +42,10 @@ module Pact | |
| 41 42 | 
             
                  rake_task
         | 
| 42 43 | 
             
                end
         | 
| 43 44 |  | 
| 45 | 
            +
                def pact_helper(pact_helper)
         | 
| 46 | 
            +
                  @pact_spec_configs << { pact_helper: pact_helper }
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 44 49 | 
             
                def uri(uri, options = {})
         | 
| 45 50 | 
             
                  @pact_spec_configs << {uri: uri, pact_helper: options[:pact_helper]}
         | 
| 46 51 | 
             
                end
         | 
| @@ -82,6 +87,7 @@ module Pact | |
| 82 87 | 
             
                      Pact::TaskHelper.handle_verification_failure do
         | 
| 83 88 | 
             
                        exit_statuses.count{ | status | status != 0 }
         | 
| 84 89 | 
             
                      end
         | 
| 90 | 
            +
             | 
| 85 91 | 
             
                    end
         | 
| 86 92 | 
             
                  end
         | 
| 87 93 | 
             
                end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            # Can't use refinements because of Travelling Ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Pact
         | 
| 4 | 
            +
              module Utils
         | 
| 5 | 
            +
                module String
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  extend self
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  # ripped from rubyworks/facets, thank you
         | 
| 10 | 
            +
                  def camelcase(string, *separators)
         | 
| 11 | 
            +
                    case separators.first
         | 
| 12 | 
            +
                    when Symbol, TrueClass, FalseClass, NilClass
         | 
| 13 | 
            +
                      first_letter = separators.shift
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                    separators = ['_', '\s'] if separators.empty?
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    str = string.dup
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    separators.each do |s|
         | 
| 21 | 
            +
                      str = str.gsub(/(?:#{s}+)([a-z])/){ $1.upcase }
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    case first_letter
         | 
| 25 | 
            +
                    when :upper, true
         | 
| 26 | 
            +
                      str = str.gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase }
         | 
| 27 | 
            +
                    when :lower, false
         | 
| 28 | 
            +
                      str = str.gsub(/(\A|\s)([A-Z])/){ $1 + $2.downcase }
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    str
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
    
        data/lib/pact/version.rb
    CHANGED
    
    
    
        data/pact.gemspec
    CHANGED
    
    | @@ -28,14 +28,14 @@ Gem::Specification.new do |gem| | |
| 28 28 |  | 
| 29 29 | 
             
              gem.add_runtime_dependency 'rspec', '~> 3.0'
         | 
| 30 30 | 
             
              gem.add_runtime_dependency 'rack-test', '>= 0.6.3', '< 2.0.0'
         | 
| 31 | 
            -
              gem.add_runtime_dependency 'thor', ' | 
| 31 | 
            +
              gem.add_runtime_dependency 'thor', '>= 0.20', '< 2.0'
         | 
| 32 32 | 
             
              gem.add_runtime_dependency 'webrick', '~> 1.3'
         | 
| 33 33 | 
             
              gem.add_runtime_dependency 'term-ansicolor', '~> 1.0'
         | 
| 34 34 |  | 
| 35 35 | 
             
              gem.add_runtime_dependency 'pact-support', '~> 1.9'
         | 
| 36 36 | 
             
              gem.add_runtime_dependency 'pact-mock_service', '~> 3.0', '>= 3.3.1'
         | 
| 37 37 |  | 
| 38 | 
            -
              gem.add_development_dependency 'rake', '~>  | 
| 38 | 
            +
              gem.add_development_dependency 'rake', '~> 13.0'
         | 
| 39 39 | 
             
              gem.add_development_dependency 'webmock', '~> 3.0'
         | 
| 40 40 | 
             
              gem.add_development_dependency 'fakefs', '0.5' # 0.6.0 blows up
         | 
| 41 41 | 
             
              gem.add_development_dependency 'hashie', '~> 2.0'
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: pact
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.55.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - James Fraser
         | 
| @@ -12,7 +12,7 @@ authors: | |
| 12 12 | 
             
            autorequire: 
         | 
| 13 13 | 
             
            bindir: bin
         | 
| 14 14 | 
             
            cert_chain: []
         | 
| 15 | 
            -
            date: 2020- | 
| 15 | 
            +
            date: 2020-09-26 00:00:00.000000000 Z
         | 
| 16 16 | 
             
            dependencies:
         | 
| 17 17 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 18 18 | 
             
              name: rspec
         | 
| @@ -52,16 +52,22 @@ dependencies: | |
| 52 52 | 
             
              name: thor
         | 
| 53 53 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 54 54 | 
             
                requirements:
         | 
| 55 | 
            -
                - - " | 
| 55 | 
            +
                - - ">="
         | 
| 56 56 | 
             
                  - !ruby/object:Gem::Version
         | 
| 57 57 | 
             
                    version: '0.20'
         | 
| 58 | 
            +
                - - "<"
         | 
| 59 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 60 | 
            +
                    version: '2.0'
         | 
| 58 61 | 
             
              type: :runtime
         | 
| 59 62 | 
             
              prerelease: false
         | 
| 60 63 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 61 64 | 
             
                requirements:
         | 
| 62 | 
            -
                - - " | 
| 65 | 
            +
                - - ">="
         | 
| 63 66 | 
             
                  - !ruby/object:Gem::Version
         | 
| 64 67 | 
             
                    version: '0.20'
         | 
| 68 | 
            +
                - - "<"
         | 
| 69 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 70 | 
            +
                    version: '2.0'
         | 
| 65 71 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 66 72 | 
             
              name: webrick
         | 
| 67 73 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -130,14 +136,14 @@ dependencies: | |
| 130 136 | 
             
                requirements:
         | 
| 131 137 | 
             
                - - "~>"
         | 
| 132 138 | 
             
                  - !ruby/object:Gem::Version
         | 
| 133 | 
            -
                    version: ' | 
| 139 | 
            +
                    version: '13.0'
         | 
| 134 140 | 
             
              type: :development
         | 
| 135 141 | 
             
              prerelease: false
         | 
| 136 142 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 137 143 | 
             
                requirements:
         | 
| 138 144 | 
             
                - - "~>"
         | 
| 139 145 | 
             
                  - !ruby/object:Gem::Version
         | 
| 140 | 
            -
                    version: ' | 
| 146 | 
            +
                    version: '13.0'
         | 
| 141 147 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 142 148 | 
             
              name: webmock
         | 
| 143 149 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -371,6 +377,7 @@ files: | |
| 371 377 | 
             
            - lib/pact/tasks/verification_task.rb
         | 
| 372 378 | 
             
            - lib/pact/templates/help.erb
         | 
| 373 379 | 
             
            - lib/pact/templates/provider_state.erb
         | 
| 380 | 
            +
            - lib/pact/utils/string.rb
         | 
| 374 381 | 
             
            - lib/pact/version.rb
         | 
| 375 382 | 
             
            - lib/tasks/pact.rake
         | 
| 376 383 | 
             
            - pact.gemspec
         | 
| @@ -397,8 +404,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 397 404 | 
             
                - !ruby/object:Gem::Version
         | 
| 398 405 | 
             
                  version: '0'
         | 
| 399 406 | 
             
            requirements: []
         | 
| 400 | 
            -
             | 
| 401 | 
            -
            rubygems_version: 2.7.7
         | 
| 407 | 
            +
            rubygems_version: 3.1.4
         | 
| 402 408 | 
             
            signing_key: 
         | 
| 403 409 | 
             
            specification_version: 4
         | 
| 404 410 | 
             
            summary: Enables consumer driven contract testing, providing a mock service and DSL
         |