pact-support 1.4.0 → 1.8.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +143 -0
  3. data/lib/pact/configuration.rb +4 -0
  4. data/lib/pact/consumer_contract/consumer_contract.rb +19 -8
  5. data/lib/pact/consumer_contract/http_consumer_contract_parser.rb +37 -0
  6. data/lib/pact/consumer_contract/interaction.rb +57 -56
  7. data/lib/pact/consumer_contract/interaction_parser.rb +23 -0
  8. data/lib/pact/consumer_contract/interaction_v2_parser.rb +34 -0
  9. data/lib/pact/consumer_contract/interaction_v3_parser.rb +73 -0
  10. data/lib/pact/consumer_contract/pact_file.rb +24 -24
  11. data/lib/pact/consumer_contract/provider_state.rb +34 -0
  12. data/lib/pact/consumer_contract/query.rb +0 -2
  13. data/lib/pact/consumer_contract/query_hash.rb +6 -0
  14. data/lib/pact/consumer_contract/query_string.rb +2 -2
  15. data/lib/pact/consumer_contract/request.rb +1 -5
  16. data/lib/pact/consumer_contract/string_with_matching_rules.rb +17 -0
  17. data/lib/pact/matchers/multipart_form_diff_formatter.rb +41 -0
  18. data/lib/pact/matching_rules/merge.rb +43 -28
  19. data/lib/pact/matching_rules/v3/extract.rb +94 -0
  20. data/lib/pact/matching_rules/v3/merge.rb +135 -0
  21. data/lib/pact/matching_rules.rb +19 -6
  22. data/lib/pact/reification.rb +6 -3
  23. data/lib/pact/shared/multipart_form_differ.rb +14 -0
  24. data/lib/pact/specification_version.rb +18 -0
  25. data/lib/pact/support/version.rb +1 -1
  26. data/script/release.sh +1 -1
  27. data/spec/fixtures/multipart-form-diff.txt +9 -0
  28. data/spec/fixtures/not-a-pact.json +3 -0
  29. data/spec/fixtures/pact-http-v2.json +36 -0
  30. data/spec/fixtures/pact-http-v3.json +36 -0
  31. data/spec/integration/matching_rules_extract_and_merge_spec.rb +41 -4
  32. data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +54 -31
  33. data/spec/lib/pact/consumer_contract/http_consumer_contract_parser_spec.rb +25 -0
  34. data/spec/lib/pact/consumer_contract/interaction_parser_spec.rb +62 -0
  35. data/spec/lib/pact/consumer_contract/interaction_spec.rb +2 -26
  36. data/spec/lib/pact/consumer_contract/interaction_v2_parser_spec.rb +54 -0
  37. data/spec/lib/pact/consumer_contract/interaction_v3_parser_spec.rb +48 -0
  38. data/spec/lib/pact/consumer_contract/pact_file_spec.rb +9 -0
  39. data/spec/lib/pact/consumer_contract/query_hash_spec.rb +23 -0
  40. data/spec/lib/pact/matchers/multipart_form_diff_formatter_spec.rb +36 -0
  41. data/spec/lib/pact/matching_rules/merge_spec.rb +198 -110
  42. data/spec/lib/pact/matching_rules/v3/extract_spec.rb +238 -0
  43. data/spec/lib/pact/matching_rules/v3/merge_spec.rb +462 -0
  44. data/spec/lib/pact/matching_rules_spec.rb +82 -0
  45. data/spec/lib/pact/reification_spec.rb +18 -5
  46. data/spec/lib/pact/shared/multipart_form_differ_spec.rb +39 -0
  47. data/spec/support/factories.rb +5 -0
  48. data/tasks/spec.rake +0 -1
  49. metadata +40 -3
@@ -47,6 +47,10 @@ module Pact
47
47
  @hash && @hash.empty?
48
48
  end
49
49
 
50
+ def to_hash
51
+ @hash
52
+ end
53
+
50
54
  private
