diff --git a/tests/unit/framework/console/controllers/MessageControllerTest.php b/tests/unit/framework/console/controllers/MessageControllerTest.php new file mode 100644 index 0000000..82bb393 --- /dev/null +++ b/tests/unit/framework/console/controllers/MessageControllerTest.php @@ -0,0 +1,364 @@ +sourcePath = Yii::getAlias('@yiiunit/runtime/test_source'); + $this->createDir($this->sourcePath); + $this->messagePath = Yii::getAlias('@yiiunit/runtime/test_messages'); + $this->createDir($this->messagePath); + $this->configFileName = Yii::getAlias('@yiiunit/runtime') . DIRECTORY_SEPARATOR . 'message_controller_test_config.php'; + } + + public function tearDown() + { + $this->removeDir($this->sourcePath); + $this->removeDir($this->messagePath); + if (file_exists($this->configFileName)) { + unlink($this->configFileName); + } + } + + /** + * Creates directory. + * @param $dirName directory full name + */ + protected function createDir($dirName) + { + if (!file_exists($dirName)) { + mkdir($dirName, 0777, true); + } + } + + /** + * Removes directory. + * @param $dirName directory full name + */ + protected function removeDir($dirName) + { + if (!empty($dirName) && file_exists($dirName)) { + $this->removeFileSystemObject($dirName); + } + } + + /** + * Removes file system object: directory or file. + * @param string $fileSystemObjectFullName file system object full name. + */ + protected function removeFileSystemObject($fileSystemObjectFullName) + { + if (!is_dir($fileSystemObjectFullName)) { + unlink($fileSystemObjectFullName); + } else { + $dirHandle = opendir($fileSystemObjectFullName); + while (($fileSystemObjectName = readdir($dirHandle)) !== false) { + if ($fileSystemObjectName==='.' || $fileSystemObjectName==='..') { + continue; + } + $this->removeFileSystemObject($fileSystemObjectFullName . DIRECTORY_SEPARATOR . $fileSystemObjectName); + } + closedir($dirHandle); + rmdir($fileSystemObjectFullName); + } + } + + /** + * Creates test message controller instance. + * @return MessageController message command instance. + */ + protected function createMessageController() + { + $module = $this->getMock('yii\\base\\Module', array('fake'), array('console')); + $command = new MessageController('message', $module); + return $command; + } + + /** + * Emulates running of the message controller action. + * @param string $actionId id of action to be run. + * @param array $args action arguments. + * @return string command output. + */ + protected function runMessageControllerAction($actionId, array $args=array()) + { + $controller = $this->createMessageController(); + ob_start(); + ob_implicit_flush(false); + $params = array( + \yii\console\Request::ANONYMOUS_PARAMS => $args + ); + $controller->run($actionId, $params); + return ob_get_clean(); + } + + /** + * Creates message command config file at {@link configFileName} + * @param array $config message command config. + */ + protected function composeConfigFile(array $config) + { + if (file_exists($this->configFileName)) { + unlink($this->configFileName); + } + $fileContent = 'configFileName, $fileContent); + } + + /** + * Creates source file with given content + * @param string $content file content + * @param string|null $name file self name + */ + protected function createSourceFile($content, $name = null) + { + if (empty($name)) { + $name = md5(uniqid()) . '.php'; + } + file_put_contents($this->sourcePath . DIRECTORY_SEPARATOR . $name, $content); + } + + /** + * Creates message file with given messages. + * @param string $name file name + * @param array $messages messages. + */ + protected function createMessageFile($name, array $messages = array()) + { + $fileName = $this->messagePath . DIRECTORY_SEPARATOR . $name; + if (file_exists($fileName)) { + unlink($fileName); + } else { + $dirName = dirname($fileName); + if (!file_exists($dirName)) { + mkdir($dirName, 0777, true); + } + } + $fileContent = 'setExpectedException('CException', 'usageError'); + $this->runMessageControllerAction('index', array()); + } + + public function testConfigFileNotExist() + { + $this->setExpectedException('CException', 'usageError'); + $this->runMessageControllerAction('index', array('not_existing_file.php')); + } + + public function testCreateTranslation() + { + $language = 'en'; + + $category = 'test_category'; + $message = 'test message'; + $sourceFileContent = "Yii::t('{$category}','{$message}')"; + $this->createSourceFile($sourceFileContent); + + $this->composeConfigFile(array( + 'languages' => array($language), + 'sourcePath' => $this->sourcePath, + 'messagePath' => $this->messagePath, + )); + $this->runMessageControllerAction('index', array($this->configFileName)); + + $this->assertTrue(file_exists($this->messagePath . DIRECTORY_SEPARATOR . $language), 'No language dir created!'); + $messageFileName = $this->messagePath . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . $category . '.php'; + $this->assertTrue(file_exists($messageFileName), 'No message file created!'); + $messages = require($messageFileName); + $this->assertTrue(is_array($messages), 'Unable to compose messages!'); + $this->assertTrue(array_key_exists($message, $messages), 'Source message is missing!'); + } + + /** + * @depends testCreateTranslation + */ + public function testNothingNew() + { + $language = 'en'; + + $category = 'test_category'; + $message = 'test message'; + $sourceFileContent = "Yii::t('{$category}', '{$message}')"; + $this->createSourceFile($sourceFileContent); + + $this->composeConfigFile(array( + 'languages' => array($language), + 'sourcePath' => $this->sourcePath, + 'messagePath' => $this->messagePath, + )); + $this->runMessageControllerAction('index', array($this->configFileName)); + + $messageFileName = $this->messagePath . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . $category . '.php'; + + // check file not overwritten: + $messageFileContent = file_get_contents($messageFileName); + $messageFileContent .= '// some not generated by command content'; + file_put_contents($messageFileName, $messageFileContent); + + $this->runMessageControllerAction('index', array($this->configFileName)); + + $this->assertEquals($messageFileContent, file_get_contents($messageFileName)); + } + + /** + * @depends testCreateTranslation + */ + public function testMerge() + { + $language = 'en'; + $category = 'test_category'; + $messageFileName = $language . DIRECTORY_SEPARATOR . $category . '.php'; + + $existingMessage = 'test existing message'; + $existingMessageContent = 'test existing message content'; + $this->createMessageFile($messageFileName, array( + $existingMessage => $existingMessageContent + )); + + $newMessage = 'test new message'; + $sourceFileContent = "Yii::t('{$category}', '{$existingMessage}')"; + $sourceFileContent .= "Yii::t('{$category}', '{$newMessage}')"; + $this->createSourceFile($sourceFileContent); + + $this->composeConfigFile(array( + 'languages' => array($language), + 'sourcePath' => $this->sourcePath, + 'messagePath' => $this->messagePath, + 'overwrite' => true, + )); + $this->runMessageControllerAction('index', array($this->configFileName)); + + $messages = require($this->messagePath . DIRECTORY_SEPARATOR . $messageFileName); + $this->assertTrue(array_key_exists($newMessage, $messages), 'Unable to add new message!'); + $this->assertTrue(array_key_exists($existingMessage, $messages), 'Unable to keep existing message!'); + $this->assertEquals('', $messages[$newMessage], 'Wrong new message content!'); + $this->assertEquals($existingMessageContent, $messages[$existingMessage], 'Unable to keep existing message content!'); + } + + /** + * @depends testMerge + */ + public function testNoLongerNeedTranslation() + { + $language = 'en'; + $category = 'test_category'; + $messageFileName = $language . DIRECTORY_SEPARATOR . $category . '.php'; + + $oldMessage = 'test old message'; + $oldMessageContent = 'test old message content'; + $this->createMessageFile($messageFileName, array( + $oldMessage => $oldMessageContent + )); + + $sourceFileContent = "Yii::t('{$category}', 'some new message')"; + $this->createSourceFile($sourceFileContent); + + $this->composeConfigFile(array( + 'languages' => array($language), + 'sourcePath' => $this->sourcePath, + 'messagePath' => $this->messagePath, + 'overwrite' => true, + 'removeOld' => false, + )); + $this->runMessageControllerAction('index', array($this->configFileName)); + + $messages = require($this->messagePath . DIRECTORY_SEPARATOR . $messageFileName); + + $this->assertTrue(array_key_exists($oldMessage, $messages), 'No longer needed message removed!'); + $this->assertEquals('@@' . $oldMessageContent . '@@', $messages[$oldMessage], 'No longer needed message content does not marked properly!'); + } + + /** + * @depends testMerge + */ + public function testMergeWithContentZero() + { + $language = 'en'; + $category = 'test_category'; + $messageFileName = $language . DIRECTORY_SEPARATOR . $category . '.php'; + + $zeroMessage = 'test zero message'; + $zeroMessageContent = '0'; + $falseMessage = 'test false message'; + $falseMessageContent = 'false'; + $this->createMessageFile($messageFileName, array( + $zeroMessage => $zeroMessageContent, + $falseMessage => $falseMessageContent, + )); + + $newMessage = 'test new message'; + $sourceFileContent = "Yii::t('{$category}', '{$zeroMessage}')"; + $sourceFileContent .= "Yii::t('{$category}', '{$falseMessage}')"; + $sourceFileContent .= "Yii::t('{$category}', '{$newMessage}')"; + $this->createSourceFile($sourceFileContent); + + $this->composeConfigFile(array( + 'languages' => array($language), + 'sourcePath' => $this->sourcePath, + 'messagePath' => $this->messagePath, + 'overwrite' => true, + )); + $this->runMessageControllerAction('index', array($this->configFileName)); + + $messages = require($this->messagePath . DIRECTORY_SEPARATOR . $messageFileName); + $this->assertTrue($zeroMessageContent === $messages[$zeroMessage], 'Message content "0" is lost!'); + $this->assertTrue($falseMessageContent === $messages[$falseMessage], 'Message content "false" is lost!'); + } + + /** + * @depends testCreateTranslation + */ + public function testMultiplyTranslators() + { + $language = 'en'; + $category = 'test_category'; + + $translators = array( + 'Yii::t', + 'Custom::translate', + ); + + $sourceMessages = array( + 'first message', + 'second message', + ); + $sourceFileContent = ''; + foreach ($sourceMessages as $key => $message) { + $sourceFileContent .= $translators[$key] . "('{$category}', '{$message}');\n"; + } + $this->createSourceFile($sourceFileContent); + + $this->composeConfigFile(array( + 'languages' => array($language), + 'sourcePath' => $this->sourcePath, + 'messagePath' => $this->messagePath, + 'translator' => $translators, + )); + $this->runMessageControllerAction('index', array($this->configFileName)); + + $messageFileName = $this->messagePath . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . $category . '.php'; + $messages = require($messageFileName); + + foreach ($sourceMessages as $sourceMessage) { + $this->assertTrue(array_key_exists($sourceMessage, $messages)); + } + } +}