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

Formatter factory method #599

Merged
merged 3 commits into from
May 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions example/csv/consumer/tests/Service/HttpClientServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use CsvConsumer\Service\HttpClientService;
use PhpPact\Consumer\Driver\Enum\InteractionPart;
use PhpPact\Consumer\InteractionBuilder;
use PhpPact\Consumer\Matcher\Formatters\PluginFormatter;
use PhpPact\Consumer\Matcher\Matcher;
use PhpPact\Consumer\Model\Body\Text;
use PhpPact\Consumer\Model\ConsumerRequest;
Expand All @@ -18,7 +17,7 @@ class HttpClientServiceTest extends TestCase
{
public function testGetCsvFile(): void
{
$matcher = new Matcher(new PluginFormatter());
tienvx marked this conversation as resolved.
Show resolved Hide resolved
$matcher = new Matcher(plugin: true);

$request = new ConsumerRequest();
$request
Expand Down
4 changes: 4 additions & 0 deletions example/matchers/consumer/tests/Service/MatchersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ public function testGetMatchers(): void
$this->matcher->atMost(3),
],
),
'atLeast' => $this->matcher->atLeast(2), // Not useful when outside of `matchAll`
'atMost' => $this->matcher->atMost(4), // Not useful when outside of `matchAll`

// Don't mind this. This is for demonstrating what query values provider will received.
'query' => [
Expand Down Expand Up @@ -218,6 +220,8 @@ public function testGetMatchers(): void
],
'url' => 'http://localhost:8080/users/1234/posts/latest',
'matchAll' => ['desktop' => '2000 usd'],
'atLeast' => [null, null],
'atMost' => [null],

// Don't mind this. This is for demonstrating what query values provider will received.
'query' => [
Expand Down
25 changes: 25 additions & 0 deletions example/matchers/pacts/matchersConsumer-matchersProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,20 @@
111,
"2fbd41cc-4bbc-44ea-a419-67f767691407"
],
"atLeast": [
null,
null
],
"atLeastLike": [
1,
1,
1,
1,
1
],
"atMost": [
null
],
"atMostLike": [
1
],
Expand Down Expand Up @@ -278,6 +285,15 @@
}
]
},
"$.atLeast": {
"combine": "AND",
"matchers": [
{
"match": "type",
"min": 2
}
]
},
"$.atLeastLike": {
"combine": "AND",
"matchers": [
Expand All @@ -287,6 +303,15 @@
}
]
},
"$.atMost": {
"combine": "AND",
"matchers": [
{
"match": "type",
"max": 4
}
]
},
"$.atMostLike": {
"combine": "AND",
"matchers": [
Expand Down
12 changes: 11 additions & 1 deletion example/matchers/provider/public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
'likeBool' => false,
'likeInt' => 34,
'likeDecimal' => 24.12,
// 'likeDecimal' => 24, // Becareful, int is accepted
'boolean' => true,
'integer' => 11,
'decimal' => 25.1,
'decimal' => 25.1, // int is not accepted
'hexadecimal' => '20AC',
'uuid' => 'e9d2f3a5-6ecc-4bff-8935-84bb6141325a',
'ipv4Address' => '192.168.1.1',
Expand Down Expand Up @@ -78,6 +79,15 @@
'tablet' => '300 usd',
'laptop' => '1200 usd',
],
'atLeast' => [
null,
null,
],
'atMost' => [
null,
],

// Don't mind this. This is for demonstrating what query values provider will received.
'query' => $request->getQueryParams(),
]));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace ProtobufAsyncMessageConsumer\Tests\MessageHandler;

use Library\Person;
use PhpPact\Consumer\Matcher\Matcher;
use PhpPact\Consumer\MessageBuilder;
use PhpPact\Consumer\Model\Body\Text;
use PhpPact\Plugins\Protobuf\Factory\ProtobufMessageDriverFactory;
Expand All @@ -16,9 +17,11 @@ class PersonMessageHandlerTest extends TestCase
private SayHelloService $service;
private string $given = 'Given';
private string $surname = 'Surname';
private Matcher $matcher;

protected function setUp(): void
{
$this->matcher = new Matcher(plugin: true);
$service = $this->createMock(SayHelloService::class);
$service
->expects($this->once())
Expand Down Expand Up @@ -50,10 +53,10 @@ public function testInvoke(): void
'pact:proto' => __DIR__ . '/../../../library/proto/say_hello.proto',
'pact:message-type' => 'Person',
'pact:content-type' => 'application/protobuf',
'id' => "matching(regex, '^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$', '{$id}')",
'id' => $this->matcher->regex($id, '^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$'),
'name' => [
'given' => "matching(type, '{$this->given}')",
'surname' => "matching(type, '{$this->surname}')"
'given' => $this->matcher->like($this->given),
'surname' => $this->matcher->like($this->surname),
],
]),
'application/protobuf'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace ProtobufSyncMessageConsumer\Tests;

