Passed
Push — 1.x ( 3a787a...7d322e )
by Kevin
02:49 queued 25s
created

SameUrlAssertion::__invoke()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
nc 2
nop 0
dl 0
loc 14
rs 9.9666
c 1
b 0
f 0
1
<?php
2
3
namespace Zenstruck\Browser\Assertion;
4
5
use Zenstruck\Assert\Assertion\Negatable;
6
use Zenstruck\Assert\AssertionFailed;
7
8
/**
9
 * @author Kevin Bond <[email protected]>
10
 *
11
 * @internal
12
 */
13
final class SameUrlAssertion implements Negatable
14
{
15
    private string $current;
16
    private string $expected;
17
    private array $partsToMatch;
18
19
    public function __construct(string $current, string $expected, array $partsToMatch = [])
20
    {
21
        $this->current = $current;
22
        $this->expected = $expected;
23
        $this->partsToMatch = $partsToMatch;
24
    }
25
26
    public function __invoke(): void
27
    {
28
        $parsedCurrent = $this->parseUrl($this->current);
29
        $parsedExpected = $this->parseUrl($this->expected);
30
31
        if ($parsedCurrent === $parsedExpected) {
32
            return;
33
        }
34
35
        AssertionFailed::throw(
36
            'Expected current URL ({current}) to be "{expected}" (comparing parts: "{parts}").',
37
            \array_merge($this->context(), [
38
                'compare_actual' => $parsedCurrent,
39
                'compare_expected' => $parsedExpected,
40
            ])
41
        );
42
    }
43
44
    public function notFailure(): AssertionFailed
45
    {
46
        return new AssertionFailed(
47
            'Expected current URL ({current}) to not be "{expected}" (comparing parts: "{parts}").',
48
            $this->context()
49
        );
50
    }
51
52
    private function context(): array
53
    {
54
        return [
55
            'current' => $this->current,
56
            'expected' => $this->expected,
57
            'parts' => \implode(', ', $this->partsToMatch),
58
        ];
59
    }
60
61
    private function parseUrl(string $url): array
62
    {
63
        $parts = \parse_url(\urldecode($url));
64
65
        if (empty($this->partsToMatch)) {
66
            return $parts;
67
        }
68
69
        foreach (\array_keys($parts) as $part) {
70
            if (!\in_array($part, $this->partsToMatch, true)) {
71
                unset($parts[$part]);
72
            }
73
        }
74
75
        return $parts;
76
    }
77
}
78