From aae0da5a005376beb3430687d56961c27e22085c Mon Sep 17 00:00:00 2001 From: Lindomar Reitz Date: Sat, 22 Jul 2017 15:37:31 +0100 Subject: [PATCH 1/7] Change generate to convert the values to string. --- lib/pact/term.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pact/term.rb b/lib/pact/term.rb index 67e241e..a6b2d99 100644 --- a/lib/pact/term.rb +++ b/lib/pact/term.rb @@ -24,9 +24,11 @@ def self.unpack_regexps source def initialize(attributes = {}) @generate = attributes[:generate] + raise "Please specify a value to generate for the Term" unless @generate != nil + + @generate = @generate.to_s @matcher = attributes[:matcher] raise "Please specify a matcher for the Term" unless @matcher != nil - raise "Please specify a value to generate for the Term" unless @generate != nil raise "Value to generate \"#{@generate}\" does not match regular expression #{@matcher.inspect}" unless @generate =~ @matcher end From 9be2736271aa2aa9f6b6994ef104c40c9d17cc92 Mon Sep 17 00:00:00 2001 From: Lindomar Reitz Date: Sat, 22 Jul 2017 15:38:09 +0100 Subject: [PATCH 2/7] Add tests to match integer/float values. --- spec/lib/pact/term_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/lib/pact/term_spec.rb b/spec/lib/pact/term_spec.rb index 56e3a6a..15d73a0 100644 --- a/spec/lib/pact/term_spec.rb +++ b/spec/lib/pact/term_spec.rb @@ -14,6 +14,22 @@ module Pact end end + context "when the generate is a integer" do + let(:term) { Term.new(generate: 10, matcher: /[0-9]/)} + + it 'does not raise an exception' do + term + end + end + + context "when the generate is a float" do + let(:term) { Term.new(generate: 50.51, matcher: /\d(\.\d{1,2})/)} + + it 'does not raise an exception' do + term + end + end + context "when the matcher does not match the generated value" do let(:generate) { 'banana' } it 'raises an exception' do From f2c448ce3f3f915710d3dee91b3d560cc43404bc Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Wed, 14 Aug 2024 15:00:08 +0100 Subject: [PATCH 3/7] chore: ensure int/floats stored in pact as such, and processed at verification --- lib/pact/matchers/matchers.rb | 8 +++++++- lib/pact/term.rb | 10 ++++++---- .../matchers/matchers_messages_regexp_spec.rb | 18 ++++++++++++++++-- spec/lib/pact/term_spec.rb | 10 +++++----- spec/support/ruby_version_helpers.rb | 4 ++++ 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/pact/matchers/matchers.rb b/lib/pact/matchers/matchers.rb index 8f5bb88..0455425 100644 --- a/lib/pact/matchers/matchers.rb +++ b/lib/pact/matchers/matchers.rb @@ -61,6 +61,12 @@ def calculate_diff expected, actual, opts = {} alias_method :structure_diff, :type_diff # Backwards compatibility def term_diff term, actual, options + if actual.is_a?(Float) || actual.is_a?(Integer) + options[:original] = actual + options[:was_float] = actual.is_a?(Float) + options[:was_int] = actual.is_a?(Integer) + actual = actual.to_s + end if actual.is_a?(String) actual_term_diff term, actual, options else @@ -72,7 +78,7 @@ def actual_term_diff term, actual, options if term.matcher.match(actual) NO_DIFF else - RegexpDifference.new term.matcher, actual, "Expected a String matching #{term.matcher.inspect} (like #{term.generate.inspect}) but got #{actual.inspect} at " + RegexpDifference.new term.matcher, options[:original] ||= actual, "Expected a #{options[:was_float] ? "Float" : options[:was_int] ? "Integer" : "String" } matching #{term.matcher.inspect} (like #{term.generate.inspect}) but got #{options[:was_float] || options[:was_int] ? class_name_with_value_in_brackets(options[:original]) : actual.inspect} at " end end diff --git a/lib/pact/term.rb b/lib/pact/term.rb index cf83c69..69f8ce9 100644 --- a/lib/pact/term.rb +++ b/lib/pact/term.rb @@ -26,12 +26,14 @@ def self.unpack_regexps source def initialize(attributes = {}) @generate = attributes[:generate] - raise Pact::Error.new("Please specify a value to generate for the Term") unless @generate != nil - - @generate = @generate.to_s @matcher = attributes[:matcher] raise Pact::Error.new("Please specify a matcher for the Term") unless @matcher != nil - raise Pact::Error.new("Value to generate '#{@generate}' does not match regular expression #{@matcher.inspect}") unless @generate =~ @matcher + raise Pact::Error.new("Please specify a value to generate for the Term") unless @generate != nil + if @generate.is_a?(Float) || @generate.is_a?(Integer) + raise Pact::Error.new("#{@generate.is_a?(Float) ? "Float" : "Integer"} Value to generate '#{@generate}' does not match regular expression #{@matcher.inspect} when converted to string") unless @generate.to_s =~ @matcher + else + raise Pact::Error.new("Value to generate '#{@generate}' does not match regular expression #{@matcher.inspect}") unless @generate =~ @matcher + end end def to_hash diff --git a/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb b/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb index 4eadeda..596255a 100644 --- a/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb +++ b/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb @@ -34,7 +34,14 @@ module Pact::Matchers context "when the actual is a numeric" do let(:actual) { INT } it "returns a message" do - expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got #{a_numeric} (1) at " + expect(difference[:thing].message).to eq "Expected a Integer matching /foo/ (like \"food\") but got #{a_numeric} (1) at " + end + end + + context "when the actual is a float" do + let(:actual) { FLOAT } + it "returns a message" do + expect(difference[:thing].message).to eq "Expected a Float matching /foo/ (like \"food\") but got #{a_float} (1.0) at " end end @@ -48,7 +55,14 @@ module Pact::Matchers context "when the actual is a numeric" do let(:actual) { INT } it "returns a message" do - expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got #{a_numeric} (1) at " + expect(difference[:thing].message).to eq "Expected a Integer matching /foo/ (like \"food\") but got #{a_numeric} (1) at " + end + end + + context "when the actual is a float" do + let(:actual) { FLOAT } + it "returns a message" do + expect(difference[:thing].message).to eq "Expected a Float matching /foo/ (like \"food\") but got #{a_float} (1.0) at " end end diff --git a/spec/lib/pact/term_spec.rb b/spec/lib/pact/term_spec.rb index 4c17fbe..414ca09 100644 --- a/spec/lib/pact/term_spec.rb +++ b/spec/lib/pact/term_spec.rb @@ -15,19 +15,19 @@ module Pact end context "when the generate is a integer" do - let(:term) { Term.new(generate: 10, matcher: /[0-9]/)} + let(:term) { Term.new(generate: 10, matcher: /[0-9]/)} it 'does not raise an exception' do term - end + end end - + context "when the generate is a float" do - let(:term) { Term.new(generate: 50.51, matcher: /\d(\.\d{1,2})/)} + let(:term) { Term.new(generate: 50.51, matcher: /\d(\.\d{1,2})/)} it 'does not raise an exception' do term - end + end end context "when the matcher does not match the generated value" do diff --git a/spec/support/ruby_version_helpers.rb b/spec/support/ruby_version_helpers.rb index b7602a0..6abcc05 100644 --- a/spec/support/ruby_version_helpers.rb +++ b/spec/support/ruby_version_helpers.rb @@ -20,4 +20,8 @@ def a_numeric end end module_function :a_numeric + def a_float + "a #{Float}" + end + module_function :a_float end From 75a36cd2ad367add86da3fb2e99f0d09f5f4f7e0 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Wed, 14 Aug 2024 15:57:15 +0100 Subject: [PATCH 4/7] feat: add like_integer / like_decimal helpers --- lib/pact/helpers.rb | 8 ++++++++ spec/lib/pact/helpers_spec.rb | 21 +++++++++++++++++++++ spec/lib/pact/term_spec.rb | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/pact/helpers.rb b/lib/pact/helpers.rb index c6c8228..c4e663f 100644 --- a/lib/pact/helpers.rb +++ b/lib/pact/helpers.rb @@ -47,6 +47,14 @@ def like_date date Pact::Term.new(generate: date, matcher: /^\d{4}-[01]\d-[0-3]\d$/) end + def like_integer int + Pact::Term.new(generate: int, matcher: /[0-9]/) + end + + def like_decimal float + Pact::Term.new(generate: float, matcher: /[-+]?([0-9]*\.[0-9]+|[0-9]+)/) + end + def like_datetime_rfc822 datetime Pact::Term.new( generate: datetime, diff --git a/spec/lib/pact/helpers_spec.rb b/spec/lib/pact/helpers_spec.rb index 86a6eff..3381eb9 100644 --- a/spec/lib/pact/helpers_spec.rb +++ b/spec/lib/pact/helpers_spec.rb @@ -139,5 +139,26 @@ module Pact end end + + describe "#like_integer" do + let(:integer) { 1 } + + it "creates a Pact::Term with regex matcher for integers" do + expect(like_integer(integer)).to eq Pact::Term.new( + generate: integer, + matcher: /[0-9]/ + ) + end + end + describe "#like_decimal" do + let(:float) { 10.2 } + + it "creates a Pact::Term with regex matcher for decimals" do + expect(like_decimal(10.2)).to eq Pact::Term.new( + generate: float, + matcher: /[-+]?([0-9]*\.[0-9]+|[0-9]+)/ + ) + end + end end end diff --git a/spec/lib/pact/term_spec.rb b/spec/lib/pact/term_spec.rb index 414ca09..f899a58 100644 --- a/spec/lib/pact/term_spec.rb +++ b/spec/lib/pact/term_spec.rb @@ -23,7 +23,7 @@ module Pact end context "when the generate is a float" do - let(:term) { Term.new(generate: 50.51, matcher: /\d(\.\d{1,2})/)} + let(:term) { Term.new(generate: 50.51, matcher: /[-+]?([0-9]*\.[0-9]+|[0-9]+)/)} it 'does not raise an exception' do term From 3cd978d20aff522040ef7e6429b1447b9e296925 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Wed, 14 Aug 2024 16:04:52 +0100 Subject: [PATCH 5/7] chore: match regex with pact-jvm for int/decimal https://github.com/pact-foundation/pact-jvm/blob/00442e6df51e5be906ed470b19859246312e5c83/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/MatcherExecutor.kt\#L56-L59 --- lib/pact/helpers.rb | 6 ++++-- spec/lib/pact/helpers_spec.rb | 4 ++-- spec/lib/pact/term_spec.rb | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/pact/helpers.rb b/lib/pact/helpers.rb index c4e663f..3059dc0 100644 --- a/lib/pact/helpers.rb +++ b/lib/pact/helpers.rb @@ -47,12 +47,14 @@ def like_date date Pact::Term.new(generate: date, matcher: /^\d{4}-[01]\d-[0-3]\d$/) end + # regex matched with pact-jvm + # https://github.com/pact-foundation/pact-jvm/blob/00442e6df51e5be906ed470b19859246312e5c83/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/MatcherExecutor.kt#L56-L59 def like_integer int - Pact::Term.new(generate: int, matcher: /[0-9]/) + Pact::Term.new(generate: int, matcher: /^-?\d+$/) end def like_decimal float - Pact::Term.new(generate: float, matcher: /[-+]?([0-9]*\.[0-9]+|[0-9]+)/) + Pact::Term.new(generate: float, matcher: /^0|-?\d+\.\d*$/) end def like_datetime_rfc822 datetime diff --git a/spec/lib/pact/helpers_spec.rb b/spec/lib/pact/helpers_spec.rb index 3381eb9..001a257 100644 --- a/spec/lib/pact/helpers_spec.rb +++ b/spec/lib/pact/helpers_spec.rb @@ -146,7 +146,7 @@ module Pact it "creates a Pact::Term with regex matcher for integers" do expect(like_integer(integer)).to eq Pact::Term.new( generate: integer, - matcher: /[0-9]/ + matcher: /^-?\d+$/ ) end end @@ -156,7 +156,7 @@ module Pact it "creates a Pact::Term with regex matcher for decimals" do expect(like_decimal(10.2)).to eq Pact::Term.new( generate: float, - matcher: /[-+]?([0-9]*\.[0-9]+|[0-9]+)/ + matcher: /^0|-?\d+\.\d*$/ ) end end diff --git a/spec/lib/pact/term_spec.rb b/spec/lib/pact/term_spec.rb index f899a58..0b4dd0f 100644 --- a/spec/lib/pact/term_spec.rb +++ b/spec/lib/pact/term_spec.rb @@ -15,7 +15,7 @@ module Pact end context "when the generate is a integer" do - let(:term) { Term.new(generate: 10, matcher: /[0-9]/)} + let(:term) { Term.new(generate: 10, matcher: /^-?\d+$/)} it 'does not raise an exception' do term @@ -23,7 +23,7 @@ module Pact end context "when the generate is a float" do - let(:term) { Term.new(generate: 50.51, matcher: /[-+]?([0-9]*\.[0-9]+|[0-9]+)/)} + let(:term) { Term.new(generate: 50.51, matcher: /^0|-?\d+\.\d*$/)} it 'does not raise an exception' do term From 0656c98a59101231700fc55a992630c1b900bca4 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Thu, 15 Aug 2024 09:56:50 +0100 Subject: [PATCH 6/7] chore: change expected message to value, rather than string cannot determine from incoming term, whether expected is string/int or decimal --- lib/pact/matchers/matchers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pact/matchers/matchers.rb b/lib/pact/matchers/matchers.rb index 0455425..c6c5395 100644 --- a/lib/pact/matchers/matchers.rb +++ b/lib/pact/matchers/matchers.rb @@ -78,7 +78,7 @@ def actual_term_diff term, actual, options if term.matcher.match(actual) NO_DIFF else - RegexpDifference.new term.matcher, options[:original] ||= actual, "Expected a #{options[:was_float] ? "Float" : options[:was_int] ? "Integer" : "String" } matching #{term.matcher.inspect} (like #{term.generate.inspect}) but got #{options[:was_float] || options[:was_int] ? class_name_with_value_in_brackets(options[:original]) : actual.inspect} at " + RegexpDifference.new term.matcher, options[:original] ||= actual, "Expected a Value matching #{term.matcher.inspect} (like #{term.generate.inspect}) but got #{options[:was_float] || options[:was_int] ? class_name_with_value_in_brackets(options[:original]) : actual.inspect} at " end end From 6231d0e2650fd75524b7a1e0bb56e2a74d7f04c9 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Thu, 15 Aug 2024 10:15:32 +0100 Subject: [PATCH 7/7] chore(test): remove duplicated tests and update expected msg --- .../matchers/matchers_messages_regexp_spec.rb | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb b/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb index 596255a..8be9204 100644 --- a/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb +++ b/spec/lib/pact/matchers/matchers_messages_regexp_spec.rb @@ -27,21 +27,21 @@ module Pact::Matchers context "when the Pact::Term does not match" do it "returns a message" do - expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got \"drink\" at " + expect(difference[:thing].message).to eq "Expected a Value matching /foo/ (like \"food\") but got \"drink\" at " end end context "when the actual is a numeric" do let(:actual) { INT } it "returns a message" do - expect(difference[:thing].message).to eq "Expected a Integer matching /foo/ (like \"food\") but got #{a_numeric} (1) at " + expect(difference[:thing].message).to eq "Expected a Value matching /foo/ (like \"food\") but got #{a_numeric} (1) at " end end context "when the actual is a float" do let(:actual) { FLOAT } it "returns a message" do - expect(difference[:thing].message).to eq "Expected a Float matching /foo/ (like \"food\") but got #{a_float} (1.0) at " + expect(difference[:thing].message).to eq "Expected a Value matching /foo/ (like \"food\") but got #{a_float} (1.0) at " end end @@ -52,20 +52,6 @@ module Pact::Matchers end end - context "when the actual is a numeric" do - let(:actual) { INT } - it "returns a message" do - expect(difference[:thing].message).to eq "Expected a Integer matching /foo/ (like \"food\") but got #{a_numeric} (1) at " - end - end - - context "when the actual is a float" do - let(:actual) { FLOAT } - it "returns a message" do - expect(difference[:thing].message).to eq "Expected a Float matching /foo/ (like \"food\") but got #{a_float} (1.0) at " - end - end - context "when the actual is nil" do let(:actual) { nil } it "returns a message" do