51
55
 
52
56
  def convert_to_hash_of_arrays(query)
@@ -56,6 +60,8 @@ module Pact
56
60
  def insert(hash, k, v)
57
61
  if Hash === v
58
62
  v.each {|k2, v2| insert(hash, :"#{k}[#{k2}]", v2) }
63
+ elsif Pact::ArrayLike === v
64
+ hash[k.to_sym] = v
59
65
  else
60
66
  hash[k.to_sym] = [*v]
61
67
  end
@@ -4,7 +4,6 @@ module Pact
4
4
  class QueryString
5
5
 
6
6
  include ActiveSupportSupport
7
- include Pact::Matchers
8
7
 
9
8
  def initialize query
10
9
  @query = query.nil? ? query : query.dup
@@ -27,7 +26,8 @@ module Pact
27
26
  end
28
27
 
29
28
  def difference(other)
30
- diff(query, other.query)
29
+ require 'pact/matchers' # avoid recursive loop between this file and pact/matchers
30
+ Pact::Matchers.diff(query, other.query)
31
31
  end
32
32
 
33
33
  def query
@@ -2,9 +2,7 @@ require 'pact/shared/request'
2
2
  require 'pact/shared/null_expectation'
3
3
 
4
4
  module Pact
5
-
6
5
  module Request
7
-
8
6
  class Expected < Pact::Request::Base
9
7
 
10
8
  DEFAULT_OPTIONS = {:allow_unexpected_keys => false}.freeze
@@ -80,8 +78,6 @@ module Pact
80
78
  def body_differ
81
79
  Pact.configuration.body_differ_for_content_type content_type
82
80
  end
83
-
84
81
  end
85
-
86
82
  end
87
- end
83
+ end
@@ -0,0 +1,17 @@
1
+ module Pact
2
+ class StringWithMatchingRules < String
3
+ attr_reader :matching_rules
4
+ attr_reader :pact_specification_version
5
+
6
+ def initialize string, pact_specification_version, matching_rules = {}
7
+ super(string)
8
+ @matching_rules = matching_rules
9
+ @pact_specification_version = pact_specification_version
10
+ end
11
+
12
+ # How can we show the matching rules too?
13
+ def to_s
14
+ super
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ require 'pact/matchers/unix_diff_formatter'
2
+ require 'pact/matchers/differ'
3
+
4
+ module Pact
5
+ module Matchers
6
+ class MultipartFormDiffFormatter
7
+
8
+ def initialize diff, options = {}
9
+ @options = options
10
+ @body_diff = diff[:body]
11
+ @non_body_diff = diff.reject{ |k, v| k == :body }
12
+ @colour = options.fetch(:colour, false)
13
+ @differ = Pact::Matchers::Differ.new(@colour)
14
+ end
15
+
16
+ def self.call diff, options = {}
17
+ new(diff, options).call
18
+ end
19
+
20
+ def call
21
+ Pact::Matchers::UnixDiffFormatter::MESSAGES_TITLE + "\n" + non_body_diff_string + "\n" + body_diff_string
22
+ end
23
+
24
+ def non_body_diff_string
25
+ if @non_body_diff.any?
26
+ Pact::Matchers::ExtractDiffMessages.call(@non_body_diff).collect{ | message| "* #{message}" }.join("\n")
27
+ else
28
+ ""
29
+ end
30
+ end
31
+
32
+ def body_diff_string
33
+ if @body_diff
34
+ @differ.diff_as_string(@body_diff.expected, @body_diff.actual)
35
+ else
36
+ ""
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -13,11 +13,12 @@ module Pact
13
13
  @expected = expected
14
14
  @matching_rules = standardise_paths(matching_rules)
15
15
  @root_path = JsonPath.new(root_path).to_s
16
+ @used_rules = []
16
17
  end
17
18
 
18
19
  def call
