JsonContext   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 10
eloc 38
c 3
b 0
f 0
dl 0
loc 91
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getJson() 0 3 1
A getValue() 0 9 2
A path_should_not_match() 0 16 2
A path_should_match() 0 16 2
A root_should_match() 0 12 2
A __construct() 0 5 1
1
<?php declare(strict_types=1);
2
namespace Behapi\PhpMatcher;
3
4
use stdClass;
5
use InvalidArgumentException;
6
7
use Behat\Behat\Context\Context;
8
use Behat\Gherkin\Node\PyStringNode;
9
10
use Symfony\Component\PropertyAccess\PropertyAccess;
11
use Symfony\Component\PropertyAccess\PropertyAccessor;
12
13
use Behapi\HttpHistory\History as HttpHistory;
14
15
use function sprintf;
16
use function json_encode;
17
use function json_decode;
18
19
class JsonContext implements Context
20
{
21
    /** @var HttpHistory */
22
    private $history;
23
24
    /** @var MatcherFactory */
25
    private $factory;
26
27
    /** @var PropertyAccessor */
28
    private $accessor;
29
30
    public function __construct(HttpHistory $history)
31
    {
32
        $this->history = $history;
33
        $this->factory = new MatcherFactory;
34
        $this->accessor = PropertyAccess::createPropertyAccessor();
35
    }
36
37
    /** @Then the root should match: */
38
    final public function root_should_match(PyStringNode $pattern): void
39
    {
40
        $matcher = $this->factory->createMatcher();
41
42
        if ($matcher->match($this->getJson(), $pattern->getRaw())) {
43
            return;
44
        }
45
46
        throw new InvalidArgumentException(
47
            sprintf(
48
                'The json root does not match with the given pattern (error : %s)',
49
                $matcher->getError()
50
            )
51
        );
52
    }
53
54
    /** @Then in the json, :path should match: */
55
    final public function path_should_match(string $path, PyStringNode $pattern): void
56
    {
57
        $value = $this->getValue($path);
58
        $matcher = $this->factory->createMatcher();
59
60
        $json = json_encode($value);
61
62
        if ($matcher->match($json, $pattern->getRaw())) {
63
            return;
64
        }
65
66
        throw new InvalidArgumentException(
67
            sprintf(
68
                'The json path "%s" does not match with the given pattern (error : %s)',
69
                $path,
70
                $matcher->getError()
71
            )
72
        );
73
    }
74
75
    /** @Then in the json, :path should not match: */
76
    final public function path_should_not_match(string $path, PyStringNode $pattern): void
77
    {
78
        $value = $this->getValue($path);
79
        $matcher = $this->factory->createMatcher();
80
81
        $json = json_encode($value);
82
83
        if (!$matcher->match($json, $pattern->getRaw())) {
84
            return;
85
        }
86
87
        throw new InvalidArgumentException(
88
            sprintf(
89
                'The json path "%s" matches with the given pattern (error : %s)',
90
                $path,
91
                $matcher->getError()
92
            )
93
        );
94
    }
95
96
    private function getJson(): ?stdClass
97
    {
98
        return json_decode((string) $this->history->getLastResponse()->getBody());
99
    }
100
101
    private function getValue(string $path)
102
    {
103
        $json = $this->getJson();
104
105
        if (null === $json) {
106
            throw new InvalidArgumentException('Expected a Json valid content, got none');
107
        }
108
109
        return $this->accessor->getValue($json, $path);
110
    }
111
}
112