Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lindomar reitz add support to match integers and floats #108

Merged
merged 8 commits into from
Nov 28, 2024
10 changes: 10 additions & 0 deletions lib/pact/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ 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: /^-?\d+$/)
end

def like_decimal float
Pact::Term.new(generate: float, matcher: /^0|-?\d+\.\d*$/)
end

def like_datetime_rfc822 datetime
Pact::Term.new(
generate: datetime,
Expand Down
8 changes: 7 additions & 1 deletion lib/pact/matchers/matchers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <path>"
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 <path>"
end
end

Expand Down
6 changes: 5 additions & 1 deletion lib/pact/term.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ def initialize(attributes = {})
@matcher = attributes[:matcher]
raise Pact::Error.new("Please specify a matcher for the Term") unless @matcher != nil
raise Pact::Error.new("Please specify a value to generate for the Term") unless @generate != nil
raise Pact::Error.new("Value to generate '#{@generate}' does not match regular expression #{@matcher.inspect}") unless @generate =~ @matcher
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
Expand Down
21 changes: 21 additions & 0 deletions spec/lib/pact/helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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: /^-?\d+$/
)
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|-?\d+\.\d*$/
)
end
end
end
end
16 changes: 8 additions & 8 deletions spec/lib/pact/matchers/matchers_messages_regexp_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,28 @@ 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 <path>"
expect(difference[:thing].message).to eq "Expected a Value matching /foo/ (like \"food\") but got \"drink\" at <path>"
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 String matching /foo/ (like \"food\") but got #{a_numeric} (1) at <path>"
expect(difference[:thing].message).to eq "Expected a Value matching /foo/ (like \"food\") but got #{a_numeric} (1) at <path>"
end
end

context "when the actual is Hash" do
let(:actual) { HASH }
context "when the actual is a float" do
let(:actual) { FLOAT }
it "returns a message" do
expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got a Hash at <path>"
expect(difference[:thing].message).to eq "Expected a Value matching /foo/ (like \"food\") but got #{a_float} (1.0) at <path>"
end
end

context "when the actual is a numeric" do
let(:actual) { INT }
context "when the actual is Hash" do
let(:actual) { HASH }
it "returns a message" do
expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got #{a_numeric} (1) at <path>"
expect(difference[:thing].message).to eq "Expected a String matching /foo/ (like \"food\") but got a Hash at <path>"
end
end

Expand Down
16 changes: 16 additions & 0 deletions spec/lib/pact/term_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ module Pact
end
end

context "when the generate is a integer" do
let(:term) { Term.new(generate: 10, matcher: /^-?\d+$/)}

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: /^0|-?\d+\.\d*$/)}

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
Expand Down
4 changes: 4 additions & 0 deletions spec/support/ruby_version_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ def a_numeric
end
end
module_function :a_numeric
def a_float
"a #{Float}"
end
module_function :a_float
end