MessageControllerTest.php 11.2 KB
Newer Older
1 2 3 4 5 6 7 8
<?php

use yiiunit\TestCase;
use yii\console\controllers\MessageController;

/**
 * Unit test for [[\yii\console\controllers\MessageController]].
 * @see MessageController
9 10
 *
 * @group console
11 12 13 14 15 16 17 18 19
 */
class MessageControllerTest extends TestCase
{
	protected $sourcePath = '';
	protected $messagePath = '';
	protected $configFileName = '';

	public function setUp()
	{
Qiang Xue committed
20
		$this->mockApplication();
21 22
		$this->sourcePath = Yii::getAlias('@yiiunit/runtime/test_source');
		$this->createDir($this->sourcePath);
23 24 25
		if (!file_exists($this->sourcePath)) {
			$this->markTestIncomplete('Unit tests runtime directory should have writable permissions!');
		}
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
		$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()
	{
Alexander Makarov committed
89
		$module = $this->getMock('yii\\base\\Module', ['fake'], ['console']);
90 91 92
		$messageController = new MessageController('message', $module);
		$messageController->interactive = false;
		return $messageController;
93 94 95 96 97 98 99 100
	}

	/**
	 * 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.
	 */
Alexander Makarov committed
101
	protected function runMessageControllerAction($actionId, array $args = [])
102 103 104 105
	{
		$controller = $this->createMessageController();
		ob_start();
		ob_implicit_flush(false);
Qiang Xue committed
106
		$controller->run($actionId, $args);
107 108 109 110
		return ob_get_clean();
	}

	/**
Qiang Xue committed
111
	 * Creates message command config file named as [[configFileName]].
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
	 * @param array $config message command config.
	 */
	protected function composeConfigFile(array $config)
	{
		if (file_exists($this->configFileName)) {
			unlink($this->configFileName);
		}
		$fileContent = '<?php return ' . var_export($config, true) . ';';
		file_put_contents($this->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.
	 */
Alexander Makarov committed
141
	protected function createMessageFile($name, array $messages = [])
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
	{
		$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 = '<?php return ' . var_export($messages, true) . ';';
		file_put_contents($fileName, $fileContent);
	}

	// Tests:

158
	public function testActionConfig()
159
	{
160
		$configFileName = $this->configFileName;
Alexander Makarov committed
161
		$this->runMessageControllerAction('config', [$configFileName]);
162
		$this->assertTrue(file_exists($configFileName), 'Unable to create config file template!');
163 164 165 166
	}

	public function testConfigFileNotExist()
	{
167
		$this->setExpectedException('yii\\console\\Exception');
Alexander Makarov committed
168
		$this->runMessageControllerAction('extract', ['not_existing_file.php']);
169 170 171 172 173 174 175 176
	}

	public function testCreateTranslation()
	{
		$language = 'en';

		$category = 'test_category';
		$message = 'test message';
177
		$sourceFileContent = "Yii::t('{$category}', '{$message}')";
178 179
		$this->createSourceFile($sourceFileContent);

Alexander Makarov committed
180 181
		$this->composeConfigFile([
			'languages' => [$language],
182 183
			'sourcePath' => $this->sourcePath,
			'messagePath' => $this->messagePath,
Alexander Makarov committed
184 185
		]);
		$this->runMessageControllerAction('extract', [$this->configFileName]);
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

		$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);

Alexander Makarov committed
207 208
		$this->composeConfigFile([
			'languages' => [$language],
209 210
			'sourcePath' => $this->sourcePath,
			'messagePath' => $this->messagePath,
Alexander Makarov committed
211 212
		]);
		$this->runMessageControllerAction('extract', [$this->configFileName]);
213 214 215 216 217 218 219 220

		$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);

Alexander Makarov committed
221
		$this->runMessageControllerAction('extract', [$this->configFileName]);
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

		$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';
Alexander Makarov committed
237
		$this->createMessageFile($messageFileName, [
238
			$existingMessage => $existingMessageContent
Alexander Makarov committed
239
		]);
240 241 242 243 244 245

		$newMessage = 'test new message';
		$sourceFileContent = "Yii::t('{$category}', '{$existingMessage}')";
		$sourceFileContent .= "Yii::t('{$category}', '{$newMessage}')";
		$this->createSourceFile($sourceFileContent);

Alexander Makarov committed
246 247
		$this->composeConfigFile([
			'languages' => [$language],
248 249 250
			'sourcePath' => $this->sourcePath,
			'messagePath' => $this->messagePath,
			'overwrite' => true,
Alexander Makarov committed
251 252
		]);
		$this->runMessageControllerAction('extract', [$this->configFileName]);
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

		$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';
Alexander Makarov committed
272
		$this->createMessageFile($messageFileName, [
273
			$oldMessage => $oldMessageContent
Alexander Makarov committed
274
		]);
275 276 277 278

		$sourceFileContent = "Yii::t('{$category}', 'some new message')";
		$this->createSourceFile($sourceFileContent);

Alexander Makarov committed
279 280
		$this->composeConfigFile([
			'languages' => [$language],
281 282 283
			'sourcePath' => $this->sourcePath,
			'messagePath' => $this->messagePath,
			'overwrite' => true,
284
			'removeUnused' => false,
Alexander Makarov committed
285 286
		]);
		$this->runMessageControllerAction('extract', [$this->configFileName]);
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306

		$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';
Alexander Makarov committed
307
		$this->createMessageFile($messageFileName, [
308 309
			$zeroMessage => $zeroMessageContent,
			$falseMessage => $falseMessageContent,
Alexander Makarov committed
310
		]);
311 312 313 314 315 316 317

		$newMessage = 'test new message';
		$sourceFileContent = "Yii::t('{$category}', '{$zeroMessage}')";
		$sourceFileContent .= "Yii::t('{$category}', '{$falseMessage}')";
		$sourceFileContent .= "Yii::t('{$category}', '{$newMessage}')";
		$this->createSourceFile($sourceFileContent);

Alexander Makarov committed
318 319
		$this->composeConfigFile([
			'languages' => [$language],
320 321 322
			'sourcePath' => $this->sourcePath,
			'messagePath' => $this->messagePath,
			'overwrite' => true,
Alexander Makarov committed
323 324
		]);
		$this->runMessageControllerAction('extract', [$this->configFileName]);
325 326 327 328 329 330 331 332 333 334 335 336 337 338

		$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';

Alexander Makarov committed
339
		$translators = [
340 341
			'Yii::t',
			'Custom::translate',
Alexander Makarov committed
342
		];
343

Alexander Makarov committed
344
		$sourceMessages = [
345 346
			'first message',
			'second message',
Alexander Makarov committed
347
		];
348 349 350 351 352 353
		$sourceFileContent = '';
		foreach ($sourceMessages as $key => $message) {
			$sourceFileContent .= $translators[$key] . "('{$category}', '{$message}');\n";
		}
		$this->createSourceFile($sourceFileContent);

Alexander Makarov committed
354 355
		$this->composeConfigFile([
			'languages' => [$language],
356 357 358
			'sourcePath' => $this->sourcePath,
			'messagePath' => $this->messagePath,
			'translator' => $translators,
Alexander Makarov committed
359 360
		]);
		$this->runMessageControllerAction('extract', [$this->configFileName]);
361 362 363 364 365 366 367 368 369

		$messageFileName = $this->messagePath . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . $category . '.php';
		$messages = require($messageFileName);

		foreach ($sourceMessages as $sourceMessage) {
			$this->assertTrue(array_key_exists($sourceMessage, $messages));
		}
	}
}