19
20
  return @expected if @matching_rules.nil? || @matching_rules.empty?
20
- recurse @expected, @root_path
21
+ recurse(@expected, @root_path).tap { log_ignored_rules }
21
22
  end
22
23
 
23
24
  private
@@ -30,36 +31,42 @@ module Pact
30
31
  end
31
32
 
32
33
  def recurse expected, path
33
- case expected
34
+ recursed = case expected
34
35
  when Hash then recurse_hash(expected, path)
35
36
  when Array then recurse_array(expected, path)
36
37
  else
37
38
  expected
38
39
  end
40
+
41
+ wrap(recursed, path)
39
42
  end
40
43
 
41
44
  def recurse_hash hash, path
42
- hash.each_with_object({}) do | (k, v), new_hash |
45
+ recursed = hash.each_with_object({}) do | (k, v), new_hash |
43
46
  new_path = path + "['#{k}']"
44
- new_hash[k] = recurse(wrap(v, new_path), new_path)
47
+ new_hash[k] = recurse(v, new_path)
45
48
  end
46
49
  end
47
50
 
48
51
  def recurse_array array, path
52
+ parent_match_rule = find_rule(path, 'match')
53
+ log_used_rule(path, 'match', parent_match_rule) if parent_match_rule
54
+
49
55
  array_like_children_path = "#{path}[*]*"
50
- parent_match_rule = @matching_rules[path] && @matching_rules[path]['match']
51
- children_match_rule = @matching_rules[array_like_children_path] && @matching_rules[array_like_children_path]['match']
52
- min = @matching_rules[path] && @matching_rules[path]['min']
56
+ children_match_rule = find_rule(array_like_children_path, 'match')
57
+ log_used_rule(array_like_children_path, 'match', children_match_rule) if children_match_rule
58
+
59
+ min = find_rule(path, 'min')
60
+ log_used_rule(path, 'min', min) if min
53
61
 
54
62
  if min && (children_match_rule == 'type' || (children_match_rule.nil? && parent_match_rule == 'type'))
55
63
  warn_when_not_one_example_item(array, path)
56
- # log_ignored_rules(path, @matching_rules[path], {'min' => min})
57
64
  Pact::ArrayLike.new(recurse(array.first, "#{path}[*]"), min: min)
58
65
  else
59
66
  new_array = []
60
67
  array.each_with_index do | item, index |
61
68
  new_path = path + "[#{index}]"
62
- new_array << recurse(wrap(item, new_path), new_path)
69
+ new_array << recurse(item, new_path)
63
70
  end
64
71
  new_array
65
72
  end
@@ -72,39 +79,47 @@ module Pact
72
79
  end
73
80
 
74
81
  def wrap object, path
75
- rules = @matching_rules[path]
76
- array_rules = @matching_rules["#{path}[*]*"]
77
- return object unless rules || array_rules
78
-
79
- if rules['match'] == 'type' && !rules.has_key?('min')
80
- handle_match_type(object, path, rules)
81
- elsif rules['regex']
82
- handle_regex(object, path, rules)
82
+ if find_rule(path, 'match') == 'type' && !find_rule(path, 'min')
83
+ handle_match_type(object, path)
84
+ elsif find_rule(path, 'regex')
85
+ handle_regex(object, path)
83
86
  else
84
- log_ignored_rules(path, rules, {})
85
87
  object
86
88
  end
87
89
  end
88
90
 
89
- def handle_match_type object, path, rules
90
- log_ignored_rules(path, rules, {'match' => 'type'})
91
+ def handle_match_type object, path
92
+ log_used_rule(path, 'match', 'type')
91
93
  Pact::SomethingLike.new(object)
92
94
  end
93
95
 
