1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: namespace Cake\TestSuite;
15:
16: use Cake\Console\Command;
17: use Cake\Console\CommandRunner;
18: use Cake\Console\ConsoleIo;
19: use Cake\Console\Exception\StopException;
20: use Cake\Core\Configure;
21: use Cake\TestSuite\Constraint\Console\ContentsContain;
22: use Cake\TestSuite\Constraint\Console\ContentsContainRow;
23: use Cake\TestSuite\Constraint\Console\ContentsEmpty;
24: use Cake\TestSuite\Constraint\Console\ContentsNotContain;
25: use Cake\TestSuite\Constraint\Console\ContentsRegExp;
26: use Cake\TestSuite\Constraint\Console\ExitCode;
27: use Cake\TestSuite\Stub\ConsoleInput;
28: use Cake\TestSuite\Stub\ConsoleOutput;
29:
30: 31: 32: 33:
34: trait ConsoleIntegrationTestTrait
35: {
36: 37: 38: 39: 40:
41: protected $_useCommandRunner = false;
42:
43: 44: 45: 46: 47:
48: protected $_exitCode;
49:
50: 51: 52: 53: 54:
55: protected $_out;
56:
57: 58: 59: 60: 61:
62: protected $_err;
63:
64: 65: 66: 67: 68:
69: protected $_in;
70:
71: 72: 73: 74: 75: 76: 77:
78: public function exec($command, array $input = [])
79: {
80: $runner = $this->makeRunner();
81:
82: $this->_out = new ConsoleOutput();
83: $this->_err = new ConsoleOutput();
84: $this->_in = new ConsoleInput($input);
85:
86: $args = $this->commandStringToArgs("cake $command");
87: $io = new ConsoleIo($this->_out, $this->_err, $this->_in);
88:
89: try {
90: $this->_exitCode = $runner->run($args, $io);
91: } catch (StopException $exception) {
92: $this->_exitCode = $exception->getCode();
93: }
94: }
95:
96: 97: 98: 99: 100: 101:
102: public function cleanupConsoleTrait()
103: {
104: $this->_exitCode = null;
105: $this->_out = null;
106: $this->_err = null;
107: $this->_in = null;
108: $this->_useCommandRunner = false;
109: }
110:
111: 112: 113: 114: 115: 116:
117: public function useCommandRunner()
118: {
119: $this->_useCommandRunner = true;
120: }
121:
122: 123: 124: 125: 126: 127: 128:
129: public function assertExitCode($expected, $message = '')
130: {
131: $this->assertThat($expected, new ExitCode($this->_exitCode), $message);
132: }
133:
134: 135: 136: 137: 138: 139:
140: public function assertExitSuccess($message = '')
141: {
142: $this->assertThat(Command::CODE_SUCCESS, new ExitCode($this->_exitCode), $message);
143: }
144:
145: 146: 147: 148: 149: 150:
151: public function assertExitError($message = '')
152: {
153: $this->assertThat(Command::CODE_ERROR, new ExitCode($this->_exitCode), $message);
154: }
155:
156: 157: 158: 159: 160: 161:
162: public function assertOutputEmpty($message = '')
163: {
164: $this->assertThat(null, new ContentsEmpty($this->_out->messages(), 'output'), $message);
165: }
166:
167: 168: 169: 170: 171: 172: 173:
174: public function assertOutputContains($expected, $message = '')
175: {
176: $this->assertThat($expected, new ContentsContain($this->_out->messages(), 'output'), $message);
177: }
178:
179: 180: 181: 182: 183: 184: 185:
186: public function assertOutputNotContains($expected, $message = '')
187: {
188: $this->assertThat($expected, new ContentsNotContain($this->_out->messages(), 'output'), $message);
189: }
190:
191: 192: 193: 194: 195: 196: 197:
198: public function assertOutputRegExp($pattern, $message = '')
199: {
200: $this->assertThat($pattern, new ContentsRegExp($this->_out->messages(), 'output'), $message);
201: }
202:
203: 204: 205: 206: 207: 208: 209:
210: protected function assertOutputContainsRow(array $row, $message = '')
211: {
212: $this->assertThat($row, new ContentsContainRow($this->_out->messages(), 'output'), $message);
213: }
214:
215: 216: 217: 218: 219: 220: 221:
222: public function assertErrorContains($expected, $message = '')
223: {
224: $this->assertThat($expected, new ContentsContain($this->_err->messages(), 'error output'), $message);
225: }
226:
227: 228: 229: 230: 231: 232: 233:
234: public function assertErrorRegExp($pattern, $message = '')
235: {
236: $this->assertThat($pattern, new ContentsRegExp($this->_err->messages(), 'error output'), $message);
237: }
238:
239: 240: 241: 242: 243: 244:
245: public function assertErrorEmpty($message = '')
246: {
247: $this->assertThat(null, new ContentsEmpty($this->_err->messages(), 'error output'), $message);
248: }
249:
250: 251: 252: 253: 254:
255: protected function makeRunner()
256: {
257: if ($this->_useCommandRunner) {
258: $applicationClassName = Configure::read('App.namespace') . '\Application';
259:
260: return new CommandRunner(new $applicationClassName(CONFIG));
261: }
262:
263: return new LegacyCommandRunner();
264: }
265:
266: 267: 268: 269: 270: 271:
272: protected function commandStringToArgs($command)
273: {
274: $charCount = strlen($command);
275: $argv = [];
276: $arg = '';
277: $inDQuote = false;
278: $inSQuote = false;
279: for ($i = 0; $i < $charCount; $i++) {
280: $char = substr($command, $i, 1);
281:
282:
283: if ($char === ' ' && !$inDQuote && !$inSQuote) {
284: if (strlen($arg)) {
285: $argv[] = $arg;
286: }
287: $arg = '';
288: continue;
289: }
290:
291:
292: if ($inSQuote && $char === "'") {
293: $inSQuote = false;
294: continue;
295: }
296:
297:
298: if ($inDQuote && $char === '"') {
299: $inDQuote = false;
300: continue;
301: }
302:
303:
304: if ($char === '"' && !$inSQuote) {
305: $inDQuote = true;
306: continue;
307: }
308:
309:
310: if ($char === "'" && !$inDQuote) {
311: $inSQuote = true;
312: continue;
313: }
314:
315: $arg .= $char;
316: }
317: $argv[] = $arg;
318:
319: return $argv;
320: }
321: }
322: