Skip to content

Commit ccb82b9

Browse files
committed
feat: add more matchers
contentType null semver values notEmpty statusCode
1 parent 13bfb5c commit ccb82b9

File tree

9 files changed

+195
-9
lines changed

9 files changed

+195
-9
lines changed

lib/pact/v2/matchers.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,22 @@ def match_each_value(template, value_matchers = V2::Type.new(""))
8989
def match_each_kv(template, key_matchers)
9090
V4::EachKeyValue.new(key_matchers.is_a?(Array) ? key_matchers : [key_matchers], template)
9191
end
92+
93+
def match_semver(template = nil)
94+
V3::Semver.new(template)
95+
end
96+
97+
def match_content_type(content_type, template = nil)
98+
V3::ContentType.new(content_type, template: template)
99+
end
100+
101+
def match_not_empty(template = nil)
102+
V4::NotEmpty.new(template)
103+
end
104+
105+
def match_status_code(template)
106+
V4::StatusCode.new(template)
107+
end
92108
end
93109
end
94110
end

lib/pact/v2/matchers/base.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,30 @@ class Base
99

1010
class MatcherInitializationError < Pact::V2::Error; end
1111

12-
def initialize(spec_version:, kind:, template:, opts: {})
12+
def initialize(spec_version:, kind:, template: nil, opts: {})
1313
@spec_version = spec_version
1414
@kind = kind
1515
@template = template
1616
@opts = opts
1717
end
1818

1919
def as_basic
20-
{
21-
"pact:matcher:type" => serialize!(@kind.deep_dup, :basic),
22-
"value" => serialize!(@template.deep_dup, :basic)
23-
}.merge(serialize!(@opts.deep_dup, :basic))
20+
result = {
21+
"pact:matcher:type" => serialize!(@kind.deep_dup, :basic)
22+
}
23+
result["status"] = serialize!(@opts[:status].deep_dup, :basic) if @opts[:status]
24+
result["value"] = serialize!(@template.deep_dup, :basic) unless @template.nil?
25+
result.merge!(serialize!(@opts.deep_dup, :basic))
26+
result
2427
end
2528

2629
def as_plugin
2730
params = @opts.values.map { |v| format_primitive(v) }.join(",")
28-
value = format_primitive(@template)
31+
value = format_primitive(@template) unless @template.nil?
32+
33+
if @template.nil?
34+
return "matching(#{@kind}#{params.present? ? ", #{params}" : ""})"
35+
end
2936

3037
return "matching(#{@kind}, #{params}, #{value})" if params.present?
3138

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
module Pact
4+
module V2
5+
module Matchers
6+
module V3
7+
class ContentType < Pact::V2::Matchers::Base
8+
def initialize(content_type, template: nil)
9+
@content_type = content_type
10+
@template = template
11+
@opts = {}
12+
@opts[:plugin_template] = template unless template.nil?
13+
unless content_type.is_a?(String) && !content_type.empty?
14+
raise MatcherInitializationError, "#{self.class}: content_type must be a non-empty String"
15+
end
16+
17+
super(
18+
spec_version: Pact::V2::Matchers::PACT_SPEC_V3,
19+
kind: "contentType",
20+
template: content_type,
21+
opts: @opts
22+
)
23+
end
24+
25+
def as_plugin
26+
"matching(contentType, '#{@content_type}', '#{@opts[:plugin_template]}')"
27+
end
28+
end
29+
end
30+
end
31+
end
32+
end

lib/pact/v2/matchers/v3/null.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
module Pact
4+
module V2
5+
module Matchers
6+
module V3
7+
class Null < Pact::V2::Matchers::Base
8+
def initialize
9+
super(spec_version: Pact::V2::Matchers::PACT_SPEC_V3, kind: "null", template: nil)
10+
end
11+
12+
end
13+
end
14+
end
15+
end
16+
end

lib/pact/v2/matchers/v3/semver.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
module Pact
4+
module V2
5+
module Matchers
6+
module V3
7+
class Semver < Pact::V2::Matchers::Base
8+
def initialize(template = nil)
9+
@template = template
10+
super(spec_version: Pact::V2::Matchers::PACT_SPEC_V3, kind: "semver", template: template)
11+
end
12+
13+
def as_plugin
14+
if @template.nil? || @template.blank?
15+
raise MatcherInitializationError, "#{self.class}: template must be provided when calling as_plugin"
16+
end
17+
"matching(semver, '#{@template}')"
18+
end
19+
end
20+
end
21+
end
22+
end
23+
end