94
- def handle_regex object, path, rules
95
- log_ignored_rules(path, rules, {'match' => 'regex', 'regex' => rules['regex']})
96
- Pact::Term.new(generate: object, matcher: Regexp.new(rules['regex']))
96
+ def handle_regex object, path
97
+ regex = find_rule(path, 'regex')
98
+ log_used_rule(path, 'match', 'regex') # assumed to be present
99
+ log_used_rule(path, 'regex', regex)
100
+ Pact::Term.new(generate: object, matcher: Regexp.new(regex))
97
101
  end
98
102
 
99
- def log_ignored_rules path, rules, used_rules
100
- dup_rules = rules.dup
101
- used_rules.each_pair do | used_key, used_value |
102
- dup_rules.delete(used_key) if dup_rules[used_key] == used_value
103
+ def log_ignored_rules
104
+ dup_rules = @matching_rules.dup
105
+ @used_rules.each do | (path, key, value) |
106
+ dup_rules[path].delete(key) if dup_rules[path][key] == value
103
107
  end
108
+
104
109
  if dup_rules.any?
105
- $stderr.puts "WARN: Ignoring unsupported matching rules #{dup_rules} for path #{path}"
110
+ dup_rules.each do | path, rules |
111
+ $stderr.puts "WARN: Ignoring unsupported matching rules #{rules} for path #{path}" if rules.any?
112
+ end
106
113
  end
107
114
  end
115
+
116
+ def find_rule(path, key)
117
+ @matching_rules[path] && @matching_rules[path][key]
118
+ end
119
+
120
+ def log_used_rule path, key, value
121
+ @used_rules << [path, key, value]
122
+ end
108
123
  end
109
124
  end
110
125
  end
