pact 1.3.3 → 1.4.0.rc2

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.
Files changed (110) hide show
  1. data/CHANGELOG.md +16 -1
  2. data/Gemfile +5 -0
  3. data/Gemfile.lock +34 -13
  4. data/README.md +3 -2
  5. data/example/animal-service/lib/animal_service/api.rb +1 -0
  6. data/example/zoo-app/lib/zoo_app/animal_service_client.rb +0 -9
  7. data/example/zoo-app/lib/zoo_app/models/alligator.rb +2 -0
  8. data/lib/pact.rb +6 -5
  9. data/lib/pact/cli.rb +0 -26
  10. data/lib/pact/consumer/configuration.rb +0 -1
  11. data/lib/pact/consumer/configuration/configuration_extensions.rb +51 -0
  12. data/lib/pact/consumer/consumer_contract_builder.rb +1 -2
  13. data/lib/pact/consumer/interaction_builder.rb +2 -4
  14. data/lib/pact/doc/interaction_view_model.rb +9 -6
  15. data/lib/pact/doc/sort_interactions.rb +1 -1
  16. data/lib/pact/provider/rspec.rb +11 -9
  17. data/lib/pact/version.rb +1 -1
  18. data/pact.gemspec +5 -0
  19. data/spec/lib/pact/consumer/interaction_builder_spec.rb +4 -8
  20. data/spec/support/case-insensitive-response-header-matching.json +21 -0
  21. data/spec/support/case-insensitive-response-header-matching.rb +15 -0
  22. data/tasks/pact-test.rake +5 -0
  23. metadata +42 -122
  24. data/lib/pact/configuration.rb +0 -195
  25. data/lib/pact/consumer/app_manager.rb +0 -158
  26. data/lib/pact/consumer/interactions_filter.rb +0 -48
  27. data/lib/pact/consumer/mock_service.rb +0 -2
  28. data/lib/pact/consumer/mock_service/app.rb +0 -82
  29. data/lib/pact/consumer/mock_service/interaction_delete.rb +0 -33
  30. data/lib/pact/consumer/mock_service/interaction_list.rb +0 -76
  31. data/lib/pact/consumer/mock_service/interaction_mismatch.rb +0 -73
  32. data/lib/pact/consumer/mock_service/interaction_post.rb +0 -31
  33. data/lib/pact/consumer/mock_service/interaction_replay.rb +0 -139
  34. data/lib/pact/consumer/mock_service/log_get.rb +0 -28
  35. data/lib/pact/consumer/mock_service/missing_interactions_get.rb +0 -30
  36. data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +0 -31
  37. data/lib/pact/consumer/mock_service/pact_post.rb +0 -33
  38. data/lib/pact/consumer/mock_service/rack_request_helper.rb +0 -51
  39. data/lib/pact/consumer/mock_service/verification_get.rb +0 -68
  40. data/lib/pact/consumer/mock_service_client.rb +0 -65
  41. data/lib/pact/consumer/mock_service_interaction_expectation.rb +0 -37
  42. data/lib/pact/consumer/request.rb +0 -27
  43. data/lib/pact/consumer/server.rb +0 -90
  44. data/lib/pact/consumer_contract.rb +0 -1
  45. data/lib/pact/consumer_contract/consumer_contract.rb +0 -115
  46. data/lib/pact/consumer_contract/consumer_contract_writer.rb +0 -84
  47. data/lib/pact/consumer_contract/file_name.rb +0 -19
  48. data/lib/pact/consumer_contract/headers.rb +0 -51
  49. data/lib/pact/consumer_contract/interaction.rb +0 -67
  50. data/lib/pact/consumer_contract/pact_file.rb +0 -24
  51. data/lib/pact/consumer_contract/request.rb +0 -73
  52. data/lib/pact/consumer_contract/service_consumer.rb +0 -28
  53. data/lib/pact/consumer_contract/service_provider.rb +0 -28
  54. data/lib/pact/logging.rb +0 -14
  55. data/lib/pact/matchers.rb +0 -1
  56. data/lib/pact/matchers/actual_type.rb +0 -16
  57. data/lib/pact/matchers/base_difference.rb +0 -37
  58. data/lib/pact/matchers/differ.rb +0 -153
  59. data/lib/pact/matchers/difference.rb +0 -13
  60. data/lib/pact/matchers/difference_indicator.rb +0 -26
  61. data/lib/pact/matchers/embedded_diff_formatter.rb +0 -62
  62. data/lib/pact/matchers/expected_type.rb +0 -35
  63. data/lib/pact/matchers/index_not_found.rb +0 -15
  64. data/lib/pact/matchers/list_diff_formatter.rb +0 -101
  65. data/lib/pact/matchers/matchers.rb +0 -139
  66. data/lib/pact/matchers/no_diff_indicator.rb +0 -18
  67. data/lib/pact/matchers/regexp_difference.rb +0 -13
  68. data/lib/pact/matchers/type_difference.rb +0 -16
  69. data/lib/pact/matchers/unexpected_index.rb +0 -11
  70. data/lib/pact/matchers/unexpected_key.rb +0 -11
  71. data/lib/pact/matchers/unix_diff_formatter.rb +0 -114
  72. data/lib/pact/reification.rb +0 -28
  73. data/lib/pact/rspec.rb +0 -53
  74. data/lib/pact/shared/active_support_support.rb +0 -51
  75. data/lib/pact/shared/dsl.rb +0 -76
  76. data/lib/pact/shared/jruby_support.rb +0 -18
  77. data/lib/pact/shared/json_differ.rb +0 -15
  78. data/lib/pact/shared/key_not_found.rb +0 -15
  79. data/lib/pact/shared/null_expectation.rb +0 -31
  80. data/lib/pact/shared/request.rb +0 -80
  81. data/lib/pact/shared/text_differ.rb +0 -14
  82. data/lib/pact/something_like.rb +0 -49
  83. data/lib/pact/symbolize_keys.rb +0 -12
  84. data/lib/pact/term.rb +0 -85
  85. data/spec/lib/pact/consumer/request_spec.rb +0 -24
  86. data/spec/lib/pact/consumer_contract/active_support_support_spec.rb +0 -58
  87. data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +0 -180
  88. data/spec/lib/pact/consumer_contract/headers_spec.rb +0 -107
  89. data/spec/lib/pact/consumer_contract/interaction_spec.rb +0 -107
  90. data/spec/lib/pact/consumer_contract/request_spec.rb +0 -329
  91. data/spec/lib/pact/matchers/differ_spec.rb +0 -214
  92. data/spec/lib/pact/matchers/difference_spec.rb +0 -22
  93. data/spec/lib/pact/matchers/embedded_diff_formatter_spec.rb +0 -90
  94. data/spec/lib/pact/matchers/index_not_found_spec.rb +0 -21
  95. data/spec/lib/pact/matchers/list_diff_formatter_spec.rb +0 -114
  96. data/spec/lib/pact/matchers/matchers_spec.rb +0 -500
  97. data/spec/lib/pact/matchers/regexp_difference_spec.rb +0 -20
  98. data/spec/lib/pact/matchers/type_difference_spec.rb +0 -34
  99. data/spec/lib/pact/matchers/unexpected_index_spec.rb +0 -20
  100. data/spec/lib/pact/matchers/unexpected_key_spec.rb +0 -20
  101. data/spec/lib/pact/matchers/unix_diff_formatter_spec.rb +0 -216
  102. data/spec/lib/pact/reification_spec.rb +0 -67
  103. data/spec/lib/pact/shared/dsl_spec.rb +0 -86
  104. data/spec/lib/pact/shared/json_differ_spec.rb +0 -36
  105. data/spec/lib/pact/shared/key_not_found_spec.rb +0 -20
  106. data/spec/lib/pact/shared/request_spec.rb +0 -111
  107. data/spec/lib/pact/shared/text_differ_spec.rb +0 -54
  108. data/spec/lib/pact/something_like_spec.rb +0 -21
  109. data/spec/lib/pact/term_spec.rb +0 -89
  110. data/spec/support/dsl_spec_support.rb +0 -7
