pact 1.3.3 → 1.4.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
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
-