@@ -0,0 +1,94 @@
1
+ require 'pact/something_like'
2
+ require 'pact/array_like'
3
+ require 'pact/term'
4
+
5
+ module Pact
6
+ module MatchingRules::V3
7
+ class Extract
8
+
9
+ def self.call matchable
10
+ new(matchable).call
11
+ end
12
+
13
+ def initialize matchable
14
+ @matchable = matchable
15
+ @rules = Hash.new
16
+ end
17
+
18
+ def call
19
+ recurse matchable, "$", nil
20
+ rules
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :matchable, :rules
26
+
27
+ def recurse object, path, match_type
28
+ case object
29
+ when Hash then recurse_hash(object, path, match_type)
30
+ when Array then recurse_array(object, path, match_type)
31
+ when Pact::SomethingLike then handle_something_like(object, path, match_type)
32
+ when Pact::ArrayLike then handle_array_like(object, path, match_type)
33
+ when Pact::Term then record_regex_rule object, path
34
+ when Pact::QueryString then recurse(object.query, path, match_type)
35
+ when Pact::QueryHash then recurse_hash(object.query, path, match_type)
36
+ end
37
+ end
38
+
39
+ def recurse_hash hash, path, match_type
40
+ hash.each do | (key, value) |
41
+ recurse value, "#{path}#{next_path_part(key)}", match_type
42
+ end
43
+ end
44
+
45
+ def recurse_array new_array, path, match_type
46
+ new_array.each_with_index do | value, index |
47
+ recurse value, "#{path}[#{index}]", match_type
48
+ end
49
+ end
50
+
51
+ def handle_something_like something_like, path, match_type
52
+ record_match_type_rule path, "type"
53
+ recurse something_like.contents, path, "type"
54
+ end
55
+
56
+ def handle_array_like array_like, path, match_type
57
+ record_rule "#{path}", 'min' => array_like.min
58
+ record_match_type_rule "#{path}[*].*", 'type'
59
+ recurse array_like.contents, "#{path}[*]", :array_like
60
+ end
61
+
62
+ def record_rule path, rule
63
+ rules[path] ||= {}
64
+ rules[path]['matchers'] ||= []
65
+ rules[path]['matchers'] << rule
66
+ end
67
+
68
+ def record_regex_rule term, path
69
+ rules[path] ||= {}
70
+ rules[path]['matchers'] ||= []
71
+ rule = { 'match' => 'regex', 'regex' => term.matcher.inspect[1..-2]}
72
+ rules[path]['matchers'] << rule
73
+ end
74
+
75
+ def record_match_type_rule path, match_type
76
+ unless match_type == :array_like || match_type.nil?
77
+ rules[path] ||= {}
78
+ rules[path]['matchers'] ||= []
79
+ rules[path]['matchers'] << { 'match' => match_type }
80
+ end
81
+ end
82
+
83
+ # Beth: there's a potential bug if the key contains a dot and a single quote.
84
+ # Not sure what to do then.
85
+ def next_path_part key
86
+ if key.to_s.include?('.')
87
+ "['#{key}']"
88
+ else
89
+ ".#{key}"
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,135 @@
1
+ require 'pact/array_like'
2
+ require 'pact/matching_rules/jsonpath'
3
+
4
+ module Pact
5
+ module MatchingRules
6
+ module V3
7
+ class Merge
8
+
9
+ def self.call expected, matching_rules, root_path = '$'
10
+ new(expected, matching_rules, root_path).call
11
+ end
12
+
13
+ def initialize expected, matching_rules, root_path
14
+ @expected = expected
15
+ @matching_rules = standardise_paths(matching_rules)
16
+ @root_path = JsonPath.new(root_path).to_s
17
+ end
18
+
19
+ def call
20
+ return @expected if @matching_rules.nil? || @matching_rules.empty?
21
+ recurse(@expected, @root_path).tap { log_ignored_rules }
22
+ end
23
+
24
+ private
25
+
26
+ def standardise_paths matching_rules
27
+ return matching_rules if matching_rules.nil? || matching_rules.empty?
28
+ matching_rules.each_with_object({}) do | (path, rules), new_matching_rules |
29
+ new_matching_rules[JsonPath.new(path).to_s] = Marshal.load(Marshal.dump(rules)) # simplest way to deep clone
30
+ end
31
+ end
32
+
33
+ def recurse expected, path
34
+ recursed = case expected
35
+ when Hash then recurse_hash(expected, path)
36
+ when Array then recurse_array(expected, path)
37
+ else
38
+ expected
39
+ end
40
+ wrap(recursed, path)
41
+ end
42
+
43
+ def recurse_hash hash, path
44
+ hash.each_with_object({}) do | (k, v), new_hash |
45
+ new_path = path + "['#{k}']"
46
+ new_hash[k] = recurse(v, new_path)
47
+ end
48
+ end
49
+
50
+ def recurse_array array, path
51
+ # This assumes there is only one rule! TODO make this find the appropriate rule.
52
+ parent_match_rule = @matching_rules[path]['matchers'].first['match'] rescue nil
53
+ array_like_children_path = "#{path}[*]*"
54
+ children_match_rule = @matching_rules[array_like_children_path]['matchers'].first['match'] rescue nil
55
+ min = @matching_rules[path]['matchers'].first['min'] rescue nil
56
+
57
+ if min && children_match_rule == 'type'
58
+ @matching_rules[path]['matchers'].first.delete('min')
59
+ @matching_rules[array_like_children_path]['matchers'].first.delete('match')
60
+ warn_when_not_one_example_item(array, path)
61
+ Pact::ArrayLike.new(recurse(array.first, "#{path}[*]"), min: min)
62
+ elsif min && parent_match_rule == 'type'
63
+ @matching_rules[path]['matchers'].first.delete('min')
64
+ @matching_rules[path]['matchers'].first.delete('match')
65
+ warn_when_not_one_example_item(array, path)
66
+ Pact::ArrayLike.new(recurse(array.first, "#{path}[*]"), min: min)
67
+ else
68
+ new_array = []
69
+ array.each_with_index do | item, index |
70
+ new_path = path + "[#{index}]"
71
+ new_array << recurse(item, new_path)
72
+ end
73
+ new_array
74
+ end
75
+ end
76
+
77
+ def warn_when_not_one_example_item array, path
78
+ unless array.size == 1
79
+ Pact.configuration.error_stream.puts "WARN: Only the first item will be used to match the items in the array at #{path}"
80
+ end
81
+ end
82
+
83
+ def wrap object, path
84
+ rules = @matching_rules[path] && @matching_rules[path]['matchers'] && @matching_rules[path]['matchers'].first
85
+ array_rules = @matching_rules["#{path}[*]*"] && @matching_rules["#{path}[*]*"]['matchers'] && @matching_rules["#{path}[*]*"]['matchers'].first
86
+ return object unless rules || array_rules
87
+
88
+ if rules['match'] == 'type' && !rules.has_key?('min')
89
+ handle_match_type(object, path, rules)
90
+ elsif rules['regex']
91
+ handle_regex(object, path, rules)
92
+ else
93
+ object
94
+ end
95
+ end
96
+
97
+ def handle_match_type object, path, rules
98
+ rules.delete('match')
99
+ Pact::SomethingLike.new(object)
100
+ end
101
+
102
+ def handle_regex object, path, rules
103
+ rules.delete('match')
104
+ regex = rules.delete('regex')
105
+ Pact::Term.new(generate: object, matcher: Regexp.new(regex))
106
+ end
107
+
108
+ def log_ignored_rules
109
+ @matching_rules.each do | jsonpath, rules_hash |
110
+ rules_array = rules_hash["matchers"]
111
+ ((rules_array.length - 1)..0).each do | index |
112
+ rules_array.delete_at(index) if rules_array[index].empty?
113
+ end
114
+ end
115
+
116
+ if @matching_rules.any?
117
+ @matching_rules.each do | path, rules_hash |
118
+ rules_hash.each do | key, value |
119
+ $stderr.puts "WARN: Ignoring unsupported #{key} #{value} for path #{path}" if value.any?
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ def find_rule(path, key)
126
+ @matching_rules[path] && @matching_rules[path][key]
127
+ end
128
+
129
+ def log_used_rule path, key, value
130
+ @used_rules << [path, key, value]
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -1,17 +1,30 @@
1
1
  require 'pact/matching_rules/extract'
