out = $this->getMockBuilder('Cake\Console\ConsoleOutput') ->disableOriginalConstructor() ->getMock(); $this->err = $this->getMockBuilder('Cake\Console\ConsoleOutput') ->disableOriginalConstructor() ->getMock(); $this->in = $this->getMockBuilder('Cake\Console\ConsoleInput') ->disableOriginalConstructor() ->getMock(); $this->io = new ConsoleIo($this->out, $this->err, $this->in); } /** * teardown method * * @return void */ public function tearDown() { parent::tearDown(); if (is_dir(TMP . 'shell_test')) { $folder = new Folder(TMP . 'shell_test'); $folder->delete(); } } /** * Provider for testing choice types. * * @return array */ public function choiceProvider() { return [ [['y', 'n']], ['y,n'], ['y/n'], ['y'], ]; } /** * test ask choices method * * @dataProvider choiceProvider * @return void */ public function testAskChoices($choices) { $this->in->expects($this->at(0)) ->method('read') ->will($this->returnValue('y')); $result = $this->io->askChoice('Just a test?', $choices); $this->assertEquals('y', $result); } /** * test ask choices method * * @dataProvider choiceProvider * @return void */ public function testAskChoicesInsensitive($choices) { $this->in->expects($this->at(0)) ->method('read') ->will($this->returnValue('Y')); $result = $this->io->askChoice('Just a test?', $choices); $this->assertEquals('Y', $result); } /** * Test ask method * * @return void */ public function testAsk() { $this->out->expects($this->at(0)) ->method('write') ->with("Just a test?\n> "); $this->in->expects($this->at(0)) ->method('read') ->will($this->returnValue('y')); $result = $this->io->ask('Just a test?'); $this->assertEquals('y', $result); } /** * Test ask method * * @return void */ public function testAskDefaultValue() { $this->out->expects($this->at(0)) ->method('write') ->with("Just a test?\n[n] > "); $this->in->expects($this->at(0)) ->method('read') ->will($this->returnValue('')); $result = $this->io->ask('Just a test?', 'n'); $this->assertEquals('n', $result); } /** * testOut method * * @return void */ public function testOut() { $this->out->expects($this->at(0)) ->method('write') ->with('Just a test', 1); $this->out->expects($this->at(1)) ->method('write') ->with(['Just', 'a', 'test'], 1); $this->out->expects($this->at(2)) ->method('write') ->with(['Just', 'a', 'test'], 2); $this->out->expects($this->at(3)) ->method('write') ->with('', 1); $this->io->out('Just a test'); $this->io->out(['Just', 'a', 'test']); $this->io->out(['Just', 'a', 'test'], 2); $this->io->out(); } /** * test that verbose and quiet output levels work * * @return void */ public function testVerboseOut() { $this->out->expects($this->at(0)) ->method('write') ->with('Verbose', 1); $this->out->expects($this->at(1)) ->method('write') ->with('Normal', 1); $this->out->expects($this->at(2)) ->method('write') ->with('Quiet', 1); $this->io->level(ConsoleIo::VERBOSE); $this->io->out('Verbose', 1, ConsoleIo::VERBOSE); $this->io->out('Normal', 1, ConsoleIo::NORMAL); $this->io->out('Quiet', 1, ConsoleIo::QUIET); } /** * test that verbose and quiet output levels work * * @return void */ public function testVerboseOutput() { $this->out->expects($this->at(0)) ->method('write') ->with('Verbose', 1); $this->out->expects($this->at(1)) ->method('write') ->with('Normal', 1); $this->out->expects($this->at(2)) ->method('write') ->with('Quiet', 1); $this->io->level(ConsoleIo::VERBOSE); $this->io->verbose('Verbose'); $this->io->out('Normal'); $this->io->quiet('Quiet'); } /** * test that verbose and quiet output levels work * * @return void */ public function testQuietOutput() { $this->out->expects($this->exactly(2)) ->method('write') ->with('Quiet', 1); $this->io->level(ConsoleIo::QUIET); $this->io->out('Verbose', 1, ConsoleIo::VERBOSE); $this->io->out('Normal', 1, ConsoleIo::NORMAL); $this->io->out('Quiet', 1, ConsoleIo::QUIET); $this->io->verbose('Verbose'); $this->io->quiet('Quiet'); } /** * testErr method * * @return void */ public function testErr() { $this->err->expects($this->at(0)) ->method('write') ->with('Just a test', 1); $this->err->expects($this->at(1)) ->method('write') ->with(['Just', 'a', 'test'], 1); $this->err->expects($this->at(2)) ->method('write') ->with(['Just', 'a', 'test'], 2); $this->err->expects($this->at(3)) ->method('write') ->with('', 1); $this->io->err('Just a test'); $this->io->err(['Just', 'a', 'test']); $this->io->err(['Just', 'a', 'test'], 2); $this->io->err(); } /** * Tests abort() wrapper. * * @return void */ public function testAbort() { $this->err->expects($this->at(0)) ->method('write') ->with('Some error', 1); $this->expectException(StopException::class); $this->expectExceptionCode(1); $this->expectExceptionMessage('Some error'); $this->io->abort('Some error'); } /** * Tests abort() wrapper. * * @return void */ public function testAbortCustomCode() { $this->err->expects($this->at(0)) ->method('write') ->with('Some error', 1); $this->expectException(StopException::class); $this->expectExceptionCode(99); $this->expectExceptionMessage('Some error'); $this->io->abort('Some error', 99); } /** * testNl * * @return void */ public function testNl() { $newLine = "\n"; if (DS === '\\') { $newLine = "\r\n"; } $this->assertEquals($this->io->nl(), $newLine); $this->assertEquals($this->io->nl(true), $newLine); $this->assertEquals('', $this->io->nl(false)); $this->assertEquals($this->io->nl(2), $newLine . $newLine); $this->assertEquals($this->io->nl(1), $newLine); } /** * testHr * * @return void */ public function testHr() { $bar = str_repeat('-', 79); $this->out->expects($this->at(0))->method('write')->with('', 0); $this->out->expects($this->at(1))->method('write')->with($bar, 1); $this->out->expects($this->at(2))->method('write')->with('', 0); $this->out->expects($this->at(3))->method('write')->with('', true); $this->out->expects($this->at(4))->method('write')->with($bar, 1); $this->out->expects($this->at(5))->method('write')->with('', true); $this->out->expects($this->at(6))->method('write')->with('', 2); $this->out->expects($this->at(7))->method('write')->with($bar, 1); $this->out->expects($this->at(8))->method('write')->with('', 2); $this->io->hr(); $this->io->hr(true); $this->io->hr(2); } /** * Test overwriting. * * @return void */ public function testOverwrite() { $number = strlen('Some text I want to overwrite'); $this->out->expects($this->at(0)) ->method('write') ->with('Some text I want to overwrite', 0) ->will($this->returnValue($number)); $this->out->expects($this->at(1)) ->method('write') ->with(str_repeat("\x08", $number), 0); $this->out->expects($this->at(2)) ->method('write') ->with('Less text', 0) ->will($this->returnValue(9)); $this->out->expects($this->at(3)) ->method('write') ->with(str_repeat(' ', $number - 9), 0); $this->io->out('Some text I want to overwrite', 0); $this->io->overwrite('Less text'); } /** * Test overwriting content with shorter content * * @return void */ public function testOverwriteWithShorterContent() { $length = strlen('12345'); $this->out->expects($this->at(0)) ->method('write') ->with('12345') ->will($this->returnValue($length)); // Backspaces $this->out->expects($this->at(1)) ->method('write') ->with(str_repeat("\x08", $length), 0) ->will($this->returnValue($length)); $this->out->expects($this->at(2)) ->method('write') ->with('123', 0) ->will($this->returnValue(3)); // 2 spaces output to pad up to 5 bytes $this->out->expects($this->at(3)) ->method('write') ->with(str_repeat(' ', $length - 3), 0) ->will($this->returnValue($length - 3)); // Backspaces $this->out->expects($this->at(4)) ->method('write') ->with(str_repeat("\x08", $length), 0) ->will($this->returnValue($length)); $this->out->expects($this->at(5)) ->method('write') ->with('12', 0) ->will($this->returnValue(2)); $this->out->expects($this->at(6)) ->method('write') ->with(str_repeat(' ', $length - 2), 0); $this->io->out('12345'); $this->io->overwrite('123', 0); $this->io->overwrite('12', 0); } /** * Test overwriting content with longer content * * @return void */ public function testOverwriteWithLongerContent() { $this->out->expects($this->at(0)) ->method('write') ->with('1') ->will($this->returnValue(1)); // Backspaces $this->out->expects($this->at(1)) ->method('write') ->with(str_repeat("\x08", 1), 0) ->will($this->returnValue(1)); $this->out->expects($this->at(2)) ->method('write') ->with('123', 0) ->will($this->returnValue(3)); // Backspaces $this->out->expects($this->at(3)) ->method('write') ->with(str_repeat("\x08", 3), 0) ->will($this->returnValue(3)); $this->out->expects($this->at(4)) ->method('write') ->with('12345', 0) ->will($this->returnValue(5)); $this->io->out('1'); $this->io->overwrite('123', 0); $this->io->overwrite('12345', 0); } /** * Tests that setLoggers works properly * * @return void */ public function testSetLoggers() { Log::drop('stdout'); Log::drop('stderr'); $this->io->setLoggers(true); $this->assertNotEmpty(Log::engine('stdout')); $this->assertNotEmpty(Log::engine('stderr')); $this->io->setLoggers(false); $this->assertFalse(Log::engine('stdout')); $this->assertFalse(Log::engine('stderr')); } /** * Tests that setLoggers works properly with quiet * * @return void */ public function testSetLoggersQuiet() { Log::drop('stdout'); Log::drop('stderr'); $this->io->setLoggers(ConsoleIo::QUIET); $this->assertEmpty(Log::engine('stdout')); $this->assertNotEmpty(Log::engine('stderr')); } /** * Tests that setLoggers works properly with verbose * * @return void */ public function testSetLoggersVerbose() { Log::drop('stdout'); Log::drop('stderr'); $this->io->setLoggers(ConsoleIo::VERBOSE); $this->assertNotEmpty(Log::engine('stderr')); $engine = Log::engine('stdout'); $this->assertEquals(['notice', 'info', 'debug'], $engine->getConfig('levels')); } /** * Ensure that styles() just proxies to stdout. * * @return void */ public function testStyles() { $this->out->expects($this->once()) ->method('styles') ->with('name', 'props'); $this->io->styles('name', 'props'); } /** * Test the helper method. * * @return void */ public function testHelper() { $this->out->expects($this->once()) ->method('write') ->with('It works!well ish'); $helper = $this->io->helper('simple'); $this->assertInstanceOf('Cake\Console\Helper', $helper); $helper->output(['well', 'ish']); } /** * Provider for output helpers * * @return array */ public function outHelperProvider() { return [['info'], ['success']]; } /** * Provider for err helpers * * @return array */ public function errHelperProvider() { return [['warning'], ['error']]; } /** * test out helper methods * * @dataProvider outHelperProvider * @return void */ public function testOutHelpers($method) { $this->out->expects($this->at(0)) ->method('write') ->with("<{$method}>Just a test", 1); $this->out->expects($this->at(1)) ->method('write') ->with(["<{$method}>Just", "<{$method}>a test"], 1); $this->io->{$method}('Just a test'); $this->io->{$method}(['Just', 'a test']); } /** * test err helper methods * * @dataProvider errHelperProvider * @return void */ public function testErrHelpers($method) { $this->err->expects($this->at(0)) ->method('write') ->with("<{$method}>Just a test", 1); $this->err->expects($this->at(1)) ->method('write') ->with(["<{$method}>Just", "<{$method}>a test"], 1); $this->io->{$method}('Just a test'); $this->io->{$method}(['Just', 'a test']); } /** * Test that createFile * * @return void */ public function testCreateFileSuccess() { $this->err->expects($this->never()) ->method('write'); $path = TMP . 'shell_test'; mkdir($path); $file = $path . DS . 'file1.php'; $contents = 'some content'; $result = $this->io->createFile($file, $contents); $this->assertTrue($result); $this->assertFileExists($file); $this->assertStringEqualsFile($file, $contents); } public function testCreateFileDirectoryCreation() { $this->err->expects($this->never()) ->method('write'); $directory = TMP . 'shell_test'; $this->assertFileNotExists($directory, 'Directory should not exist before createFile'); $path = $directory . DS . 'create.txt'; $contents = 'some content'; $result = $this->io->createFile($path, $contents); $this->assertTrue($result, 'File should create'); $this->assertFileExists($path); $this->assertStringEqualsFile($path, $contents); } /** * Test that createFile with permissions error. * * @return void */ public function testCreateFilePermissionsError() { $this->skipIf(DS === '\\', 'Cant perform operations using permissions on windows.'); $path = TMP . 'shell_test'; $file = $path . DS . 'no_perms'; if (!is_dir($path)) { mkdir($path); } chmod($path, 0444); $this->io->createFile($file, 'testing'); $this->assertFileNotExists($file); chmod($path, 0744); rmdir($path); } /** * Test that `q` raises an error. * * @expectedException \Cake\Console\Exception\StopException * @return void */ public function testCreateFileOverwriteQuit() { $path = TMP . 'shell_test'; mkdir($path); $file = $path . DS . 'file1.php'; touch($file); $this->in->expects($this->once()) ->method('read') ->will($this->returnValue('q')); $this->io->createFile($file, 'some content'); } /** * Test that `n` raises an error. * * @return void */ public function testCreateFileOverwriteNo() { $path = TMP . 'shell_test'; mkdir($path); $file = $path . DS . 'file1.php'; file_put_contents($file, 'original'); touch($file); $this->in->expects($this->once()) ->method('read') ->will($this->returnValue('n')); $contents = 'new content'; $result = $this->io->createFile($file, $contents); $this->assertFalse($result); $this->assertFileExists($file); $this->assertStringEqualsFile($file, 'original'); } /** * Test the forceOverwrite parameter * * @return void */ public function testCreateFileOverwriteParam() { $path = TMP . 'shell_test'; mkdir($path); $file = $path . DS . 'file1.php'; file_put_contents($file, 'original'); touch($file); $contents = 'new content'; $result = $this->io->createFile($file, $contents, true); $this->assertTrue($result); $this->assertFileExists($file); $this->assertStringEqualsFile($file, $contents); } /** * Test the `a` response * * @return void */ public function testCreateFileOverwriteAll() { $path = TMP . 'shell_test'; mkdir($path); $file = $path . DS . 'file1.php'; file_put_contents($file, 'original'); touch($file); $this->in->expects($this->once()) ->method('read') ->will($this->returnValue('a')); $this->io->createFile($file, 'new content'); $this->assertStringEqualsFile($file, 'new content'); $this->io->createFile($file, 'newer content'); $this->assertStringEqualsFile($file, 'newer content'); $this->io->createFile($file, 'newest content', false); $this->assertStringEqualsFile( $file, 'newest content', 'overwrite state replaces parameter' ); } }