22
33namespace Bolt \tests ;
44
5- use \PHPUnit \Framework \TestCase ;
5+ use PHPUnit \Framework \TestCase ;
6+ use Bolt \connection \IConnection ;
67
78/**
89 * Class TestBase
@@ -14,30 +15,96 @@ abstract class ATest extends TestCase
1415{
1516
1617 /**
17- * @var bool
18+ * @var int Internal pointer for "readArray"
1819 */
19- private static $ bypass = false ;
20+ static $ readIndex = 0 ;
21+ /**
22+ * @var array Order of consecutive returns from "read" method calls
23+ */
24+ static $ readArray = [];
25+ /**
26+ * @var int Internal pointer for "writeBuffer"
27+ */
28+ static $ writeIndex = 0 ;
29+ /**
30+ * @var array Expected write buffers or keep empty to skip verification
31+ */
32+ static $ writeBuffer = [];
33+
34+ /**
35+ * Mock Socket class with "write" and "read" methods
36+ * @return IConnection
37+ */
38+ protected function mockConnection ()
39+ {
40+ $ mockBuilder = $ this
41+ ->getMockBuilder (IConnection::class)
42+ ->disableOriginalConstructor ();
43+ call_user_func ([$ mockBuilder , method_exists ($ mockBuilder , 'onlyMethods ' ) ? 'onlyMethods ' : 'setMethods ' ], ['write ' , 'read ' , 'connect ' , 'disconnect ' ]);
44+ /** @var IConnection $connection */
45+ $ connection = $ mockBuilder ->getMock ();
46+
47+ $ connection
48+ ->method ('write ' )
49+ ->with (
50+ $ this ->callback (function ($ buffer ) {
51+ $ i = self ::$ writeIndex ;
52+ self ::$ writeIndex ++;
53+
54+ //skip write buffer check
55+ if (empty (self ::$ writeBuffer ))
56+ return true ;
57+
58+ //verify expected buffer
59+ return (self ::$ writeBuffer [$ i ] ?? '' ) == $ buffer ;
60+ })
61+ );
62+
63+ $ connection
64+ ->method ('read ' )
65+ ->will ($ this ->returnCallback ([$ this , 'readCallback ' ]));
66+
67+ return $ connection ;
68+ }
2069
2170 /**
22- * Bypass Socket final keyword before autoload
71+ * Mocked Socket read method
72+ * @return string
2373 */
24- public static function setUpBeforeClass (): void
74+ public function readCallback (): string
2575 {
26- if (!self ::$ bypass ) {
27- $ path = __DIR__ ;
28- while (!file_exists ($ path . DS . 'Socket.php ' )) {
29- $ path = dirname ($ path );
30- }
31-
32- $ content = file_get_contents ($ path . DS . 'Socket.php ' );
33- if (strpos ($ content , "final class Socket " ) !== false ) {
34- file_put_contents ($ path . DS . 'Socket.php ' , str_replace ('final class Socket ' , 'class Socket ' , $ content ));
35- $ socket = new \Bolt \Socket ('localhost ' , 0 , 0 );
36- file_put_contents ($ path . DS . 'Socket.php ' , $ content );
37- }
76+ switch (self ::$ readArray [self ::$ readIndex ]) {
77+ case 1 :
78+ $ output = hex2bin ('0003 ' ); // header of length 3
79+ break ;
80+ case 2 :
81+ $ output = hex2bin ('B170A0 ' ); // success {}
82+ break ;
83+ case 3 :
84+ $ output = hex2bin ('B171A0 ' ); // record {}
85+ break ;
86+ case 4 :
87+ $ output = hex2bin ('004b ' ); // failure header
88+ break ;
89+ case 5 :
90+ $ output = hex2bin ('b17fa284636f6465d0254e656f2e436c69656e744572726f722e53746174656d656e742e53796e7461784572726f72876d657373616765d012736f6d65206572726f72206d657373616765 ' ); // failure message
91+ break ;
92+ default :
93+ $ output = hex2bin ('0000 ' ); // end
3894 }
3995
40- self ::$ bypass = true ;
96+ self ::$ readIndex ++;
97+ return (string )$ output ;
4198 }
4299
100+ /**
101+ * Reset mockup IConnetion variables
102+ */
103+ protected function setUp ()
104+ {
105+ self ::$ readIndex = 0 ;
106+ self ::$ readArray = [];
107+ self ::$ writeIndex = 0 ;
108+ self ::$ writeBuffer = [];
109+ }
43110}
0 commit comments