2
+ require 'pact/matching_rules/v3/extract'
2
3
  require 'pact/matching_rules/merge'
4
+ require 'pact/matching_rules/v3/merge'
3
5
 
4
6
  module Pact
5
7
  module MatchingRules
6
8
 
7
9
  # @api public Used by pact-mock_service
8
- def self.extract object_graph
9
- Extract.(object_graph)
10
+ def self.extract object_graph, options = {}
11
+ pact_specification_version = options[:pact_specification_version] || Pact::SpecificationVersion::NIL_VERSION
12
+ case pact_specification_version.major
13
+ when nil, 0, 1, 2
14
+ Extract.(object_graph)
15
+ else
16
+ V3::Extract.(object_graph)
17
+ end
10
18
  end
11
19
 
12
- def self.merge object_graph, matching_rules
13
- Merge.(object_graph, matching_rules)
20
+ def self.merge object_graph, matching_rules, options = {}
21
+ pact_specification_version = options[:pact_specification_version] || Pact::SpecificationVersion::NIL_VERSION
22
+ case pact_specification_version.major
23
+ when nil, 0, 1, 2
24
+ Merge.(object_graph, matching_rules)
25
+ else
26
+ V3::Merge.(object_graph, matching_rules)
27
+ end
14
28
  end
15
-
16
29
  end
17
- end
30
+ end
@@ -5,6 +5,7 @@ require 'pact/array_like'
5
5
  require 'pact/shared/request'
6
6
  require 'pact/consumer_contract/query_hash'
7
7
  require 'pact/consumer_contract/query_string'
8
+ require 'pact/consumer_contract/string_with_matching_rules'
8
9
 
9
10
  module Pact
10
11
  module Reification
