diff --git a/compatibility-suite/tests/Service/BodyValidator.php b/compatibility-suite/tests/Service/BodyValidator.php index 53026891..980202d3 100644 --- a/compatibility-suite/tests/Service/BodyValidator.php +++ b/compatibility-suite/tests/Service/BodyValidator.php @@ -8,8 +8,6 @@ final class BodyValidator implements BodyValidatorInterface { - public const INT_REGEX = '/\d+/'; - public const DEC_REGEX = '/\d+\.\d+/'; public const HEX_REGEX = '/[a-fA-F0-9]+/'; public const STR_REGEX = '/\d{1,8}/'; public const DATE_REGEX = '/\d{4}-\d{2}-\d{2}/'; @@ -23,19 +21,19 @@ public function __construct(private BodyStorageInterface $bodyStorage) public function validateType(string $path, string $type): void { $value = $this->getActualValue($path); - Assert::assertTrue((bool) match ($type) { - 'integer' => is_numeric($value) && preg_match(self::INT_REGEX, $value), - 'decimal number' => is_string($value) && preg_match(self::DEC_REGEX, $value), - 'hexadecimal number' => is_string($value) && preg_match(self::HEX_REGEX, $value), - 'random string' => is_string($value), - 'string from the regex' => is_string($value) && preg_match(self::STR_REGEX, $value), - 'date' => is_string($value) && preg_match(self::DATE_REGEX, $value), - 'time' => is_string($value) && preg_match(self::TIME_REGEX, $value), - 'date-time' => is_string($value) && preg_match(self::DATETIME_REGEX, $value), - 'UUID', 'simple UUID', 'lower-case-hyphenated UUID', 'upper-case-hyphenated UUID', 'URN UUID' => Uuid::isValid($value), - 'boolean' => is_bool($value), - default => false, - }); + match ($type) { + 'integer' => Assert::assertIsInt($value), + 'decimal number' => Assert::assertIsFloat($value), + 'hexadecimal number' => Assert::assertIsString($value) && Assert::assertMatchesRegularExpression(self::HEX_REGEX, $value), + 'random string' => Assert::assertIsString($value), + 'string from the regex' => Assert::assertIsString($value) && Assert::assertMatchesRegularExpression(self::STR_REGEX, $value), + 'date' => Assert::assertIsString($value) && Assert::assertMatchesRegularExpression(self::DATE_REGEX, $value), + 'time' => Assert::assertIsString($value) && Assert::assertMatchesRegularExpression(self::TIME_REGEX, $value), + 'date-time' => Assert::assertIsString($value) && Assert::assertMatchesRegularExpression(self::DATETIME_REGEX, $value), + 'UUID', 'simple UUID', 'lower-case-hyphenated UUID', 'upper-case-hyphenated UUID', 'URN UUID' => Assert::assertTrue(Uuid::isValid($value)), + 'boolean' => Assert::assertIsBool($value), + default => null, + }; } public function validateValue(string $path, string $value): void diff --git a/compatibility-suite/tests/Service/MatchingRuleConverter.php b/compatibility-suite/tests/Service/MatchingRuleConverter.php index daea0ae5..fa896c9f 100644 --- a/compatibility-suite/tests/Service/MatchingRuleConverter.php +++ b/compatibility-suite/tests/Service/MatchingRuleConverter.php @@ -2,6 +2,7 @@ namespace PhpPactTest\CompatibilitySuite\Service; +use PhpPact\Consumer\Matcher\Enum\HttpStatus; use PhpPact\Consumer\Matcher\Matchers\ArrayContains; use PhpPact\Consumer\Matcher\Matchers\Boolean; use PhpPact\Consumer\Matcher\Matchers\ContentType; @@ -55,10 +56,10 @@ public function convert(MatchingRule $rule, mixed $value): ?MatcherInterface return new Number($this->getNumber($value)); case 'integer': - return new Integer($this->getNumber($value)); + return new Integer($this->getInteger($value)); case 'decimal': - return new Decimal($this->getNumber($value)); + return new Decimal($this->getDecimal($value)); case 'null': return new NullValue(); @@ -92,43 +93,48 @@ public function convert(MatchingRule $rule, mixed $value): ?MatcherInterface case 'regex': $regex = $rule->getMatcherAttribute('regex'); - return new Regex($regex, $this->ignoreInvalidValue($regex, $value)); + return new Regex($regex, $value ?? ''); case 'statusCode': - return new StatusCode($rule->getMatcherAttribute('status')); + return new StatusCode($this->getHttpStatus($rule)); default: return null; } } - private function getNumber(mixed $value): int|float|null + private function getNumber(mixed $value): int|float { if (is_numeric($value)) { - $value = $value + 0; - } else { - $value = null; + return $value + 0; } - return $value; + // @todo Fix this compatibility-suite's mistake: there is no number in `basic.json` + return 1; } - private function ignoreInvalidValue(string $regex, mixed $value): string|array|null + private function getInteger(mixed $value): int { - if (is_string($value)) { - if (!preg_match("/$regex/", $value)) { - $value = null; - } - } elseif (is_array($value)) { - foreach (array_keys($value) as $key) { - if (!preg_match("/$regex/", $value[$key])) { - $value[$key] = null; - } - } - } else { - $value = null; + if (is_numeric($value)) { + return $value + 0; } - return $value; + // @todo Fix this compatibility-suite's mistake: there is no integer in `basic.json` + return 1; + } + + private function getDecimal(mixed $value): float + { + if (is_numeric($value)) { + return $value + 0; + } + + // @todo Fix this compatibility-suite's mistake: there is no decimal in `basic.json` + return 1.1; + } + + private function getHttpStatus(MatchingRule $rule): HttpStatus + { + return HttpStatus::from($rule->getMatcherAttribute('status') ?? ''); } } diff --git a/example/generators/consumer/tests/Service/GeneratorsTest.php b/example/generators/consumer/tests/Service/GeneratorsTest.php index e69ffd40..f97a5bdc 100644 --- a/example/generators/consumer/tests/Service/GeneratorsTest.php +++ b/example/generators/consumer/tests/Service/GeneratorsTest.php @@ -103,7 +103,7 @@ public function testGetGenerators(): void $this->assertTrue($this->validateDateTime($body['time'], 'H:i:s')); $this->assertTrue($this->validateDateTime($body['datetime'], "Y-m-d\TH:i:s")); $this->assertIsString($body['string']); - $this->assertNotSame(StringValue::DEFAULT_VALUE, $body['string']); + $this->assertNotSame('', $body['string']); $this->assertIsNumeric($body['number']); $this->assertNotSame('http://localhost/users/1234/posts/latest', $body['url']); $this->assertMatchesRegularExpression('/.*(\\/users\\/\\d+\\/posts\\/latest)$/', $body['url']); diff --git a/example/generators/pacts/generatorsConsumer-generatorsProvider.json b/example/generators/pacts/generatorsConsumer-generatorsProvider.json index 95aba645..ad659daf 100644 --- a/example/generators/pacts/generatorsConsumer-generatorsProvider.json +++ b/example/generators/pacts/generatorsConsumer-generatorsProvider.json @@ -14,7 +14,7 @@ "request": { "body": { "content": { - "id": null + "id": 13 }, "contentType": "application/json", "encoded": false @@ -54,25 +54,25 @@ "body": { "content": { "boolean": true, - "boolean_v3": null, - "date": null, - "datetime": null, + "boolean_v3": false, + "date": "", + "datetime": "", "decimal": 13.01, - "decimal_v3": null, + "decimal_v3": 13.01, "equality": "Hello World!", - "hexadecimal": null, + "hexadecimal": "", "integer": 13, - "integer_v3": null, + "integer_v3": 13, "like": "6057401b-c539-4948-971a-24b702d79882", "notEmpty": "text", - "number": null, - "regex": null, + "number": 13, + "regex": "", "requestId": 222, - "semver": null, - "string": "some string", - "time": null, - "url": null, - "uuid": null + "semver": "", + "string": "", + "time": "", + "url": "", + "uuid": "" }, "contentType": "application/json", "encoded": false diff --git a/example/message/pacts/messageConsumer-messageProvider.json b/example/message/pacts/messageConsumer-messageProvider.json index a24b8f80..d933e615 100644 --- a/example/message/pacts/messageConsumer-messageProvider.json +++ b/example/message/pacts/messageConsumer-messageProvider.json @@ -5,7 +5,7 @@ "messages": [ { "contents": { - "number": null, + "number": 13, "text": "Hello Mary" }, "description": "an alligator named Mary exists", @@ -49,7 +49,7 @@ "metadata": { "contentType": "application/json", "queue": "wind cries", - "routing_key": "some string" + "routing_key": "" }, "providerStates": [ { diff --git a/src/PhpPact/Consumer/Matcher/Exception/InvalidRegexException.php b/src/PhpPact/Consumer/Matcher/Exception/InvalidRegexException.php deleted file mode 100644 index 97b72f6d..00000000 --- a/src/PhpPact/Consumer/Matcher/Exception/InvalidRegexException.php +++ /dev/null @@ -1,7 +0,0 @@ -withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $values ? new RegexGenerator($pattern) : null) + ->withFormatter($this->createFormatter()); } /** @@ -231,28 +239,34 @@ public function integer(?int $value = null): Type public function decimal(?float $value = null): Type { return $this->like($value ?? 13.01) - ->withGenerator(is_null($value) ? new RandomDecimal() : null); + ->withGenerator(null === $value ? new RandomDecimal() : null); } public function booleanV3(?bool $value = null): Boolean { - $matcher = new Boolean($value); + $matcher = new Boolean($value ?? false); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new RandomBoolean() : null) + ->withFormatter($this->createFormatter()); } public function integerV3(?int $value = null): Integer { - $matcher = new Integer($value); + $matcher = new Integer($value ?? 13); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new RandomInt() : null) + ->withFormatter($this->createFormatter()); } public function decimalV3(?float $value = null): Decimal { - $matcher = new Decimal($value); + $matcher = new Decimal($value ?? 13.01); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new RandomDecimal() : null) + ->withFormatter($this->createFormatter()); } /** @@ -260,10 +274,10 @@ public function decimalV3(?float $value = null): Decimal */ public function hexadecimal(?string $value = null): Regex { - $matcher = new Regex(self::HEX_FORMAT, $value); + $matcher = new Regex(self::HEX_FORMAT, $value ?? ''); return $matcher - ->withGenerator(is_null($value) ? new RandomHexadecimal() : null) + ->withGenerator(null === $value ? new RandomHexadecimal() : null) ->withFormatter($this->createFormatter()); } @@ -272,10 +286,10 @@ public function hexadecimal(?string $value = null): Regex */ public function uuid(?string $value = null): Regex { - $matcher = new Regex(self::UUID_V4_FORMAT, $value); + $matcher = new Regex(self::UUID_V4_FORMAT, $value ?? ''); return $matcher - ->withGenerator(is_null($value) ? new Uuid() : null) + ->withGenerator(null === $value ? new Uuid() : null) ->withFormatter($this->createFormatter()); } @@ -314,9 +328,11 @@ public function nullValue(): NullValue */ public function date(string $format = 'yyyy-MM-dd', ?string $value = null): Date { - $matcher = new Date($format, $value); + $matcher = new Date($format, $value ?? ''); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new DateGenerator($format) : null) + ->withFormatter($this->createFormatter()); } /** @@ -328,9 +344,11 @@ public function date(string $format = 'yyyy-MM-dd', ?string $value = null): Date */ public function time(string $format = 'HH:mm:ss', ?string $value = null): Time { - $matcher = new Time($format, $value); + $matcher = new Time($format, $value ?? ''); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new TimeGenerator() : null) + ->withFormatter($this->createFormatter()); } /** @@ -342,16 +360,20 @@ public function time(string $format = 'HH:mm:ss', ?string $value = null): Time */ public function datetime(string $format = "yyyy-MM-dd'T'HH:mm:ss", ?string $value = null): DateTime { - $matcher = new DateTime($format, $value); + $matcher = new DateTime($format, $value ?? ''); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new DateTimeGenerator() : null) + ->withFormatter($this->createFormatter()); } public function string(?string $value = null): StringValue { - $matcher = new StringValue($value); + $matcher = new StringValue($value ?? ''); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new RandomString() : null) + ->withFormatter($this->createFormatter()); } /** @@ -389,9 +411,11 @@ public function includes(string $value): Includes */ public function number(int|float|null $value = null): Number { - $matcher = new Number($value); + $matcher = new Number($value ?? 13); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new RandomInt() : null) + ->withFormatter($this->createFormatter()); } /** @@ -422,9 +446,11 @@ public function notEmpty(mixed $value): NotEmpty */ public function semver(?string $value = null): Semver { - $matcher = new Semver($value); + $matcher = new Semver($value ?? ''); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator(null === $value ? new RegexGenerator('\d+\.\d+\.\d+') : null) + ->withFormatter($this->createFormatter()); } /** @@ -432,9 +458,32 @@ public function semver(?string $value = null): Semver */ public function statusCode(string|HttpStatus $status, ?int $value = null): StatusCode { + if (is_string($status)) { + try { + $status = HttpStatus::from($status); + } catch (\Throwable $th) { + $all = implode(', ', array_map( + fn (HttpStatus $status) => $status->value, + HttpStatus::cases() + )); + throw new InvalidHttpStatusException(sprintf("Status '%s' is not supported. Supported status are: %s", $status, $all)); + } + } + + if (null === $value) { + $value = 0; + $range = $status->range(); + + $generator = new RandomInt($range->min, $range->max); + } else { + $generator = null; + } + $matcher = new StatusCode($status, $value); - return $matcher->withFormatter($this->createFormatter()); + return $matcher + ->withGenerator($generator) + ->withFormatter($this->createFormatter()); } /** @@ -492,7 +541,7 @@ public function eachValue(array|object $values, array $rules): EachValue */ public function url(string $url, string $regex, bool $useMockServerBasePath = true): Regex { - $matcher = new Regex($regex, $useMockServerBasePath ? null : $url); + $matcher = new Regex($regex, $useMockServerBasePath ? '' : $url); return $matcher ->withGenerator($useMockServerBasePath ? new MockServerURL($regex, $url) : null) diff --git a/src/PhpPact/Consumer/Matcher/Matchers/AbstractDateTime.php b/src/PhpPact/Consumer/Matcher/Matchers/AbstractDateTime.php index 4baf8308..ef73b3a4 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/AbstractDateTime.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/AbstractDateTime.php @@ -15,7 +15,7 @@ abstract class AbstractDateTime extends GeneratorAwareMatcher implements JsonFor use JsonFormattableTrait; use ExpressionFormattableTrait; - public function __construct(protected string $format, private ?string $value = null) + public function __construct(protected string $format, private string $value = '') { parent::__construct(); } @@ -31,10 +31,6 @@ public function formatJson(): Attributes public function formatExpression(): Expression { - if (!is_string($this->value)) { - throw new InvalidValueException(sprintf("DateTime matching expression doesn't support value of type %s", gettype($this->value))); - } - $type = $this->getType(); return $this->mergeExpression(new Expression( diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Boolean.php b/src/PhpPact/Consumer/Matcher/Matchers/Boolean.php index bccd03d7..28242b0e 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Boolean.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Boolean.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; -use PhpPact\Consumer\Matcher\Generators\RandomBoolean; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Expression; use PhpPact\Consumer\Matcher\Model\Matcher\ExpressionFormattableInterface; @@ -17,11 +15,8 @@ class Boolean extends GeneratorAwareMatcher implements JsonFormattableInterface, { use JsonFormattableTrait; - public function __construct(private ?bool $value = null) + public function __construct(private bool $value = false) { - if ($value === null) { - $this->setGenerator(new RandomBoolean()); - } parent::__construct(); } @@ -35,10 +30,6 @@ public function formatJson(): Attributes public function formatExpression(): Expression { - if (!is_bool($this->value)) { - throw new InvalidValueException(sprintf("Boolean matching expression doesn't support value of type %s", gettype($this->value))); - } - return new Expression('matching(boolean, %value%)', ['value' => $this->value]); } } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Date.php b/src/PhpPact/Consumer/Matcher/Matchers/Date.php index 67ca1e82..1c73195a 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Date.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Date.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Generators\Date as DateGenerator; - /** * Matches the string representation of a value against the date format. * @@ -13,11 +11,8 @@ */ class Date extends AbstractDateTime { - public function __construct(string $format = 'yyyy-MM-dd', ?string $value = null) + public function __construct(string $format = 'yyyy-MM-dd', string $value = '') { - if ($value === null) { - $this->setGenerator(new DateGenerator($format)); - } parent::__construct($format, $value); } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/DateTime.php b/src/PhpPact/Consumer/Matcher/Matchers/DateTime.php index 5d2f8184..980f3e2c 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/DateTime.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/DateTime.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Generators\DateTime as DateTimeGenerator; - /** * Matches the string representation of a value against the datetime format. * @@ -13,11 +11,8 @@ */ class DateTime extends AbstractDateTime { - public function __construct(string $format = "yyyy-MM-dd'T'HH:mm:ss", ?string $value = null) + public function __construct(string $format = "yyyy-MM-dd'T'HH:mm:ss", string $value = '') { - if ($value === null) { - $this->setGenerator(new DateTimeGenerator($format)); - } parent::__construct($format, $value); } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Decimal.php b/src/PhpPact/Consumer/Matcher/Matchers/Decimal.php index ca0421b2..b6b2649f 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Decimal.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Decimal.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; -use PhpPact\Consumer\Matcher\Generators\RandomDecimal; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Expression; use PhpPact\Consumer\Matcher\Model\Matcher\ExpressionFormattableInterface; @@ -19,11 +17,8 @@ class Decimal extends GeneratorAwareMatcher implements JsonFormattableInterface, use JsonFormattableTrait; use ExpressionFormattableTrait; - public function __construct(private ?float $value = null) + public function __construct(private float $value = 13.01) { - if ($value === null) { - $this->setGenerator(new RandomDecimal()); - } parent::__construct(); } @@ -37,9 +32,6 @@ public function formatJson(): Attributes public function formatExpression(): Expression { - if (!is_float($this->value)) { - throw new InvalidValueException(sprintf("Decimal matching expression doesn't support value of type %s", gettype($this->value))); - } return $this->mergeExpression(new Expression('matching(decimal, %value%)', ['value' => $this->value])); } } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Integer.php b/src/PhpPact/Consumer/Matcher/Matchers/Integer.php index dd912915..db69a3cb 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Integer.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Integer.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; -use PhpPact\Consumer\Matcher\Generators\RandomInt; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Expression; use PhpPact\Consumer\Matcher\Model\Matcher\ExpressionFormattableInterface; @@ -19,11 +17,8 @@ class Integer extends GeneratorAwareMatcher implements JsonFormattableInterface, use JsonFormattableTrait; use ExpressionFormattableTrait; - public function __construct(private ?int $value = null) + public function __construct(private int $value = 13) { - if ($value === null) { - $this->setGenerator(new RandomInt()); - } parent::__construct(); } @@ -37,9 +32,6 @@ public function formatJson(): Attributes public function formatExpression(): Expression { - if (!is_int($this->value)) { - throw new InvalidValueException(sprintf("Integer matching expression doesn't support value of type %s", gettype($this->value))); - } return $this->mergeExpression(new Expression('matching(integer, %value%)', ['value' => $this->value])); } } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Number.php b/src/PhpPact/Consumer/Matcher/Matchers/Number.php index 8a69a91d..00778565 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Number.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Number.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; -use PhpPact\Consumer\Matcher\Generators\RandomInt; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Expression; use PhpPact\Consumer\Matcher\Model\Matcher\ExpressionFormattableInterface; @@ -19,11 +17,8 @@ class Number extends GeneratorAwareMatcher implements JsonFormattableInterface, use JsonFormattableTrait; use ExpressionFormattableTrait; - public function __construct(private int|float|null $value = null) + public function __construct(private int|float $value = 13) { - if ($value === null) { - $this->setGenerator(new RandomInt()); - } parent::__construct(); } @@ -37,9 +32,6 @@ public function formatJson(): Attributes public function formatExpression(): Expression { - if (null === $this->value) { - throw new InvalidValueException(sprintf("Number matching expression doesn't support value of type %s", gettype($this->value))); - } return $this->mergeExpression(new Expression('matching(number, %value%)', ['value' => $this->value])); } } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Regex.php b/src/PhpPact/Consumer/Matcher/Matchers/Regex.php index 91d49e46..e83d8880 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Regex.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Regex.php @@ -3,52 +3,26 @@ namespace PhpPact\Consumer\Matcher\Matchers; use PhpPact\Consumer\Matcher\Exception\InvalidValueException; -use PhpPact\Consumer\Matcher\Exception\InvalidRegexException; -use PhpPact\Consumer\Matcher\Generators\Regex as RegexGenerator; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Expression; use PhpPact\Consumer\Matcher\Model\Matcher\ExpressionFormattableInterface; use PhpPact\Consumer\Matcher\Model\Matcher\JsonFormattableInterface; use PhpPact\Consumer\Matcher\Trait\JsonFormattableTrait; -use function preg_last_error; -use function preg_match; - class Regex extends GeneratorAwareMatcher implements JsonFormattableInterface, ExpressionFormattableInterface { use JsonFormattableTrait; /** - * @param string|string[]|null $values + * @param string|string[] $values */ public function __construct( private string $regex, - private string|array|null $values = null, + private string|array $values = '', ) { - if ($values === null) { - $this->setGenerator(new RegexGenerator($this->regex)); - } else { - $this->validateRegex(); - } parent::__construct(); } - /** - * @todo Use json_validate() - */ - private function validateRegex(): void - { - foreach ((array) $this->values as $value) { - $result = preg_match("/$this->regex/", $value); - - if ($result !== 1) { - $errorCode = preg_last_error(); - - throw new InvalidRegexException("The value '{$value}' doesn't match pattern '{$this->regex}'. Failed with error code {$errorCode}."); - } - } - } - public function formatJson(): Attributes { return $this->mergeJson(new Attributes([ diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Semver.php b/src/PhpPact/Consumer/Matcher/Matchers/Semver.php index c1e94aaa..a3b9f24f 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Semver.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Semver.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; -use PhpPact\Consumer\Matcher\Generators\Regex; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Expression; use PhpPact\Consumer\Matcher\Model\Matcher\ExpressionFormattableInterface; @@ -17,11 +15,8 @@ class Semver extends GeneratorAwareMatcher implements JsonFormattableInterface, { use JsonFormattableTrait; - public function __construct(private ?string $value = null) + public function __construct(private string $value = '') { - if ($value === null) { - $this->setGenerator(new Regex('\d+\.\d+\.\d+')); - } parent::__construct(); } @@ -35,9 +30,6 @@ public function formatJson(): Attributes public function formatExpression(): Expression { - if (!is_string($this->value)) { - throw new InvalidValueException(sprintf("Semver matching expression doesn't support value of type %s", gettype($this->value))); - } return new Expression('matching(semver, %value%)', ['value' => $this->value]); } } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/StatusCode.php b/src/PhpPact/Consumer/Matcher/Matchers/StatusCode.php index 70940880..60c3f6e3 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/StatusCode.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/StatusCode.php @@ -3,8 +3,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; use PhpPact\Consumer\Matcher\Enum\HttpStatus; -use PhpPact\Consumer\Matcher\Exception\InvalidHttpStatusException; -use PhpPact\Consumer\Matcher\Generators\RandomInt; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Matcher\JsonFormattableInterface; use PhpPact\Consumer\Matcher\Trait\JsonFormattableTrait; @@ -16,28 +14,8 @@ class StatusCode extends GeneratorAwareMatcher implements JsonFormattableInterfa { use JsonFormattableTrait; - private HttpStatus $status; - - public function __construct(string|HttpStatus $status, private ?int $value = null) + public function __construct(private HttpStatus $status, private int $value = 0) { - if (is_string($status)) { - try { - $status = HttpStatus::from($status); - } catch (\Throwable $th) { - $all = implode(', ', array_map( - fn (HttpStatus $status) => $status->value, - HttpStatus::cases() - )); - throw new InvalidHttpStatusException(sprintf("Status '%s' is not supported. Supported status are: %s", $status, $all)); - } - } - $this->status = $status; - - if ($value === null) { - $range = $status->range(); - - $this->setGenerator(new RandomInt($range->min, $range->max)); - } parent::__construct(); } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/StringValue.php b/src/PhpPact/Consumer/Matcher/Matchers/StringValue.php index 7bf689fc..c0aee507 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/StringValue.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/StringValue.php @@ -2,7 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Generators\RandomString; use PhpPact\Consumer\Matcher\Model\Attributes; use PhpPact\Consumer\Matcher\Model\Expression; use PhpPact\Consumer\Matcher\Model\Matcher\ExpressionFormattableInterface; @@ -16,13 +15,8 @@ class StringValue extends GeneratorAwareMatcher implements JsonFormattableInterf { use JsonFormattableTrait; - public const DEFAULT_VALUE = 'some string'; - - public function __construct(private ?string $value = null) + public function __construct(private string $value = '') { - if ($value === null) { - $this->setGenerator(new RandomString()); - } parent::__construct(); } @@ -30,17 +24,12 @@ public function formatJson(): Attributes { return $this->mergeJson(new Attributes([ 'pact:matcher:type' => 'type', - 'value' => $this->getValue(), + 'value' => $this->value, ])); } public function formatExpression(): Expression { - return new Expression('matching(type, %value%)', ['value' => $this->getValue()]); - } - - private function getValue(): string - { - return $this->value ?? self::DEFAULT_VALUE; + return new Expression('matching(type, %value%)', ['value' => $this->value]); } } diff --git a/src/PhpPact/Consumer/Matcher/Matchers/Time.php b/src/PhpPact/Consumer/Matcher/Matchers/Time.php index ac3f9fad..b6b01043 100644 --- a/src/PhpPact/Consumer/Matcher/Matchers/Time.php +++ b/src/PhpPact/Consumer/Matcher/Matchers/Time.php @@ -2,8 +2,6 @@ namespace PhpPact\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Generators\Time as TimeGenerator; - /** * Matches the string representation of a value against the time format. * @@ -13,11 +11,8 @@ */ class Time extends AbstractDateTime { - public function __construct(string $format = 'HH:mm:ss', ?string $value = null) + public function __construct(string $format = 'HH:mm:ss', string $value = '') { - if ($value === null) { - $this->setGenerator(new TimeGenerator($format)); - } parent::__construct($format, $value); } diff --git a/tests/PhpPact/Consumer/Matcher/Enum/HttpStatusTest.php b/tests/PhpPact/Consumer/Matcher/Enum/HttpStatusTest.php new file mode 100644 index 00000000..1c8a3bed --- /dev/null +++ b/tests/PhpPact/Consumer/Matcher/Enum/HttpStatusTest.php @@ -0,0 +1,18 @@ +range(); + $this->assertSame($min, $range->min); + $this->assertSame($max, $range->max); + } +} diff --git a/tests/PhpPact/Consumer/Matcher/MatcherTest.php b/tests/PhpPact/Consumer/Matcher/MatcherTest.php index 18a84d39..6f221200 100644 --- a/tests/PhpPact/Consumer/Matcher/MatcherTest.php +++ b/tests/PhpPact/Consumer/Matcher/MatcherTest.php @@ -3,7 +3,7 @@ namespace PhpPactTest\Consumer\Matcher; use PhpPact\Consumer\Matcher\Enum\HttpStatus; -use PhpPact\Consumer\Matcher\Exception\MatcherNotSupportedException; +use PhpPact\Consumer\Matcher\Exception\InvalidHttpStatusException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; use PhpPact\Consumer\Matcher\Formatters\Json\JsonFormatter; use PhpPact\Consumer\Matcher\Generators\MockServerURL; @@ -12,6 +12,11 @@ use PhpPact\Consumer\Matcher\Generators\RandomDecimal; use PhpPact\Consumer\Matcher\Generators\RandomHexadecimal; use PhpPact\Consumer\Matcher\Generators\RandomInt; +use PhpPact\Consumer\Matcher\Generators\RandomString; +use PhpPact\Consumer\Matcher\Generators\Regex as RegexGenerator; +use PhpPact\Consumer\Matcher\Generators\Date as DateGenerator; +use PhpPact\Consumer\Matcher\Generators\Time as TimeGenerator; +use PhpPact\Consumer\Matcher\Generators\DateTime as DateTimeGenerator; use PhpPact\Consumer\Matcher\Generators\Uuid; use PhpPact\Consumer\Matcher\Matcher; use PhpPact\Consumer\Matcher\Matchers\ArrayContains; @@ -96,15 +101,37 @@ public function testConstrainedArrayLike(): void $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testTerm(): void + /** + * @param string|string[]|null $values + */ + #[TestWith([null, true])] + #[TestWith(['123', false])] + #[TestWith([['123', '234'], false])] + public function testTerm(string|array|null $values, bool $hasGenerator): void { - $this->assertInstanceOf(Regex::class, $result = $this->matcher->term('123', '\d+')); + $this->assertInstanceOf(Regex::class, $result = $this->matcher->term($values, '\d+')); + if ($hasGenerator) { + $this->assertInstanceOf(RegexGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testRegex(): void + /** + * @param string|string[]|null $values + */ + #[TestWith([null, true])] + #[TestWith(['Games', false])] + #[TestWith([['Games', 'Other'], false])] + public function testRegex(string|array|null $values, bool $hasGenerator): void { - $this->assertInstanceOf(Regex::class, $result = $this->matcher->regex('Games', 'Games|Other')); + $this->assertInstanceOf(Regex::class, $result = $this->matcher->regex($values, 'Games|Other')); + if ($hasGenerator) { + $this->assertInstanceOf(RegexGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } @@ -204,21 +231,46 @@ public function testDecimal(?float $value, bool $hasGenerator): void } } - public function testIntegerV3(): void + #[TestWith([null, true])] + #[TestWith([13, false])] + public function testIntegerV3(?int $value, bool $hasGenerator): void { - $this->assertInstanceOf(Integer::class, $result = $this->matcher->integerV3(13)); + $this->assertInstanceOf(Integer::class, $result = $this->matcher->integerV3($value)); + $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); + if ($hasGenerator) { + $this->assertInstanceOf(RandomInt::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testBooleanV3(): void + #[TestWith([null, true])] + #[TestWith([true, false])] + #[TestWith([false, false])] + public function testBooleanV3(?bool $value, bool $hasGenerator): void { - $this->assertInstanceOf(Boolean::class, $result = $this->matcher->booleanV3(true)); + $this->assertInstanceOf(Boolean::class, $result = $this->matcher->booleanV3($value)); + $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); + if ($hasGenerator) { + $this->assertInstanceOf(RandomBoolean::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testDecimalV3(): void + #[TestWith([null, true])] + #[TestWith([13.01, false])] + public function testDecimalV3(?float $value, bool $hasGenerator): void { - $this->assertInstanceOf(Decimal::class, $result = $this->matcher->decimalV3(13.01)); + $this->assertInstanceOf(Decimal::class, $result = $this->matcher->decimalV3($value)); + $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); + if ($hasGenerator) { + $this->assertInstanceOf(RandomDecimal::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } @@ -250,21 +302,42 @@ public function testUuid(?string $value, bool $hasGenerator): void $this->assertInstanceOf(JsonFormatter::class, $uuid->getFormatter()); } - public function testIpv4Address(): void + #[TestWith([null, true])] + #[TestWith(['127.0.0.13', false])] + public function testIpv4Address(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(Regex::class, $result = $this->matcher->ipv4Address()); + $this->assertInstanceOf(Regex::class, $result = $this->matcher->ipv4Address($value)); + if ($hasGenerator) { + $this->assertInstanceOf(RegexGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testIpv6Address(): void + #[TestWith([null, true])] + #[TestWith(['::ffff:192.0.2.128', false])] + public function testIpv6Address(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(Regex::class, $result = $this->matcher->ipv6Address()); + $this->assertInstanceOf(Regex::class, $result = $this->matcher->ipv6Address($value)); + if ($hasGenerator) { + $this->assertInstanceOf(RegexGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testEmail(): void + #[TestWith([null, true])] + #[TestWith(['hello@pact.io', false])] + public function testEmail(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(Regex::class, $result = $this->matcher->email()); + $this->assertInstanceOf(Regex::class, $result = $this->matcher->email($value)); + if ($hasGenerator) { + $this->assertInstanceOf(RegexGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } @@ -274,27 +347,55 @@ public function testNullValue(): void $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testDate(): void + #[TestWith([null, true])] + #[TestWith(['2022-11-21', false])] + public function testDate(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(Date::class, $result = $this->matcher->date('yyyy-MM-dd', '2022-11-21')); + $this->assertInstanceOf(Date::class, $result = $this->matcher->date('yyyy-MM-dd', $value)); + if ($hasGenerator) { + $this->assertInstanceOf(DateGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testTime(): void + #[TestWith([null, true])] + #[TestWith(['21:45::31', false])] + public function testTime(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(Time::class, $result = $this->matcher->time('HH:mm:ss', '21:45::31')); + $this->assertInstanceOf(Time::class, $result = $this->matcher->time('HH:mm:ss', $value)); + if ($hasGenerator) { + $this->assertInstanceOf(TimeGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testDateTime(): void + #[TestWith([null, true])] + #[TestWith(['2015-08-06T16:53:10', false])] + public function testDateTime(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(DateTime::class, $result = $this->matcher->datetime("yyyy-MM-dd'T'HH:mm:ss", '2015-08-06T16:53:10')); + $this->assertInstanceOf(DateTime::class, $result = $this->matcher->datetime("yyyy-MM-dd'T'HH:mm:ss", $value)); + if ($hasGenerator) { + $this->assertInstanceOf(DateTimeGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testString(): void + #[TestWith([null, true])] + #[TestWith(['test string', false])] + public function testString(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(StringValue::class, $result = $this->matcher->string('test string')); + $this->assertInstanceOf(StringValue::class, $result = $this->matcher->string($value)); + if ($hasGenerator) { + $this->assertInstanceOf(RandomString::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } @@ -319,9 +420,17 @@ public function testIncludes(): void $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testNumber(): void + #[TestWith([null, true])] + #[TestWith([13, false])] + #[TestWith([13.01, false])] + public function testNumber(int|float|null $value, bool $hasGenerator): void { - $this->assertInstanceOf(Number::class, $result = $this->matcher->number(13.01)); + $this->assertInstanceOf(Number::class, $result = $this->matcher->number($value)); + if ($hasGenerator) { + $this->assertInstanceOf(RandomInt::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } @@ -340,18 +449,41 @@ public function testNotEmpty(): void $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testSemver(): void + #[TestWith([null, true])] + #[TestWith(['1.2.3', false])] + public function testSemver(?string $value, bool $hasGenerator): void { - $this->assertInstanceOf(Semver::class, $result = $this->matcher->semver('1.2.3')); + $this->assertInstanceOf(Semver::class, $result = $this->matcher->semver($value)); + if ($hasGenerator) { + $this->assertInstanceOf(RegexGenerator::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } - public function testValidStatusCode(): void + #[TestWith(['success', null, true])] + #[TestWith(['success', 123, false])] + #[TestWith([HttpStatus::SUCCESS, null, true])] + #[TestWith([HttpStatus::SUCCESS, 123, false])] + public function testValidStatusCode(string|HttpStatus $status, ?int $value, bool $hasGenerator): void { - $this->assertInstanceOf(StatusCode::class, $result = $this->matcher->statusCode(HttpStatus::SUCCESS)); + $this->assertInstanceOf(StatusCode::class, $result = $this->matcher->statusCode($status, $value)); + if ($hasGenerator) { + $this->assertInstanceOf(RandomInt::class, $result->getGenerator()); + } else { + $this->assertNull($result->getGenerator()); + } $this->assertInstanceOf(JsonFormatter::class, $result->getFormatter()); } + public function testInvalidStatusCode(): void + { + $this->expectException(InvalidHttpStatusException::class); + $this->expectExceptionMessage("Status 'invalid' is not supported. Supported status are: info, success, redirect, clientError, serverError, nonError, error"); + $this->matcher->statusCode('invalid'); + } + public function testValues(): void { $this->assertInstanceOf(Values::class, $result = $this->matcher->values([ diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/ArrayContainsTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/ArrayContainsTest.php index 4556cb0d..f74d5ec9 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/ArrayContainsTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/ArrayContainsTest.php @@ -36,11 +36,8 @@ public function testFormatJson(): void "value": "string" }, { - "pact:generator:type": "RandomInt", - "min": 0, - "max": 10, "pact:matcher:type": "integer", - "value": null + "value": 13 } ], "value": [ @@ -49,11 +46,8 @@ public function testFormatJson(): void "value": "string" }, { - "pact:generator:type": "RandomInt", - "min": 0, - "max": 10, "pact:matcher:type": "integer", - "value": null + "value": 13 } ] } diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/BooleanTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/BooleanTest.php index 114604bb..e9ad0e53 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/BooleanTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/BooleanTest.php @@ -2,33 +2,28 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; +use PhpPact\Consumer\Matcher\Generators\RandomBoolean; use PhpPact\Consumer\Matcher\Matchers\Boolean; +use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PhpPact\Consumer\Matcher\Model\MatcherInterface; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; class BooleanTest extends TestCase { - #[TestWith([new Boolean(null), '{"pact:generator:type":"RandomBoolean","pact:matcher:type":"boolean","value":null}'])] - #[TestWith([new Boolean(true), '{"pact:matcher:type":"boolean","value":true}'])] - #[TestWith([new Boolean(false), '{"pact:matcher:type":"boolean","value":false}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new Boolean(true), null, '{"pact:matcher:type":"boolean","value":true}'])] + #[TestWith([new Boolean(false), null, '{"pact:matcher:type":"boolean","value":false}'])] + #[TestWith([new Boolean(true), new RandomBoolean(), '{"pact:generator:type":"RandomBoolean","pact:matcher:type":"boolean","value":true}'])] + #[TestWith([new Boolean(false), new RandomBoolean(), '{"pact:generator:type":"RandomBoolean","pact:matcher:type":"boolean","value":false}'])] + public function testFormatJson(Boolean $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - public function testInvalidValue(): void - { - $matcher = (new Boolean())->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage(sprintf("Boolean matching expression doesn't support value of type %s", gettype(null))); - json_encode($matcher); - } - #[TestWith([new Boolean(true), '"matching(boolean, true)"'])] #[TestWith([new Boolean(false), '"matching(boolean, false)"'])] public function testFormatExpression(MatcherInterface $matcher, string $expression): void diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/DateTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/DateTest.php index 7e7ae4e4..b71a0ca3 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/DateTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/DateTest.php @@ -2,8 +2,8 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; +use PhpPact\Consumer\Matcher\Generators\Date as DateGenerator; use PhpPact\Consumer\Matcher\Generators\ProviderState; use PhpPact\Consumer\Matcher\Matchers\Date; use PhpPact\Consumer\Matcher\Model\GeneratorInterface; @@ -13,23 +13,16 @@ class DateTest extends TestCase { - #[TestWith([new Date('yyyy-MM-dd', null), '{"pact:generator:type":"Date","format":"yyyy-MM-dd","pact:matcher:type":"date","value":null}'])] - #[TestWith([new Date('yyyy-MM-dd', '1995-02-04'), '{"pact:matcher:type":"date","format":"yyyy-MM-dd","value":"1995-02-04"}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new Date('yyyy-MM-dd', '1995-02-04'), null, '{"pact:matcher:type":"date","format":"yyyy-MM-dd","value":"1995-02-04"}'])] + #[TestWith([new Date('yyyy-MM-dd', '1995-02-04'), new DateGenerator('yyyy-MM-dd'), '{"pact:generator:type":"Date","format":"yyyy-MM-dd","pact:matcher:type":"date","value":"1995-02-04"}'])] + public function testFormatJson(Date $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - public function testInvalidValue(): void - { - $matcher = (new Date('yyyy-MM-dd'))->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage(sprintf("DateTime matching expression doesn't support value of type %s", gettype(null))); - json_encode($matcher); - } - #[TestWith([new Date("contains single quote '", '2012-04-12'), "\"matching(date, 'contains single quote \\\'', '2012-04-12')\""])] #[TestWith([new Date('yyyy-MM-dd', "contains single quote '"), "\"matching(date, 'yyyy-MM-dd', 'contains single quote \\\'')\""])] #[TestWith([new Date('yyyy-MM-dd', '2012-04-12'), "\"matching(date, 'yyyy-MM-dd', '2012-04-12')\""])] diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/DateTimeTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/DateTimeTest.php index 0fe34a80..cb2f1cb0 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/DateTimeTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/DateTimeTest.php @@ -2,8 +2,8 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; +use PhpPact\Consumer\Matcher\Generators\DateTime as DateTimeGenerator; use PhpPact\Consumer\Matcher\Generators\ProviderState; use PhpPact\Consumer\Matcher\Matchers\DateTime; use PhpPact\Consumer\Matcher\Model\GeneratorInterface; @@ -13,24 +13,16 @@ class DateTimeTest extends TestCase { - #[TestWith([new DateTime("yyyy-MM-dd'T'HH:mm:ss"), '{"pact:matcher:type":"datetime","pact:generator:type":"DateTime","format":"yyyy-MM-dd\'T\'HH:mm:ss","value": null}'])] - #[TestWith([new DateTime("yyyy-MM-dd'T'HH:mm:ss", '1995-02-04T22:45:00'), '{"pact:matcher:type":"datetime","format":"yyyy-MM-dd\'T\'HH:mm:ss","value":"1995-02-04T22:45:00"}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new DateTime("yyyy-MM-dd'T'HH:mm:ss", '1995-02-04T22:45:00'), null, '{"pact:matcher:type":"datetime","format":"yyyy-MM-dd\'T\'HH:mm:ss","value":"1995-02-04T22:45:00"}'])] + #[TestWith([new DateTime("yyyy-MM-dd'T'HH:mm:ss", '1995-02-04T22:45:00'), new DateTimeGenerator("yyyy-MM-dd'T'HH:mm:ss"), '{"pact:matcher:type":"datetime","pact:generator:type":"DateTime","format":"yyyy-MM-dd\'T\'HH:mm:ss","value": "1995-02-04T22:45:00"}'])] + public function testFormatJson(DateTime $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - - public function testInvalidValue(): void - { - $matcher = (new DateTime("yyyy-MM-dd'T'HH:mm:ss"))->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage(sprintf("DateTime matching expression doesn't support value of type %s", gettype(null))); - json_encode($matcher); - } - #[TestWith([new DateTime("contains single quote '", '2020-05-21 16:44:32+10:00'), "\"matching(datetime, 'contains single quote \\\'', '2020-05-21 16:44:32+10:00')\""])] #[TestWith([new DateTime('yyyy-MM-dd HH:mm:ssZZZZZ', "contains single quote '"), "\"matching(datetime, 'yyyy-MM-dd HH:mm:ssZZZZZ', 'contains single quote \\\'')\""])] #[TestWith([new DateTime('yyyy-MM-dd HH:mm:ssZZZZZ', '2020-05-21 16:44:32+10:00'), "\"matching(datetime, 'yyyy-MM-dd HH:mm:ssZZZZZ', '2020-05-21 16:44:32+10:00')\""])] diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/DecimalTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/DecimalTest.php index 5990cd5c..fcc9871a 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/DecimalTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/DecimalTest.php @@ -2,9 +2,9 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; use PhpPact\Consumer\Matcher\Generators\ProviderState; +use PhpPact\Consumer\Matcher\Generators\RandomDecimal; use PhpPact\Consumer\Matcher\Matchers\Decimal; use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PhpPact\Consumer\Matcher\Model\MatcherInterface; @@ -13,23 +13,16 @@ class DecimalTest extends TestCase { - #[TestWith([new Decimal(null), '{"pact:matcher:type":"decimal","pact:generator:type":"RandomDecimal","digits":10,"value":null}'])] - #[TestWith([new Decimal(1.23), '{"pact:matcher:type":"decimal","value":1.23}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new Decimal(1.23), null, '{"pact:matcher:type":"decimal","value":1.23}'])] + #[TestWith([new Decimal(1.23), new RandomDecimal(), '{"pact:matcher:type":"decimal","pact:generator:type":"RandomDecimal","digits":10,"value":1.23}'])] + public function testFormatJson(Decimal $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - public function testInvalidValue(): void - { - $matcher = (new Decimal())->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage(sprintf("Decimal matching expression doesn't support value of type %s", gettype(null))); - json_encode($matcher); - } - #[TestWith([new Decimal(-99), '"matching(decimal, -99)"'])] // Provider verification will fail on this case #[TestWith([new Decimal(100), '"matching(decimal, 100)"'])] // Provider verification will fail on this case #[TestWith([new Decimal(100.01), '"matching(decimal, 100.01)"'])] diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/EachKeyTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/EachKeyTest.php index b01341d5..cff7183c 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/EachKeyTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/EachKeyTest.php @@ -2,6 +2,7 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; +use PhpPact\Consumer\Matcher\Enum\HttpStatus; use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Exception\MatcherNotSupportedException; use PhpPact\Consumer\Matcher\Exception\MatchingExpressionException; @@ -54,9 +55,8 @@ public function testFormatJson(): void }, { "pact:matcher:type": "regex", - "pact:generator:type": "Regex", "regex": "\\\\w{3}", - "value": null + "value": "" } ] } @@ -82,7 +82,7 @@ public function testTooManyRules(): void public function testInvalidRules(): void { - $matcher = (new EachKey(['key' => 'value'], [new StatusCode('info')]))->withFormatter(new ExpressionFormatter()); + $matcher = (new EachKey(['key' => 'value'], [new StatusCode(HttpStatus::INFORMATION)]))->withFormatter(new ExpressionFormatter()); $this->expectException(MatcherNotSupportedException::class); $this->expectExceptionMessage(sprintf("Rule '%s' must implement '%s' to be formatted as expression", StatusCode::class, ExpressionFormattableInterface::class)); json_encode($matcher); diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/EachValueTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/EachValueTest.php index 98a16879..e5fa1f87 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/EachValueTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/EachValueTest.php @@ -2,6 +2,7 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; +use PhpPact\Consumer\Matcher\Enum\HttpStatus; use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Exception\MatcherNotSupportedException; use PhpPact\Consumer\Matcher\Exception\MatchingExpressionException; @@ -50,12 +51,11 @@ public function testFormatJson(): void }, { "pact:matcher:type": "regex", - "pact:generator:type": "Regex", "regex": "\\\\w{2}\\\\d", - "value": null + "value": "" } ] - } + } JSON, $jsonEncoded ); @@ -78,7 +78,7 @@ public function testTooManyRules(): void public function testInvalidRules(): void { - $matcher = (new EachValue(['value'], [new StatusCode('info')]))->withFormatter(new ExpressionFormatter()); + $matcher = (new EachValue(['value'], [new StatusCode(HttpStatus::INFORMATION)]))->withFormatter(new ExpressionFormatter()); $this->expectException(MatcherNotSupportedException::class); $this->expectExceptionMessage(sprintf("Rule '%s' must implement '%s' to be formatted as expression", StatusCode::class, ExpressionFormattableInterface::class)); json_encode($matcher); diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/IntegerTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/IntegerTest.php index 0360d231..8ada8d35 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/IntegerTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/IntegerTest.php @@ -2,9 +2,9 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; use PhpPact\Consumer\Matcher\Generators\ProviderState; +use PhpPact\Consumer\Matcher\Generators\RandomInt; use PhpPact\Consumer\Matcher\Matchers\Integer; use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PhpPact\Consumer\Matcher\Model\MatcherInterface; @@ -13,24 +13,16 @@ class IntegerTest extends TestCase { - #[TestWith([new Integer(null), '{"pact:matcher:type":"integer","pact:generator:type":"RandomInt","min":0,"max":10,"value": null}'])] - #[TestWith([new Integer(123), '{"pact:matcher:type":"integer","value":123}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new Integer(123), null, '{"pact:matcher:type":"integer","value":123}'])] + #[TestWith([new Integer(123), new RandomInt(), '{"pact:matcher:type":"integer","pact:generator:type":"RandomInt","min":0,"max":10,"value": 123}'])] + public function testFormatJson(Integer $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - public function testInvalidValue(): void - { - $matcher = new Integer(); - $matcher = $matcher->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage(sprintf("Integer matching expression doesn't support value of type %s", gettype(null))); - json_encode($matcher); - } - #[TestWith([new Integer(-99), '"matching(integer, -99)"'])] #[TestWith([new Integer(100), '"matching(integer, 100)"'])] public function testFormatExpression(MatcherInterface $matcher, string $expression): void diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/NumberTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/NumberTest.php index 4aeebe5f..2e9f6d52 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/NumberTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/NumberTest.php @@ -2,9 +2,9 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; use PhpPact\Consumer\Matcher\Generators\ProviderState; +use PhpPact\Consumer\Matcher\Generators\RandomInt; use PhpPact\Consumer\Matcher\Matchers\Number; use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PhpPact\Consumer\Matcher\Model\MatcherInterface; @@ -13,25 +13,18 @@ class NumberTest extends TestCase { - #[TestWith([new Number(null), '{"pact:matcher:type":"number","pact:generator:type":"RandomInt","min":0,"max":10,"value":null}'])] - #[TestWith([new Number(123), '{"pact:matcher:type":"number","value":123}'])] - #[TestWith([new Number(12.3), '{"pact:matcher:type":"number","value":12.3}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new Number(123), null, '{"pact:matcher:type":"number","value":123}'])] + #[TestWith([new Number(12.3), null, '{"pact:matcher:type":"number","value":12.3}'])] + #[TestWith([new Number(123), new RandomInt(), '{"pact:matcher:type":"number","pact:generator:type":"RandomInt","min":0,"max":10,"value":123}'])] + #[TestWith([new Number(12.3), new RandomInt(), '{"pact:matcher:type":"number","pact:generator:type":"RandomInt","min":0,"max":10,"value":12.3}'])] + public function testFormatJson(Number $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - public function testInvalidValue(): void - { - $matcher = new Number(); - $matcher = $matcher->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage(sprintf("Number matching expression doesn't support value of type %s", gettype(null))); - json_encode($matcher); - } - #[TestWith([new Number(-99), '"matching(number, -99)"'])] #[TestWith([new Number(100), '"matching(number, 100)"'])] #[TestWith([new Number(100.01), '"matching(number, 100.01)"'])] diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/RegexTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/RegexTest.php index 9306fd84..54e8bb6c 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/RegexTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/RegexTest.php @@ -2,38 +2,24 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidRegexException; use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; +use PhpPact\Consumer\Matcher\Generators\Regex as RegexGenerator; use PhpPact\Consumer\Matcher\Matchers\Regex; +use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PhpPact\Consumer\Matcher\Model\MatcherInterface; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; class RegexTest extends TestCase { - private string $regex = '\d+'; - - #[TestWith(['number', true])] - #[TestWith(['integer', false])] - public function testInvalidRegex(string $value, bool $isArray): void - { - $values = $isArray ? [$value] : $value; - $this->expectException(InvalidRegexException::class); - $value = is_array($values) ? $values[0] : $values; - $this->expectExceptionMessage("The value '{$value}' doesn't match pattern '{$this->regex}'. Failed with error code 0."); - new Regex($this->regex, $values); - } - - /** - * @param string|string[]|null $values - */ - #[TestWith([null, '{"pact:matcher:type":"regex","pact:generator:type":"Regex","regex":"\\\\d+","value":null}'])] - #[TestWith(['12+', '{"pact:matcher:type":"regex","regex":"\\\\d+","value":"12+"}'])] - #[TestWith([['12.3', '456'], '{"pact:matcher:type":"regex","regex":"\\\\d+","value":["12.3","456"]}'])] - public function testFormatJson(string|array|null $values, string $json): void + #[TestWith([new Regex('\d+', '12+'), null, '{"pact:matcher:type":"regex","regex":"\\\\d+","value":"12+"}'])] + #[TestWith([new Regex('\d+', ['12.3', '456']), null, '{"pact:matcher:type":"regex","regex":"\\\\d+","value":["12.3","456"]}'])] + #[TestWith([new Regex('\d+', '12+'), new RegexGenerator('\d+'), '{"pact:matcher:type":"regex","pact:generator:type":"Regex","regex":"\\\\d+","value":"12+"}'])] + #[TestWith([new Regex('\d+', ['12.3', '456']), new RegexGenerator('\d+'), '{"pact:matcher:type":"regex","pact:generator:type":"Regex","regex":"\\\\d+","value":["12.3","456"]}'])] + public function testFormatJson(Regex $matcher, ?GeneratorInterface $generator, string $json): void { - $matcher = new Regex($this->regex, $values); + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/SemverTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/SemverTest.php index 78edf764..d5d0ee7d 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/SemverTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/SemverTest.php @@ -2,33 +2,26 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; +use PhpPact\Consumer\Matcher\Generators\Regex; use PhpPact\Consumer\Matcher\Matchers\Semver; +use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PhpPact\Consumer\Matcher\Model\MatcherInterface; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; class SemverTest extends TestCase { - #[TestWith([new Semver(null), '{"pact:matcher:type":"semver","pact:generator:type":"Regex","regex":"\\\\d+\\\\.\\\\d+\\\\.\\\\d+","value": null}'])] - #[TestWith([new Semver('1.2.3'), '{"pact:matcher:type":"semver","value":"1.2.3"}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new Semver('1.2.3'), null, '{"pact:matcher:type":"semver","value":"1.2.3"}'])] + #[TestWith([new Semver('1.2.3'), new Regex('\d+\.\d+\.\d+'), '{"pact:matcher:type":"semver","pact:generator:type":"Regex","regex":"\\\\d+\\\\.\\\\d+\\\\.\\\\d+","value": "1.2.3"}'])] + public function testFormatJson(Semver $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - public function testInvalidValue(): void - { - $matcher = new Semver(); - $matcher = $matcher->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage("Semver matching expression doesn't support value of type NULL"); - json_encode($matcher); - } - #[TestWith([new Semver("contains single quote '"), "\"matching(semver, 'contains single quote \\\'')\""])] #[TestWith([new Semver('1.0.0'), "\"matching(semver, '1.0.0')\""])] public function testFormatExpression(MatcherInterface $matcher, string $expression): void diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/StatusCodeTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/StatusCodeTest.php index 886c5e95..283bf2df 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/StatusCodeTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/StatusCodeTest.php @@ -2,33 +2,35 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidHttpStatusException; +use PhpPact\Consumer\Matcher\Enum\HttpStatus; +use PhpPact\Consumer\Matcher\Generators\RandomInt; use PhpPact\Consumer\Matcher\Matchers\StatusCode; +use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; class StatusCodeTest extends TestCase { - #[TestWith(['invalid', null, null])] - #[TestWith(['info', null, '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"info","min":100,"max":199,"value": null}'])] - #[TestWith(['success', null, '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"success","min":200,"max":299,"value": null}'])] - #[TestWith(['redirect', null, '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"redirect","min":300,"max":399,"value": null}'])] - #[TestWith(['clientError', null, '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"clientError","min":400,"max":499,"value": null}'])] - #[TestWith(['serverError', null, '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"serverError","min":500,"max":599,"value": null}'])] - #[TestWith(['nonError', null, '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"nonError","min":100,"max":399,"value": null}'])] - #[TestWith(['error', null, '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"error","min":400,"max":599,"value": null}'])] - #[TestWith(['info', 123, '{"pact:matcher:type":"statusCode","status":"info","value":123}'])] - public function testFormatJson(string $status, ?int $value, ?string $json): void + #[TestWith([HttpStatus::INFORMATION, 123, null, '{"pact:matcher:type":"statusCode","status":"info","value":123}'])] + #[TestWith([HttpStatus::SUCCESS, 123, null, '{"pact:matcher:type":"statusCode","status":"success","value":123}'])] + #[TestWith([HttpStatus::REDIRECT, 123, null, '{"pact:matcher:type":"statusCode","status":"redirect","value":123}'])] + #[TestWith([HttpStatus::CLIENT_ERROR, 123, null, '{"pact:matcher:type":"statusCode","status":"clientError","value":123}'])] + #[TestWith([HttpStatus::SERVER_ERROR, 123, null, '{"pact:matcher:type":"statusCode","status":"serverError","value":123}'])] + #[TestWith([HttpStatus::NON_ERROR, 123, null, '{"pact:matcher:type":"statusCode","status":"nonError","value":123}'])] + #[TestWith([HttpStatus::ERROR, 123, null, '{"pact:matcher:type":"statusCode","status":"error","value":123}'])] + #[TestWith([HttpStatus::INFORMATION, 0, new RandomInt(100, 199), '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"info","min":100,"max":199,"value": 0}'])] + #[TestWith([HttpStatus::SUCCESS, 0, new RandomInt(200, 299), '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"success","min":200,"max":299,"value": 0}'])] + #[TestWith([HttpStatus::REDIRECT, 0, new RandomInt(300, 399), '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"redirect","min":300,"max":399,"value": 0}'])] + #[TestWith([HttpStatus::CLIENT_ERROR, 0, new RandomInt(400, 499), '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"clientError","min":400,"max":499,"value": 0}'])] + #[TestWith([HttpStatus::SERVER_ERROR, 0, new RandomInt(500, 599), '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"serverError","min":500,"max":599,"value": 0}'])] + #[TestWith([HttpStatus::NON_ERROR, 0, new RandomInt(100, 399), '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"nonError","min":100,"max":399,"value": 0}'])] + #[TestWith([HttpStatus::ERROR, 0, new RandomInt(400, 599), '{"pact:matcher:type":"statusCode","pact:generator:type":"RandomInt","status":"error","min":400,"max":599,"value": 0}'])] + public function testFormatJson(HttpStatus $status, int $value, ?GeneratorInterface $generator, string $json): void { - if (!$json) { - $this->expectException(InvalidHttpStatusException::class); - $this->expectExceptionMessage("Status 'invalid' is not supported. Supported status are: info, success, redirect, clientError, serverError, nonError, error"); - } $matcher = new StatusCode($status, $value); + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); - if ($json) { - $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); - } + $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } } diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/StringValueTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/StringValueTest.php index e146a1bd..191cf093 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/StringValueTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/StringValueTest.php @@ -5,20 +5,18 @@ use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; use PhpPact\Consumer\Matcher\Generators\Regex; use PhpPact\Consumer\Matcher\Matchers\StringValue; +use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; class StringValueTest extends TestCase { - #[TestWith([null, false, '{"pact:matcher:type": "type", "pact:generator:type": "RandomString", "size": 10, "value": "some string"}'])] - #[TestWith([null, true, '{"pact:matcher:type": "type", "pact:generator:type": "Regex", "regex": "\\\\w{3}", "value": "some string"}'])] - #[TestWith(['example text', false, '{"pact:matcher:type": "type", "value": "example text"}'])] - public function testFormatJson(?string $value, bool $hasGenerator, string $json): void + #[TestWith(['example text', null, '{"pact:matcher:type": "type", "value": "example text"}'])] + #[TestWith(['example text', new Regex('\w{3}'), '{"pact:matcher:type": "type", "pact:generator:type": "Regex", "regex": "\\\\w{3}", "value": "example text"}'])] + public function testFormatJson(string $value, ?GeneratorInterface $generator, string $json): void { $matcher = new StringValue($value); - if ($hasGenerator) { - $matcher->setGenerator(new Regex('\w{3}')); - } + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); @@ -26,8 +24,7 @@ public function testFormatJson(?string $value, bool $hasGenerator, string $json) #[TestWith(["contains single quote '", "\"matching(type, 'contains single quote \\\'')\""])] #[TestWith(['value', "\"matching(type, 'value')\""])] - #[TestWith([null, "\"matching(type, 'some string')\""])] - public function testFormatExpression(?string $value, string $expression): void + public function testFormatExpression(string $value, string $expression): void { $matcher = new StringValue($value); $matcher = $matcher->withFormatter(new ExpressionFormatter()); diff --git a/tests/PhpPact/Consumer/Matcher/Matchers/TimeTest.php b/tests/PhpPact/Consumer/Matcher/Matchers/TimeTest.php index 08a84596..d176fe8d 100644 --- a/tests/PhpPact/Consumer/Matcher/Matchers/TimeTest.php +++ b/tests/PhpPact/Consumer/Matcher/Matchers/TimeTest.php @@ -2,9 +2,9 @@ namespace PhpPactTest\Consumer\Matcher\Matchers; -use PhpPact\Consumer\Matcher\Exception\InvalidValueException; use PhpPact\Consumer\Matcher\Formatters\Expression\ExpressionFormatter; use PhpPact\Consumer\Matcher\Generators\ProviderState; +use PhpPact\Consumer\Matcher\Generators\Time as TimeGenerator; use PhpPact\Consumer\Matcher\Matchers\Time; use PhpPact\Consumer\Matcher\Model\GeneratorInterface; use PhpPact\Consumer\Matcher\Model\MatcherInterface; @@ -13,23 +13,16 @@ class TimeTest extends TestCase { - #[TestWith([new Time('HH:mm:ss', null), '{"pact:matcher:type":"time","pact:generator:type":"Time","format":"HH:mm:ss","value":null}'])] - #[TestWith([new Time('HH:mm:ss', '12:02::34'), '{"pact:matcher:type":"time","format":"HH:mm:ss","value":"12:02::34"}'])] - public function testFormatJson(MatcherInterface $matcher, string $json): void + #[TestWith([new Time('HH:mm:ss', '12:02::34'), null, '{"pact:matcher:type":"time","format":"HH:mm:ss","value":"12:02::34"}'])] + #[TestWith([new Time('HH:mm:ss', '12:02::34'), new TimeGenerator('HH:mm:ss'), '{"pact:matcher:type":"time","pact:generator:type":"Time","format":"HH:mm:ss","value":"12:02::34"}'])] + public function testFormatJson(Time $matcher, ?GeneratorInterface $generator, string $json): void { + $matcher->setGenerator($generator); $jsonEncoded = json_encode($matcher); $this->assertIsString($jsonEncoded); $this->assertJsonStringEqualsJsonString($json, $jsonEncoded); } - public function testInvalidValue(): void - { - $matcher = (new Time('HH:mm'))->withFormatter(new ExpressionFormatter()); - $this->expectException(InvalidValueException::class); - $this->expectExceptionMessage(sprintf("DateTime matching expression doesn't support value of type %s", gettype(null))); - json_encode($matcher); - } - #[TestWith([new Time("contains single quote '", '22:04'), "\"matching(time, 'contains single quote \\\'', '22:04')\""])] #[TestWith([new Time('HH:mm', "contains single quote '"), "\"matching(time, 'HH:mm', 'contains single quote \\\'')\""])] #[TestWith([new Time('HH:mm', '22:04'), "\"matching(time, 'HH:mm', '22:04')\""])] diff --git a/tests/PhpPact/Xml/XmlTextTest.php b/tests/PhpPact/Xml/XmlTextTest.php index 88e6e431..f1fa1af9 100644 --- a/tests/PhpPact/Xml/XmlTextTest.php +++ b/tests/PhpPact/Xml/XmlTextTest.php @@ -30,7 +30,7 @@ public function testJsonSerializeMatcher(): void $matcher->setFormatter(new XmlContentFormatter()); $text = new XmlText($matcher); $expected = json_encode([ - 'content' => null, + 'content' => 13, 'matcher' => [ 'pact:matcher:type' => 'integer', 'min' => 2,