@@ -1,28 +0,0 @@
1
- require 'randexp'
2
-
3
- module Pact
4
- module Reification
5
-
6
- def self.from_term(term)
7
- case term
8
- when Pact::Term, Regexp, Pact::SomethingLike
9
- term.generate
10
- when Hash
11
- term.inject({}) do |mem, (key,term)|
12
- mem[key] = from_term(term)
13
- mem
14
- end
15
- when Array
16
- term.inject([]) do |mem, term|
17
- mem << from_term(term)
18
- mem
19
- end
20
- when Pact::Request::Base
21
- from_term(term.to_hash)
22
- else
23
- term
24
- end
25
- end
26
-
27
- end
28
- end
data/lib/pact/rspec.rb DELETED
@@ -1,53 +0,0 @@
1
- require 'rspec'
2
- # This is horrible, must work out a better way of doing this
3
- module Pact
4
- module RSpec
5
-
6
- def self.color_enabled?
7
- if ::RSpec.configuration.respond_to?(:color_enabled?)
8
- ::RSpec.configuration.color_enabled?(::RSpec.configuration.output_stream)
9
- else
10
- ::RSpec.configuration.color_enabled?
11
- end
12
- end
13
-
14
- def self.formatter_class
15
- if ::RSpec::Core::Formatters.respond_to?(:register)
16
- require 'pact/provider/rspec/formatter_rspec_3'
17
- Pact::Provider::RSpec::Formatter
18
- else
19
- require 'pact/provider/rspec/formatter_rspec_2'
20
- Pact::Provider::RSpec::Formatter2
21
- end
22
-
23
- end
24
-
25
- def self.full_description example
26
- example.respond_to?(:full_description) ? example.full_description : example.example.full_description
27
- end
28
-
29
- def self.runner_defined?
30
- defined?(::RSpec::Core::Runner)
31
- end
32
-
33
- def self.is_rspec_3
34
- ::RSpec::Core::Formatters.respond_to?(:register)
35
- end
36
-
37
- def self.is_rspec_2
38
- !is_rspec_3
39
- end
40
-
41
- def self.with_rspec_3
42
- if is_rspec_3
43
- yield
44
- end
45
- end
46
-
47
- def self.with_rspec_2
48
- if is_rspec_2
49
- yield
50
- end
51
- end
52
- end
53
- end
@@ -1,51 +0,0 @@
1
- module Pact
2
- module ActiveSupportSupport
3
-
4
- extend self
5
-
6
- def fix_all_the_things thing
7
- if thing.is_a?(Regexp)
8
- fix_regexp(thing)
9
- elsif thing.is_a?(Array)
10
- thing.each{ | it | fix_all_the_things it }
11
- elsif thing.is_a?(Hash)
12
- thing.values.each{ | it | fix_all_the_things it }
13
- elsif thing.class.name.start_with?("Pact")
14
- thing.instance_variables.collect{ | iv_name | thing.instance_variable_get(iv_name)}.each do | iv |
15
- fix_all_the_things iv
16
- end
17
- end
18
- thing
19
- end
20
-
21
- # ActiveSupport JSON overwrites (i.e. TRAMPLES) the json methods of the Regexp class directly
22
- # (beneath its destructive hooves of destruction).
23
- # This does not seem to be able to be undone without affecting the JSON serialisation in the
24
- # calling project, so the best way I've found to fix this issue is to reattach the
25
- # original as_json to the Regexp instances in the ConsumerContract before we write them to the
26
- # pact file. If anyone can find a better way, please submit a pull request ASAP!
27
- def fix_regexp regexp
28
- def regexp.as_json options = {}
29
- {:json_class => 'Regexp', "o" => self.options, "s" => self.source }
30
- end
31
- regexp
32
- end
33
-
34
- # Having Active Support JSON loaded somehow kills the formatting of pretty_generate for objects.
35
- # Don't ask me why, but it still seems to work for hashes, so the hacky work around is to
36
- # reparse the generated JSON into a hash and pretty_generate that... sigh...
37
- # Oh ActiveSupport, why....
38
- def fix_json_formatting json
39
- if json.include?("\n")
40
- json
41
- else
42
- JSON.pretty_generate(JSON.parse(json, create_additions: false))
43
- end
44
- end
45
-
46
- def remove_unicode json
47
- json.gsub(/\\u([0-9A-Za-z]{4})/) {|s| [$1.to_i(16)].pack("U")}
48
- end
49
-
50
- end
51
- end
@@ -1,76 +0,0 @@
1
- module Pact
2
-
3
- class DslDelegator
4
-
5
- def initialize delegation_target
6
- @delegation_target = delegation_target
7
- end
8
-
9
- def instance_eval_with_previous_context_available(*args, &block)
10
- with_previous_context_available(block.binding) do
11
- bind_block_as_instance_method_on_self(&block).call(*args)
12
- end
13
- end
14
-
15
- protected
16
-
17
- def method_missing(method, *args, &block)
18
- if delegation_target_responds_to? method
19
- delegation_target.send(method, *args, &block)
20
- else
21
- previous_context.send(method, *args, &block)
22
- end
23
- end
24
-
25
- private
26
-
27
- attr_accessor :delegation_target, :previous_context
28
-
29
- def bind_block_as_instance_method_on_self(&block)
30
- create_instance_method_from_block(&block).bind(self)
31
- end
32
-
33
-
34
- def create_instance_method_from_block &block
35
- meth = self.class.class_eval do
36
- define_method :block_as_instance_method_, &block
37
- meth = instance_method :block_as_instance_method_
38
- remove_method :block_as_instance_method_
39
- meth
40
- end
41
- end
42
-
43
- def with_previous_context_available(binding, &block)
44
- @previous_context = binding.eval('self')
45
- result = block.call
46
- @previous_context = nil
47
- result
48
- end
49
-
50
- def delegation_target_responds_to?(method)
51
- delegation_target.respond_to? method
52
- end
53
-
54
- end
55
-
56
-
57
- # Ripped from http://blog.joecorcoran.co.uk/2013/09/04/simple-pattern-ruby-dsl
58
- # and then fixed up by using http://www.skorks.com/2013/03/a-closure-is-not-always-a-closure-in-ruby/
59
- # to access variables and methods defined in the calling scope.
60
- module DSL
61
- def build(*args, &block)
62
- new_instance_of_delegation_target_class = self.new(*args)
63
- dsl_delegator_class = self.const_get('DSL_DELEGATOR_CLASS')
64
- dsl_delegator = dsl_delegator_class.new(new_instance_of_delegation_target_class)
65
- dsl_delegator.instance_eval_with_previous_context_available(&block)
66
- new_instance_of_delegation_target_class.finalize
67
- new_instance_of_delegation_target_class
68
- end
69
-
70
- def dsl(&block)
71
- dsl_delegator_class = Class.new(DslDelegator, &block)
72
- self.const_set('DSL_DELEGATOR_CLASS', dsl_delegator_class)
73
- end
74
-
75
- end
76
- end
@@ -1,18 +0,0 @@
1
- module Pact
2
- module JRubySupport
3
-
4
- # Under jruby, JSON.pretty_generate inserts a blank new line between the opening and closing
5
- # brackets of an empty hash, like so:
6
- # {
7
- # "empty": {
8
- #
9
- # }
10
- # }
11
- # This screws up the UnixDiffFormatter, so we need to remove the blank lines.
12
-
13
- def fix_blank_lines_in_empty_hashes json
14
- json.gsub(/({\n)\n(\s*})/,'\1\2')
15
- end
16
-
17
- end
18
- end
@@ -1,15 +0,0 @@
1
- require 'pact/matchers/matchers'
2
-
3
- module Pact
4
- class JsonDiffer
5
-
6
- extend Matchers
7
-
8
-
9
- def self.call expected, actual, options = {}
10
- diff expected, actual, options
11
- end
12
-
13
-
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- require 'pact/matchers/difference_indicator'
2
-
3
- module Pact
4
- class KeyNotFound < Pact::DifferenceIndicator
5
-
6
- def to_s
7
- "<key not found>"
8
- end
9
-
10
- def empty?
11
- true
12
- end
13
- end
14
-
15
- end
@@ -1,31 +0,0 @@
1
- module Pact
2
- class NullExpectation
3
- def to_s
4
- "<No expectation>"
5
- end
6
-
7
- def ==(other_object)
8
- other_object.is_a? NullExpectation
9
- end
10
-
11
- def ===(other_object)
12
- other_object.is_a? NullExpectation
13
- end
14
-
15
- def eql?(other_object)
16
- self == other_object
17
- end
18
-
19
- def hash
20
- 2934820948209428748274238642672
21
- end
22
-
23
- def empty?
24
- true
25
- end
26
-
27
- def nil?
28
- true
29
- end
30
- end
31
- end
@@ -1,80 +0,0 @@
1
- require 'pact/matchers'
2
- require 'pact/symbolize_keys'
3
- require 'pact/consumer_contract/headers'
4
-
5
- module Pact
6
-
7
- module Request
8
-
9
- class Base
10
- include Pact::Matchers
11
- include Pact::SymbolizeKeys
12
- extend Pact::Matchers
13
-
14
- attr_reader :method, :path, :headers, :body, :query, :options
15
-
16
- def initialize(method, path, headers, body, query)
17
- @method = method.to_s
18
- @path = path.chomp('/')
19
- @headers = Hash === headers ? Headers.new(headers) : headers # Could be a NullExpectation - TODO make this more elegant
20
- @body = body
21
- @query = query
22
- end
23
-
24
- def to_json(options = {})
25
- as_json.to_json(options)
26
- end
27
-
28
- def as_json options = {}
29
- to_hash
30
- end
31
-
32
- def to_hash
33
- hash = {
34
- method: method,
35
- path: path,
36
- }
37
-
38
- hash.merge!(query: query) unless query.is_a? self.class.key_not_found.class
39
- hash.merge!(headers: headers) unless headers.is_a? self.class.key_not_found.class
40
- hash.merge!(body: body) unless body.is_a? self.class.key_not_found.class
41
- hash
42
- end
43
-
44
- def method_and_path
45
- "#{method.upcase} #{full_path}"
46
- end
47
-
48
- def full_path
49
- display_path + display_query
50
- end
51
-
52
- def content_type
53
- return nil if headers.is_a? self.class.key_not_found.class
54
- headers['Content-Type']
55
- end
56
-
57
- protected
58
-
59
- def self.key_not_found
60
- raise NotImplementedError
61
- end
62
-
63
- def to_hash_without_body
64
- keep_keys = [:method, :path, :headers, :query]
65
- as_json.reject{ |key, value| !keep_keys.include? key }.tap do | hash |
66
- hash[:method] = method.upcase
67
- end
68
- end
69
-
70
- def display_path
71
- path.empty? ? "/" : path
72
- end
73
-
74
- def display_query
75
- (query.nil? || query.empty?) ? '' : "?#{Pact::Reification.from_term(query)}"
76
- end
77
-
78
- end
79
- end
80
- end
@@ -1,14 +0,0 @@
1
- require 'pact/matchers/matchers'
2
- require 'pact/matchers/difference'
3
-
4
- module Pact
5
- class TextDiffer
6
-
7
- extend Matchers
8
-
9
- def self.call expected, actual, options = {}
10
- diff expected, actual, options
11
- end
12
-
13
- end
14
- end
@@ -1,49 +0,0 @@
1
- require 'pact/symbolize_keys'
2
- module Pact
3
-
4
- # Specifies that the actual object should be considered a match if
5
- # it includes the same keys, and the values of the keys are of the same class.
6
-
7
- class SomethingLike
8
- include SymbolizeKeys
9
-
10
- attr_reader :contents
11
-
12
- def initialize contents
13
- @contents = contents
14
- end
15
-
16
- def to_hash
17
- {
18
- :json_class => self.class.name,
19
- :contents => contents
20
- }
21
- end
22
-
23
- def as_json
24
- to_hash
25
- end
26
-
27
- def to_json opts = {}
28
- as_json.to_json opts
29
- end
30
-
31
- def self.json_create hash
32
- new(symbolize_keys(hash)[:contents])
33
- end
34
-
35
- def eq other
36
- self == other
37
- end
38
-
39
- def == other
40
- other.is_a?(SomethingLike) && other.contents == self.contents
41
- end
42
-
43
- def generate
44
- contents
45
- end
46
- end
47
- end
48
-
49
-