@@ -26,15 +27,17 @@ module Pact
26
27
  when Pact::QueryString
27
28
  from_term(term.query)
28
29
  when Pact::QueryHash
29
- term.query.map { |k, v|
30
+ from_term(term.query).map { |k, v|
30
31
  if v.nil?
31
32
  k
32
33
  elsif v.is_a?(Array) #For cases where there are multiple instance of the same parameter
33
- v.map { |x| "#{k}=#{escape(from_term(x))}"}.join('&')
34
+ v.map { |x| "#{k}=#{escape(x)}"}.join('&')
34
35
  else
35
- "#{k}=#{escape(from_term(v))}"
36
+ "#{k}=#{escape(v)}"
36
37
  end
37
38
  }.join('&')
39
+ when Pact::StringWithMatchingRules
40
+ String.new(term)
38
41
  else
39
42
  term
40
43
  end
@@ -0,0 +1,14 @@
1
+ require 'uri'
2
+ require 'pact/shared/text_differ'
3
+
4
+ module Pact
5
+ class MultipartFormDiffer
6
+ def self.call expected, actual, options = {}
7
+ require 'pact/matchers' # avoid recursive loop between this file and pact/matchers
8
+ expected_boundary = expected.split.first
9
+ actual_boundary = actual.split.first
10
+ actual_with_hardcoded_boundary = actual.gsub(actual_boundary, expected_boundary)
11
+ TextDiffer.call(expected, actual_with_hardcoded_boundary, options)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module Pact
2
+ class SpecificationVersion < Gem::Version
3
+
4
+ def major
5
+ segments.first
6
+ end
7
+
8
+ def === other
9
+ major && major == other
10
+ end
11
+
12
+ def after? other
13
+ major && other < major
14
+ end
15
+ end
16
+
17
+ SpecificationVersion::NIL_VERSION = Pact::SpecificationVersion.new('0')
18
+ end
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module Support
3
- VERSION = "1.4.0"
3
+ VERSION = "1.8.0"
4
4
  end
5
5
  end
data/script/release.sh CHANGED
@@ -5,5 +5,5 @@ git checkout -- lib/pact/support/version.rb
5
5
  bundle exec bump ${1:-minor} --no-commit
6
6
  bundle exec rake generate_changelog
7
7
  git add CHANGELOG.md lib/pact/support/version.rb
8
- git commit -m "Releasing version $(ruby -r ./lib/pact/support/version.rb -e "puts Pact::Support::VERSION")"
8
+ git commit -m "chore(release): version $(ruby -r ./lib/pact/support/version.rb -e "puts Pact::Support::VERSION")"
9
9
  bundle exec rake release
@@ -0,0 +1,9 @@
1
+
2
+
3
+ Description of differences
4
+ --------------------------------------
5
+ * Wrong header
6
+
7
+ @@ -1,2 +1,2 @@
8
+ -bar
9
+ +foo
@@ -0,0 +1,3 @@
1
+ {
2
+ "foo": "bar"
3
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "consumer": {
3
+ "name": "some-test-consumer"
4
+ },
5
+ "provider": {
6
+ "name": "an unknown provider"
7
+ },
8
+ "interactions": [
9
+ {
10
+ "description": "a test request",
11
+ "request": {
12
+ "method": "get",
13
+ "path": "/weather",
14
+ "query": ""
15
+ },
16
+ "response": {
17
+ "matchingRules": {
18
+ "$.headers.Content-Type" : {
19
+ "match": "regex", "regex": "json"
20
+ },
21
+ "$.body.message" : {
22
+ "match": "regex", "regex": "sun"
23
+ }
24
+ },
25
+ "status": 200,
26
+ "headers" : {
27
+ "Content-Type": "foo/json"
28
+ },
29
+ "body": {
30
+ "message" : "sunful"
31
+ }
32
+ },
33
+ "provider_state": "the weather is sunny"
34
+ }
35
+ ]
36
+ }