Test   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 13
Bugs 2 Features 2
Metric Value
wmc 31
lcom 1
cbo 3
dl 0
loc 146
c 13
b 2
f 2
rs 9.8

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A assertValueTestability() 0 6 2
A apply() 0 10 2
A assertEquals() 0 16 1
A assertStringsEquals() 0 10 3
A assertNumbersEquals() 0 10 3
A assertLiteralEquals() 0 10 3
A assertArraysEquals() 0 14 4
A assertObjectsEquals() 0 15 4
A assertObjectHas() 0 6 2
A revert() 0 4 1
A fromDecodedJSON() 0 6 1
A assertValidOperationContent() 0 6 3
A __toString() 0 8 1
1
<?php
2
declare(strict_types=1);
3
4
namespace gamringer\JSONPatch\Operation;
5
6
use gamringer\JSONPatch\Operation;
7
use gamringer\JSONPointer\Pointer;
8
use gamringer\JSONPointer;
9
10
class Test extends Operation implements Atomic
11
{
12
    private $value;
13
14
    public function __construct(string $path, $value)
15
    {
16
        $this->assertValueTestability($value);
17
18
        $this->path = $path;
19
        $this->value = $value;
20
    }
21
22
    public function assertValueTestability($value)
23
    {
24
        if (!in_array(gettype($value), ['object', 'array', 'string', 'double', 'integer', 'boolean', 'NULL'])) {
25
            throw new Exception('Value is not a valid type');
26
        }
27
    }
28
29
    public function apply(Pointer $target)
30
    {
31
        try {
32
            $targetValue = $target->get($this->path);
33
        } catch (JSONPointer\Exception $e) {
34
            throw new Exception($e->getMessage(), 0, $e);
35
        }
36
37
        $this->assertEquals($this->value, $targetValue);
38
    }
39
40
    private function assertEquals($expected, $actual)
41
    {
42
        $assertionMethods = [
43
            'object' => 'assertObjectsEquals',
44
            'array' => 'assertArraysEquals',
45
            'string' => 'assertStringsEquals',
46
            'double' => 'assertNumbersEquals',
47
            'integer' => 'assertNumbersEquals',
48
            'boolean' => 'assertLiteralEquals',
49
            'NULL' => 'assertLiteralEquals',
50
        ];
51
52
        $type = gettype($expected);
53
        $assertionMethodName = $assertionMethods[$type];
54
        $this->$assertionMethodName($expected, $actual);
55
    }
56
57
    private function assertStringsEquals($expected, $actual)
58
    {
59
        if (gettype($actual) !== 'string') {
60
            throw new Exception('Target value is not a string');
61
        }
62
63
        if ($expected !== $actual) {
64
            throw new Exception('Target value does not match expected value');
65
        }
66
    }
67
68
    private function assertNumbersEquals($expected, $actual)
69
    {
70
        if (!in_array(gettype($actual), ['integer', 'double'])) {
71
            throw new Exception('Target value is not a number');
72
        }
73
74
        if ($expected != $actual) {
75
            throw new Exception('Target value does not match expected value');
76
        }
77
    }
78
79
    private function assertLiteralEquals($expected, $actual)
80
    {
81
        if (!in_array(gettype($actual), ['boolean', 'NULL'])) {
82
            throw new Exception('Target value is not a literal (true, false, null)');
83
        }
84
85
        if ($expected !== $actual) {
86
            throw new Exception('Target value does not match expected value');
87
        }
88
    }
89
90
    private function assertArraysEquals($expected, $actual)
91
    {
92
        if (gettype($actual) !== 'array') {
93
            throw new Exception('Target value is not an array');
94
        }
95
96
        if (sizeof($expected) !== sizeof($actual)) {
97
            throw new Exception('Target value size does not match expected value size');
98
        }
99
100
        foreach ($expected as $i => $expectedValue) {
101
            $this->assertEquals($expectedValue, $actual[$i]);
102
        }
103
    }
104
105
    private function assertObjectsEquals($expected, $actual)
106
    {
107
        if (gettype($actual) !== 'object') {
108
            throw new Exception('Target value is not an object');
109
        }
110
111
        if (sizeof(get_object_vars($expected)) !== sizeof(get_object_vars($actual))) {
112
            throw new Exception('Target value size does not match expected value size');
113
        }
114
115
        foreach ($expected as $i => $expectedValue) {
116
            $this->assertObjectHas($i, $actual);
117
            $this->assertEquals($expectedValue, $actual->{$i});
118
        }
119
    }
120
121
    private function assertObjectHas($property, $object)
122
    {
123
        if (!property_exists($object, $property)) {
124
            throw new Exception('Property missing from the target: '.$property);
125
        }
126
    }
127
128
    public function revert(Pointer $target)
129
    {
130
131
    }
132
133
    public static function fromDecodedJSON($operationContent): self
134
    {
135
        self::assertValidOperationContent($operationContent);
136
137
        return new self($operationContent->path, $operationContent->value);
138
    }
139
140
    private static function assertValidOperationContent($operationContent)
141
    {
142
        if (!property_exists($operationContent, 'path') || !property_exists($operationContent, 'value')) {
143
            throw new Operation\Exception('"Test" Operations must contain a "path" and "value" member');
144
        }
145
    }
146
147
    public function __toString(): string
148
    {
149
        return json_encode([
150
            'op' => Operation::OP_TEST,
151
            'path' => $this->path,
152
            'value' => $this->value,
153
        ]);
154
    }
155
}
156