File tree Expand file tree Collapse file tree 9 files changed +186
-2
lines changed Expand file tree Collapse file tree 9 files changed +186
-2
lines changed Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ The package currently provides the following traits:
2525 * [ ` Dont\DontSet ` ] ( docs/DontSet.md )
2626 * [ ` Dont\DontCall ` ] ( docs/DontCall.md )
2727 * [ ` Dont\DontCallStatic ` ] ( docs/DontCallStatic.md )
28+ * [ ` Dont\DontToString ` ] ( docs/DontToString.md )
2829 * [ ` Dont\JustDont ` ] ( docs/JustDont.md )
2930
3031Usage is straightforward:
Original file line number Diff line number Diff line change 1+ # DontToString
2+
3+ Prevent converting an object as a string.
4+
5+ ``` php
6+ use Dont\DontToString;
7+
8+ class MyClass
9+ {
10+ use DontToString;
11+ }
12+ (new MyClass)->__toString(); // will throw NonStringableObject exception
13+ ```
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Dont ;
6+
7+ use Dont \Exception \NonCloneableObject ;
8+ use Dont \Exception \NonStringableObject ;
9+ use Dont \Exception \TypeError ;
10+
11+ trait DontToString
12+ {
13+ /**
14+ * @throws NonStringableObject
15+ * @throws TypeError
16+ */
17+ final public function __toString () : string
18+ {
19+ throw NonStringableObject::fromAttemptedToString ($ this );
20+ }
21+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Dont \Exception ;
6+
7+ use LogicException ;
8+
9+ class NonStringableObject extends LogicException implements ExceptionInterface
10+ {
11+ private const ERROR_TEMPLATE = <<<'ERROR'
12+ The given object %s#%s is not designed to be stringable.
13+
14+ You tried to access a method called "__toString()".
15+ ERROR;
16+
17+ /**
18+ * @return NonStringableObject
19+ */
20+ public static function fromAttemptedToString (object $ object ) : self
21+ {
22+ $ className = get_class ($ object );
23+
24+ return new self (sprintf (
25+ self ::ERROR_TEMPLATE ,
26+ $ className ,
27+ spl_object_hash ($ object )
28+ ));
29+ }
30+ }
Original file line number Diff line number Diff line change @@ -13,4 +13,5 @@ trait JustDont
1313 use DontClone;
1414 use DontSerialise;
1515 use DontDeserialise;
16+ use DontToString;
1617}
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace DontTest ;
6+
7+ use Dont \DontToString ;
8+ use Dont \Exception \NonStringableObject ;
9+ use DontTestAsset \DontDoIt ;
10+ use DontTestAsset \NonStringable ;
11+ use PHPUnit \Framework \TestCase ;
12+
13+ /**
14+ * @covers \Dont\DontToString
15+ */
16+ final class DontToStringTest extends TestCase
17+ {
18+ /**
19+ * @dataProvider nonStringableObject
20+ *
21+ * @param object $object
22+ */
23+ public function testWillThrowOnToStringMethodAttempt ($ object ) : void
24+ {
25+ $ this ->expectException (NonStringableObject::class);
26+
27+ $ object ->__toString ();
28+ }
29+
30+ /**
31+ * @dataProvider nonStringableObject
32+ *
33+ * @param object $object
34+ */
35+ public function testWillThrowOnStringCastAttempt ($ object ) : void
36+ {
37+ $ this ->expectException (NonStringableObject::class);
38+
39+ (string ) $ object ;
40+ }
41+
42+ /**
43+ * @return object[]
44+ */
45+ public function nonStringableObject () : array
46+ {
47+ return [
48+ [new NonStringable ()],
49+ [new DontDoIt ()],
50+ ];
51+ }
52+
53+ public function testToStringPreventionIsFinal () : void
54+ {
55+ self ::assertTrue ((new \ReflectionMethod (DontToString::class, '__toString ' ))->isFinal ());
56+ }
57+ }
Original file line number Diff line number Diff line change @@ -75,5 +75,4 @@ public function nonObjectProvider() : array
7575 [STDERR ],
7676 ];
7777 }
78-
79- }
78+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace DontTest \Exception ;
6+
7+ use Dont \Exception \ExceptionInterface ;
8+ use Dont \Exception \NonCloneableObject ;
9+ use Dont \Exception \NonStringableObject ;
10+ use Dont \Exception \TypeError ;
11+ use LogicException ;
12+ use PHPUnit \Framework \TestCase ;
13+ use stdClass ;
14+
15+ /**
16+ * @covers \Dont\Exception\NonStringableObject
17+ */
18+ final class NonStringableObjectTest extends TestCase
19+ {
20+ /**
21+ * @dataProvider objectProvider
22+ *
23+ * @param object $object
24+ */
25+ public function testFromAttemptedCloning ($ object ) : void
26+ {
27+ $ exception = NonStringableObject::fromAttemptedToString ($ object );
28+
29+ self ::assertInstanceOf (NonStringableObject::class, $ exception );
30+ self ::assertInstanceOf (LogicException::class, $ exception );
31+ self ::assertInstanceOf (ExceptionInterface::class, $ exception );
32+
33+ $ expected = 'The given object ' . get_class ($ object )
34+ . '# ' . spl_object_hash ($ object ) . " is not designed to be stringable. \n\n"
35+ . "You tried to access a method called \"__toString() \". " ;
36+
37+ self ::assertSame ($ expected , $ exception ->getMessage ());
38+ }
39+
40+ /**
41+ * @return object[][]
42+ */
43+ public function objectProvider () : array
44+ {
45+ return [
46+ [new stdClass ()],
47+ [$ this ],
48+ ];
49+ }
50+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace DontTestAsset ;
6+
7+ use Dont \DontToString ;
8+
9+ final class NonStringable
10+ {
11+ use DontToString;
12+ }
You can’t perform that action at this time.
0 commit comments