lib/pact/v2/matchers/v3/values.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
module Pact
4+
module V2
5+
module Matchers
6+
module V3
7+
class Values < Pact::V2::Matchers::Base
8+
def initialize
9+
super(spec_version: Pact::V2::Matchers::PACT_SPEC_V3, kind: "values", template: nil)
10+
end
11+
12+
end
13+
end
14+
end
15+
end
16+
end

lib/pact/v2/matchers/v4/not_empty.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@ module V2
55
module Matchers
66
module V4
77
class NotEmpty < Pact::V2::Matchers::Base
8-
def initialize(template)
9-
raise MatcherInitializationError, "#{self.class}: #{template} should not be empty" if template.blank?
8+
def initialize(template = nil)
9+
@template = template
10+
super(spec_version: Pact::V2::Matchers::PACT_SPEC_V4, kind: 'notEmpty', template: @template)
11+
end
12+
13+
def as_plugin
14+
if @template.nil? || @template.blank?
15+
raise MatcherInitializationError, "#{self.class}: template must be provided when calling as_plugin"
16+
end
1017

11-
super(spec_version: Pact::V2::Matchers::PACT_SPEC_V4, kind: "time", template: template)
18+
"notEmpty('#{@template}')"
1219
end
1320
end
1421
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
module Pact
4+
module V2
5+
module Matchers
6+
module V4
7+
class StatusCode < Pact::V2::Matchers::Base
8+
def initialize(template = nil)
9+
super(spec_version: Pact::V2::Matchers::PACT_SPEC_V4, kind: 'statusCode', opts: {
10+
'status' => template
11+
})
12+
end
13+
end
14+
end
15+
end
16+
end
17+
end

spec/v2/pact/matchers_spec.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,46 @@
289289
}
290290
})
291291
end
292+
293+
it "properly builds semver matcher" do
294+
expect(test_class.match_semver.as_basic).to eq({
295+
"pact:matcher:type" => "semver",
296+
})
297+
end
298+
it "properly builds content_type matcher" do
299+
expect(test_class.match_content_type("application/xml").as_basic).to eq({
300+
"pact:matcher:type" => "contentType",
301+
"value" => "application/xml"
302+
})
303+
end
304+
it "properly builds not_empty matcher" do
305+
expect(test_class.match_not_empty.as_basic).to eq({
306+
"pact:matcher:type" => "notEmpty"
307+
})
308+
end
309+
310+
it "properly builds values matcher" do
311+
expect(Pact::V2::Matchers::V3::Values.new.as_basic).to eq({
312+
"pact:matcher:type" => "values"
313+
})
314+
end
315+
316+
it "properly builds null matcher" do
317+
expect(Pact::V2::Matchers::V3::Null.new.as_basic).to eq({
318+
"pact:matcher:type" => "null"
319+
})
320+
end
321+
322+
it "properly builds status_code matcher" do
323+
expect(test_class.match_status_code(200).as_basic).to eq({
324+
"pact:matcher:type" => "statusCode",
325+
"status" => 200
326+
})
327+
expect(test_class.match_status_code('nonError').as_basic).to eq({
328+
"pact:matcher:type" => "statusCode",
329+
"status" => 'nonError'
330+
})
331+
end
292332
end
293333

294334
context "with plugin format serialization" do
@@ -409,6 +449,18 @@
409449
}
410450
})
411451
end
452+
453+
it "properly builds semver matcher" do
454+
expect(test_class.match_semver("1.2.3").as_plugin).to eq("matching(semver, '1.2.3')")
455+
end
456+
457+
it "properly builds content_type matcher" do
458+
expect(test_class.match_content_type("application/xml", '<?xml?><test/>').as_plugin).to eq("matching(contentType, 'application/xml', '<?xml?><test/>')")
459+
end
460+
461+
it "properly builds not_empty matcher" do
462+
expect(test_class.match_not_empty("some value").as_plugin).to eq("notEmpty('some value')")
463+
end
412464
end
413465

414466
context "with common regex" do

0 commit comments

Comments
 (0)