use PhpPact\Consumer\Matcher\Formatters\PluginFormatter;
use PhpPact\Consumer\Matcher\Matcher;
use PhpPact\Consumer\Model\Body\Text;
use PhpPact\Plugins\Protobuf\Factory\ProtobufSyncMessageDriverFactory;
Expand All @@ -17,7 +16,7 @@ class ProtobufClientTest extends TestCase
{
public function testCalculateArea(): void
{
$matcher = new Matcher(new PluginFormatter());
$matcher = new Matcher(plugin: true);
$protoPath = __DIR__ . '/../../library/proto/area_calculator.proto';

$config = new MockServerConfig();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Exception\InvalidValueException;
use PhpPact\Consumer\Matcher\Exception\MatcherNotSupportedException;
use PhpPact\Consumer\Matcher\Model\ExpressionFormatterInterface;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

abstract class AbstractExpressionFormatter implements ExpressionFormatterInterface
{
protected function normalize(mixed $value): string
{
if (is_string($value) && str_contains($value, "'")) {
throw new InvalidValueException(sprintf('String value "%s" should not contains single quote', $value));
}
return match (gettype($value)) {
'string' => sprintf("'%s'", $value),
'boolean' => $value ? 'true' : 'false',
'integer' => (string) $value,
'double' => (string) $value,
'NULL' => 'null',
default => throw new InvalidValueException(sprintf("Expression doesn't support value of type %s", gettype($value))),
};
}

protected function getMatcherNotSupportedException(MatcherInterface $matcher): MatcherNotSupportedException
{
return new MatcherNotSupportedException(sprintf('Matcher %s is not supported by %s', $matcher->getType(), static::class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Exception\InvalidValueException;
use PhpPact\Consumer\Matcher\Matchers\Boolean;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

class BooleanFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof Boolean) {
throw $this->getMatcherNotSupportedException($matcher);
}
$value = $matcher->getValue();
if (!is_bool($value)) {
throw new InvalidValueException(sprintf("Boolean formatter doesn't support value of type %s", gettype($value)));
}

return sprintf('matching(boolean, %s)', $this->normalize($value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Matchers\ContentType;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

class ContentTypeFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof ContentType) {
throw $this->getMatcherNotSupportedException($matcher);
}

return sprintf("matching(contentType, %s, %s)", $this->normalize($matcher->getContentType()), $this->normalize($matcher->getValue()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Exception\InvalidValueException;
use PhpPact\Consumer\Matcher\Matchers\AbstractDateTime;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

class DateTimeFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof AbstractDateTime) {
throw $this->getMatcherNotSupportedException($matcher);
}
$value = $matcher->getValue();
if (!is_string($value)) {
throw new InvalidValueException(sprintf("DateTime formatter doesn't support value of type %s", gettype($value)));
}

return sprintf("matching(%s, %s, %s)", $matcher->getType(), $this->normalize($matcher->getFormat()), $this->normalize($value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Exception\InvalidValueException;
use PhpPact\Consumer\Matcher\Matchers\Decimal;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

class DecimalFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof Decimal) {
throw $this->getMatcherNotSupportedException($matcher);
}
$value = $matcher->getValue();
if (!is_float($value)) {
throw new InvalidValueException(sprintf("Decimal formatter doesn't support value of type %s", gettype($value)));
}

return sprintf('matching(decimal, %s)', $this->normalize($value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Exception\MatchingExpressionException;
use PhpPact\Consumer\Matcher\Matchers\EachKey;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

class EachKeyFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof EachKey) {
throw $this->getMatcherNotSupportedException($matcher);
}
$rules = $matcher->getRules();
if (count($rules) !== 1) {
throw new MatchingExpressionException(sprintf("Matcher 'eachKey' only support 1 rule in expression, %d provided", count($rules)));
}
$rule = reset($rules);

return sprintf('eachKey(%s)', $rule->createExpressionFormatter()->format($rule));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Exception\MatchingExpressionException;
use PhpPact\Consumer\Matcher\Matchers\EachValue;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

class EachValueFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof EachValue) {
throw $this->getMatcherNotSupportedException($matcher);
}
$rules = $matcher->getRules();
if (count($rules) !== 1) {
throw new MatchingExpressionException(sprintf("Matcher 'eachValue' only support 1 rule in expression, %d provided", count($rules)));
}
$rule = reset($rules);

return sprintf('eachValue(%s)', $rule->createExpressionFormatter()->format($rule));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

use PhpPact\Consumer\Matcher\Matchers\Equality;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

class EqualityFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof Equality) {
throw $this->getMatcherNotSupportedException($matcher);
}

return sprintf('matching(equalTo, %s)', $this->normalize($matcher->getValue()));
}
}
Loading