Passed
Push — master ( 9a5b65...e7105f )
by Sergei
03:07
created

ObjectParserTest.php$3 ➔ testCache()   A

Complexity

Conditions 2

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 52
cc 2
rs 9.0472

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Tests\Helper;
6
7
use Error;
8
use InvalidArgumentException;
9
use PHPUnit\Framework\TestCase;
10
use ReflectionObject;
11
use Yiisoft\Validator\Helper\ObjectParser;
12
use Yiisoft\Validator\Rule\Number;
13
use Yiisoft\Validator\Rule\Required;
14
use Yiisoft\Validator\Tests\Support\Data\ObjectForTestingCache1;
15
use Yiisoft\Validator\Tests\Support\Data\ObjectForTestingCache2;
16
use Yiisoft\Validator\Tests\Support\Data\ObjectForTestingDisabledCache;
17
use Yiisoft\Validator\Tests\Support\Data\SimpleDto;
18
use Yiisoft\Validator\Tests\Support\Rule\CustomUrlRuleSet;
19
20
final class ObjectParserTest extends TestCase
21
{
22
    public function testInvalidSource(): void
23
    {
24
        $this->expectException(InvalidArgumentException::class);
25
        $this->expectExceptionMessage('Class "non-exist-class" not found.');
26
        new ObjectParser('non-exist-class');
27
    }
28
29
    public function dataSkipStaticProperties(): array
30
    {
31
        return [
32
            [
33
                ['a' => 4, 'b' => 2],
34
                new class () {
35
                    public int $a = 4;
36
                    public static int $b = 2;
37
                },
38
                false,
39
            ],
40
            [
41
                ['a' => 4, 'c' => 'hello'],
42
                new class () {
43
                    public int $a = 4;
44
                    public static int $b = 2;
45
                    public string $c = 'hello';
46
                },
47
                true,
48
            ],
49
        ];
50
    }
51
52
    /**
53
     * @dataProvider dataSkipStaticProperties
54
     */
55
    public function testSkipStaticProperties(array $expectedData, object $object, bool $skipStaticProperties): void
56
    {
57
        $parser = new ObjectParser($object, skipStaticProperties: $skipStaticProperties);
58
59
        $this->assertSame($expectedData, $parser->getData());
60
    }
61
62
    public function testSkipStaticPropertiesDefault(): void
63
    {
64
        $object = new class () {
65
            public int $a = 4;
66
            public static int $b = 2;
67
        };
68
69
        $parser = new ObjectParser($object);
70
71
        $this->assertSame(['a' => 4, 'b' => 2], $parser->getData());
72
    }
73
74
    public function testDataWithClassString(): void
75
    {
76
        $parser = new ObjectParser(SimpleDto::class);
77
78
        $this->assertSame([], $parser->getData());
79
        $this->assertNull($parser->getAttributeValue('a'));
80
        $this->assertNull($parser->getAttributeValue('x'));
81
        $this->assertFalse($parser->hasAttribute('a'));
82
        $this->assertFalse($parser->hasAttribute('x'));
83
    }
84
85
    public function testGetRulesExpectingAttributeInheritance(): void
86
    {
87
        $object = new class () {
88
            #[CustomUrlRuleSet]
89
            public string $url;
90
        };
91
        $parser = new ObjectParser($object);
92
93
        $this->expectException(Error::class);
94
95
        $className = CustomUrlRuleSet::class;
96
        $this->expectExceptionMessage("Attempting to use non-attribute class \"$className\" as attribute");
97
98
        $parser->getRules();
99
    }
100
101
    public function testCache(): void
102
    {
103
        $parser1 = new ObjectParser(new ObjectForTestingCache1());
104
        $reflectionParser = new ReflectionObject($parser1);
105
106
        $cacheProperty = $reflectionParser->getProperty('cache');
107
        if (PHP_VERSION_ID < 80100) {
108
            $cacheProperty->setAccessible(true);
109
        }
110
111
        $cacheKey1 = 'Yiisoft\Validator\Tests\Support\Data\ObjectForTestingCache1_7_0';
112
        $this->assertArrayNotHasKey($cacheKey1, $cacheProperty->getValue());
113
114
        $expectedRules1 = [
115
            'a' => [new Required()],
116
            'b' => [new Number(min: 1)],
117
            'c' => [new Number(max: 2)],
118
        ];
119
        $rules1 = $parser1->getRules();
120
        $this->assertEquals($expectedRules1, $rules1);
121
        $cache = $cacheProperty->getValue();
122
        $this->assertArrayHasKey($cacheKey1, $cache);
123
        $this->assertArrayHasKey('rules', $cache[$cacheKey1]);
124
        $this->assertArrayHasKey('reflectionProperties', $cache[$cacheKey1]);
125
        $this->assertArrayHasKey('reflectionSource', $cache[$cacheKey1]);
126
        $this->assertSame($rules1, $parser1->getRules());
127
128
        $parser2 = new ObjectParser(new ObjectForTestingCache2());
129
        $cacheKey2 = 'Yiisoft\Validator\Tests\Support\Data\ObjectForTestingCache2_7_0';
130
        $cache = $cacheProperty->getValue();
131
        $this->assertArrayHasKey($cacheKey1, $cache);
132
        $this->assertArrayNotHasKey($cacheKey2, $cache);
133
134
        $reflectionProperties2 = $parser2->getReflectionProperties();
135
        $cache = $cacheProperty->getValue();
136
        $this->assertArrayHasKey($cacheKey1, $cache);
137
        $this->assertArrayHasKey($cacheKey2, $cache);
138
        $this->assertArrayNotHasKey('rules', $cache[$cacheKey2]);
139
        $this->assertArrayHasKey('reflectionProperties', $cache[$cacheKey2]);
140
        $this->assertArrayHasKey('reflectionSource', $cache[$cacheKey2]);
141
        $this->assertSame($reflectionProperties2, $parser2->getReflectionProperties());
142
143
        $expectedRules2 = [
144
            'd' => [new Required()],
145
            'e' => [new Number(min: 5)],
146
            'f' => [new Number(max: 6)],
147
        ];
148
        $rules2 = $parser2->getRules();
149
        $this->assertEquals($expectedRules2, $parser2->getRules());
150
        $this->assertArrayHasKey('rules', $cacheProperty->getValue()[$cacheKey2]);
151
        $this->assertSame($rules2, $parser2->getRules());
152
        $this->assertSame($rules1, $parser1->getRules());
153
    }
154
155
    public function testDisabledCache(): void
156
    {
157
        $parser = new ObjectParser(new ObjectForTestingDisabledCache(), useCache: false);
158
        $reflectionParser = new ReflectionObject($parser);
159
160
        $cacheProperty = $reflectionParser->getProperty('cache');
161
        if (PHP_VERSION_ID < 80100) {
162
            $cacheProperty->setAccessible(true);
163
        }
164
165
        $cacheKey = 'Yiisoft\Validator\Tests\Support\Data\ObjectForTestingDisabledCache_7_0';
166
        $this->assertArrayNotHasKey($cacheKey, $cacheProperty->getValue());
167
168
        $expectedRules = [
169
            'a' => [new Required()],
170
            'b' => [new Number(min: 1)],
171
            'c' => [new Number(max: 2)],
172
        ];
173
        $rules = $parser->getRules();
174
        $this->assertEquals($expectedRules, $rules);
175
        $this->assertArrayNotHasKey($cacheKey, $cacheProperty->getValue());
176
        $this->assertEquals($expectedRules, $parser->getRules());
177
        $this->assertNotSame($rules, $parser->getRules());
178
        $this->assertArrayNotHasKey($cacheKey, $cacheProperty->getValue());
179
    }
180
}
181