Skip to content

Commit

Permalink
refactor: Apply Factory Method pattern to formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
tienvx committed May 10, 2024
1 parent d9b24d7 commit b806bc9
Show file tree
Hide file tree
Showing 133 changed files with 2,708 additions and 594 deletions.
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());
$matcher = new Matcher(plugin: true);

$request = new ConsumerRequest();
$request
Expand Down
3 changes: 2 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
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()));
}
}
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\Includes;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

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

return sprintf('matching(include, %s)', $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\Integer;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

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

return sprintf('matching(integer, %d)', $value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace PhpPact\Consumer\Matcher\Formatters\Expression;

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

class MatchAllFormatter extends AbstractExpressionFormatter
{
public function format(MatcherInterface $matcher): string
{
if (!$matcher instanceof MatchAll) {
throw $this->getMatcherNotSupportedException($matcher);
}
$matchers = $matcher->getMatchers();
if (empty($matchers)) {
throw new MatchingExpressionException("Matcher 'matchAll' need at least 1 matchers");
}

return implode(', ', array_map(
fn (MatcherInterface $matcher): string => $matcher->createExpressionFormatter()->format($matcher),
$matchers
));
}
}
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\MatchingField;
use PhpPact\Consumer\Matcher\Model\MatcherInterface;

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

return sprintf("matching($%s)", $this->normalize($matcher->getFieldName()));
}
}
Loading

0 comments on commit b806bc9

Please sign in to comment.