1 | <?php |
||
2 | |||
3 | /** |
||
4 | * PHP: Nelson Martell Library file |
||
5 | * |
||
6 | * Copyright © 2017-2021 Nelson Martell (http://nelson6e65.github.io) |
||
7 | * |
||
8 | * Licensed under The MIT License (MIT) |
||
9 | * For full copyright and license information, please see the LICENSE |
||
10 | * Redistributions of files must retain the above copyright notice. |
||
11 | * |
||
12 | * @copyright 2017-2021 Nelson Martell |
||
13 | * @link http://nelson6e65.github.io/php_nml/ |
||
14 | * @since v0.7.0 |
||
15 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License (MIT) |
||
16 | * */ |
||
17 | |||
18 | declare(strict_types=1); |
||
19 | |||
20 | namespace NelsonMartell\Test\Helpers; |
||
21 | |||
22 | use BadMethodCallException; |
||
23 | use NelsonMartell\Extensions\Text; |
||
24 | use NelsonMartell\IStrictPropertiesContainer; |
||
25 | use SebastianBergmann\Exporter\Exporter; |
||
26 | use PHPUnit\Framework\TestCase; |
||
27 | |||
28 | /** |
||
29 | * Split of ImplementsIStrictPropertiesContainer, for classes implementing any write-only property. |
||
30 | * |
||
31 | * @author Nelson Martell <[email protected]> |
||
32 | * */ |
||
33 | trait HasReadOnlyProperties |
||
34 | { |
||
35 | /** |
||
36 | * ImplementsIStrictPropertiesContainer trait provides this method implementation. |
||
37 | * |
||
38 | * @see ImplementsIStrictPropertiesContainer::testImplementsIStrictPropertiesContainerInterface() |
||
39 | */ |
||
40 | abstract public function testImplementsIStrictPropertiesContainerInterface(): void; |
||
41 | |||
42 | abstract public function readonlyPropertiesProvider(): array; |
||
43 | |||
44 | |||
45 | /** |
||
46 | * @depends testImplementsIStrictPropertiesContainerInterface |
||
47 | * |
||
48 | * @dataProvider readonlyPropertiesProvider |
||
49 | * |
||
50 | * @param IStrictPropertiesContainer $obj |
||
51 | * @param string $property |
||
52 | * @param mixed $expected |
||
53 | */ |
||
54 | public function testReadonlyPropertiesAreReadables( |
||
55 | IStrictPropertiesContainer $obj, |
||
56 | string $property, |
||
57 | $expected |
||
58 | ): void { |
||
59 | /** @var TestCase $this */ |
||
60 | try { |
||
61 | $actual = $obj->$property; |
||
62 | } catch (BadMethodCallException $e) { |
||
0 ignored issues
–
show
|
|||
63 | $message = Text::format( |
||
64 | 'Property `{1}` it should be accessible, but does it throws an exception: "{2}".', |
||
65 | get_class($obj), |
||
66 | $property, |
||
67 | $e->getMessage() |
||
68 | ); |
||
69 | |||
70 | $this->fail($message); |
||
71 | } |
||
72 | |||
73 | $exporter = new Exporter(); |
||
74 | |||
75 | $var = get_class($obj); |
||
76 | $var = Text::variable(substr( |
||
77 | $var, |
||
78 | strrpos($var, '\\') === false ? 0 : strrpos($var, '\\') + 1 |
||
79 | )); |
||
80 | |||
81 | $message = Text::format( |
||
82 | '$actual = ${var}->{property}; // {actual}', |
||
83 | [ |
||
84 | 'var' => $var, |
||
85 | 'property' => $property, |
||
86 | 'actual' => $exporter->shortenedExport($actual), |
||
87 | ] |
||
88 | ); |
||
89 | |||
90 | $this->assertEquals($expected, $actual, $message); |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * @depends testImplementsIStrictPropertiesContainerInterface |
||
95 | * @dataProvider readonlyPropertiesProvider |
||
96 | * |
||
97 | * @param IStrictPropertiesContainer|null $obj |
||
98 | * @param string|null $property |
||
99 | * @param mixed $value |
||
100 | */ |
||
101 | public function testReadonlyPropertiesAreNotWritables( |
||
102 | IStrictPropertiesContainer $obj = null, |
||
103 | string $property = null, |
||
104 | $value = null |
||
105 | ): void { |
||
106 | /** @var TestCase $this */ |
||
107 | $this->expectException(BadMethodCallException::class); |
||
108 | |||
109 | $obj->$property = $value; |
||
110 | } |
||
111 | } |
||
112 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.