Skip to content

Commit

Permalink
feat: Refactor http client mock
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Request matcher behaviour has changed for headers, queryParams, requestParams and multiparts
  • Loading branch information
Stephan Wentz committed Jan 30, 2025
1 parent 9afa5f9 commit 8125287
Show file tree
Hide file tree
Showing 61 changed files with 4,005 additions and 1,723 deletions.
10 changes: 5 additions & 5 deletions src/HttpClientMock/CallStack.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

use const PHP_EOL;

/** @implements IteratorAggregate<MockRequestBuilder> */
/** @implements IteratorAggregate<RealRequest> */
final class CallStack implements Countable, IteratorAggregate
{
/** @var MockRequestBuilder[] */
/** @var RealRequest[] */
private array $calls;

public function __construct(MockRequestBuilder ...$calls)
public function __construct(RealRequest ...$calls)
{
$this->calls = $calls;
}
Expand All @@ -33,7 +33,7 @@ public static function fromCallStacks(CallStack ...$callStacks): self
return new self(...$requests);
}

public function first(): MockRequestBuilder|null
public function first(): RealRequest|null

Check warning on line 36 in src/HttpClientMock/CallStack.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/CallStack.php#L36

Added line #L36 was not covered by tests
{
if (!count($this->calls)) {
return null;
Expand All @@ -52,7 +52,7 @@ public function count(): int
return count($this->calls);
}

/** @return Traversable<MockRequestBuilder>|MockRequestBuilder[] */
/** @return Traversable<RealRequest> */
public function getIterator(): Traversable
{
yield from $this->calls;
Expand Down
57 changes: 0 additions & 57 deletions src/HttpClientMock/Compare.php

This file was deleted.

105 changes: 97 additions & 8 deletions src/HttpClientMock/Exception/NoMatchingMockRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,114 @@

namespace Brainbits\FunctionalTestHelpers\HttpClientMock\Exception;

use Brainbits\FunctionalTestHelpers\HttpClientMock\MockRequestBuilder;
use Brainbits\FunctionalTestHelpers\HttpClientMock\MockRequestMatch;
use Brainbits\FunctionalTestHelpers\HttpClientMock\Matcher\Hit;
use Brainbits\FunctionalTestHelpers\HttpClientMock\Matcher\MatchResult;
use Brainbits\FunctionalTestHelpers\HttpClientMock\Matcher\Mismatch;
use Brainbits\FunctionalTestHelpers\HttpClientMock\Matcher\Missing;
use Brainbits\FunctionalTestHelpers\HttpClientMock\RealRequest;
use RuntimeException;

use function array_map;
use function explode;
use function implode;
use function sprintf;

use const PHP_EOL;

final class NoMatchingMockRequest extends RuntimeException implements HttpClientMockException
{
/** @param MockRequestMatch[] $matches */
public static function fromMockRequest(MockRequestBuilder $request, array $matches): self
public static function noBuilders(RealRequest $request): self

Check warning on line 23 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L23

Added line #L23 was not covered by tests
{
$message = sprintf('No mock request builders given for:%s%s%s', PHP_EOL, $request, PHP_EOL);

Check warning on line 25 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L25

Added line #L25 was not covered by tests

return new self($message);

Check warning on line 27 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L27

Added line #L27 was not covered by tests
}

/** @param MatchResult[] $matchResults */
public static function fromResults(RealRequest $request, array $matchResults): self

Check warning on line 31 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L31

Added line #L31 was not covered by tests
{
$message = sprintf('No matching mock request builder found for:%s%s%s', PHP_EOL, $request, PHP_EOL);
$message .= sprintf('%sMock request builders:%s', PHP_EOL, PHP_EOL);

Check warning on line 34 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L34

Added line #L34 was not covered by tests

$tick = '';
$cross = '';

Check warning on line 37 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L36-L37

Added lines #L36 - L37 were not covered by tests

foreach ($matchResults as $key => $matchResult) {
$no = $key + 1;
$name = $matchResult->getName();

Check warning on line 41 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L39-L41

Added lines #L39 - L41 were not covered by tests

$message .= sprintf(
'#%s %s%s',
$no,
$name ?? '(unnamed)',
PHP_EOL,
);

Check warning on line 48 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L43-L48

Added lines #L43 - L48 were not covered by tests

foreach ($matchResult->getResults() as $result) {
if ($result instanceof Hit) {
if ($result->key) {
$line = sprintf(
'%s %s %s matches "%s"',
$tick,
$result->matcher,
$result->key,
$result->actual,
);

Check warning on line 59 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L50-L59

Added lines #L50 - L59 were not covered by tests
} else {
$line = sprintf(
'%s %s matches "%s"',
$tick,
$result->matcher,
$result->actual,
);

Check warning on line 66 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L61-L66

Added lines #L61 - L66 were not covered by tests
}
} elseif ($result instanceof Mismatch) {
if ($result->key) {
$line = sprintf(
'%s %s %s "%s" does not match "%s"',
$cross,
$result->matcher,
$result->key,
$result->actual ?? 'NULL',
$result->expected,
);

Check warning on line 77 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L68-L77

Added lines #L68 - L77 were not covered by tests
} else {
$line = sprintf(
'%s %s "%s" does not match "%s"',
$cross,
$result->matcher,
$result->actual ?? 'NULL',
$result->expected,
);

Check warning on line 85 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L79-L85

Added lines #L79 - L85 were not covered by tests
}
} elseif ($result instanceof Missing) {
$line = sprintf(
'%s %s %s missing',
$cross,
$result->matcher,
$result->key,
);

Check warning on line 93 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L87-L93

Added lines #L87 - L93 were not covered by tests
} else {
continue;

Check warning on line 95 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L95

Added line #L95 was not covered by tests
}

$message .= sprintf(
' %s (%s)%s',
$line,
$result->score,
PHP_EOL,
);

Check warning on line 103 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L98-L103

Added lines #L98 - L103 were not covered by tests

if ($matches) {
$message .= sprintf('%sReasons:%s', PHP_EOL, PHP_EOL);
foreach ($matches as $match) {
$message .= sprintf('- %s%s', $match->getReason(), PHP_EOL);
if ($result instanceof Mismatch && $result->diff) { // phpcs:ignore
$diff = implode(
PHP_EOL,
array_map(
static fn ($line) => ' ' . $line,
explode(PHP_EOL, $result->diff),
),
);
$message .= $diff . PHP_EOL;

Check warning on line 113 in src/HttpClientMock/Exception/NoMatchingMockRequest.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoMatchingMockRequest.php#L105-L113

Added lines #L105 - L113 were not covered by tests
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/HttpClientMock/Exception/NoResponseMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@ public static function allResponsesProcessed(): self
return new self('All responses have already been processed');
}

public static function withRequest(self $decorated, MockRequestBuilder $request): self
public static function withRequest(self $decorated, MockRequestBuilder $requestBuilder): self

Check warning on line 26 in src/HttpClientMock/Exception/NoResponseMock.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoResponseMock.php#L26

Added line #L26 was not covered by tests
{
$message = sprintf('%s for:%s%s%s', $decorated->getMessage(), PHP_EOL, $request, PHP_EOL);
$message = sprintf(
'%s for:%s%s%s',
$decorated->getMessage(),
PHP_EOL,
$requestBuilder,
PHP_EOL,
);

Check warning on line 34 in src/HttpClientMock/Exception/NoResponseMock.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/NoResponseMock.php#L28-L34

Added lines #L28 - L34 were not covered by tests

return new self($message, $decorated->getCode(), $decorated->getPrevious());
}
Expand Down
17 changes: 0 additions & 17 deletions src/HttpClientMock/Exception/NoUriConfigured.php

This file was deleted.

17 changes: 17 additions & 0 deletions src/HttpClientMock/Exception/UriContainsQueryParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Brainbits\FunctionalTestHelpers\HttpClientMock\Exception;

use RuntimeException;

use function sprintf;

final class UriContainsQueryParameters extends RuntimeException implements HttpClientMockException
{
public static function fromUri(string $uri): self

Check warning on line 13 in src/HttpClientMock/Exception/UriContainsQueryParameters.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/UriContainsQueryParameters.php#L13

Added line #L13 was not covered by tests
{
return new self(sprintf('Given uri %s conts query parameters, use queryParam() calls instead.', $uri));

Check warning on line 15 in src/HttpClientMock/Exception/UriContainsQueryParameters.php

View check run for this annotation

Codecov / codecov/patch

src/HttpClientMock/Exception/UriContainsQueryParameters.php#L15

Added line #L15 was not covered by tests
}
}
Loading

0 comments on commit 8125287

Please sign in to comment.