Skip to content
Snippets Groups Projects
Commit 0a8717f7 authored by Demian Katz's avatar Demian Katz Committed by Robert Lange
Browse files

Add replace option to CopyString command.

parent 36a563ea
No related merge requests found
......@@ -29,6 +29,7 @@ namespace VuFindConsole\Command\Language;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
......@@ -68,6 +69,18 @@ class CopyStringCommand extends AbstractCommand
'target',
InputArgument::REQUIRED,
'the target key to write ' . $note
)->addOption(
'replace',
null,
InputOption::VALUE_REQUIRED,
'string delimited by replaceDelimiter option, representing '
. "search-and-replace operation.\ne.g. textToReplace/replacementText"
)->addOption(
'replaceDelimiter',
null,
InputOption::VALUE_REQUIRED,
'delimiter used in replace option',
'/'
);
}
......@@ -90,6 +103,20 @@ class CopyStringCommand extends AbstractCommand
fclose($fHandle);
}
/**
* Apply a replacement rule, if necessary.
*
* @param string $text Text to transform
* @param array $rule Replacement rule (empty for no change; [text to replace,
* replacement] array to apply a transformation)
*
* @return string
*/
protected function applyReplaceRule(string $text, array $rule): string
{
return empty($rule) ? $text : str_replace($rule[0], $rule[1], $text);
}
/**
* Run the command.
*
......@@ -102,6 +129,9 @@ class CopyStringCommand extends AbstractCommand
{
$source = $input->getArgument('source');
$target = $input->getArgument('target');
$replace = $input->getOption('replace');
$replaceDelimiter = $input->getOption('replaceDelimiter');
$replaceRule = empty($replace) ? [] : explode($replaceDelimiter, $replace);
list($sourceDomain, $sourceKey) = $this->extractTextDomain($source);
list($targetDomain, $targetKey) = $this->extractTextDomain($target);
......@@ -114,14 +144,17 @@ class CopyStringCommand extends AbstractCommand
// First, collect the source values from the source text domain:
$sources = [];
$sourceCallback = function ($full) use ($output, $sourceKey, & $sources) {
$strings = $this->reader->getTextDomain($full, false);
if (!isset($strings[$sourceKey])) {
$output->writeln('Source key not found.');
} else {
$sources[basename($full)] = $strings[$sourceKey];
}
};
$sourceCallback
= function ($full) use ($output, $replaceRule, $sourceKey, & $sources) {
$strings = $this->reader->getTextDomain($full, false);
if (!isset($strings[$sourceKey])) {
$output->writeln('Source key not found.');
return;
}
$sources[basename($full)] = $this->applyReplaceRule(
$strings[$sourceKey], $replaceRule
);
};
$this->processDirectory($sourceDir, $sourceCallback, [$output, 'writeln']);
// Make sure that all target files exist:
......
......@@ -72,11 +72,13 @@ class CopyStringCommandTest extends \PHPUnit\Framework\TestCase
}
/**
* Test the simplest possible success case.
* Get a command mock with expectations of success.
*
* @return void
* @param string $expectedString The expected output string of the process.
*
* @return CopyStringCommand
*/
public function testSuccessWithMinimalParameters()
protected function getSuccessfulMockCommand($expectedString = 'baz')
{
$expectedPath = realpath($this->languageFixtureDir) . '/foo/en.ini';
$normalizer = $this->getMockNormalizer();
......@@ -91,8 +93,19 @@ class CopyStringCommandTest extends \PHPUnit\Framework\TestCase
->with(
$this->equalTo($expectedPath),
$this->equalTo('xyzzy'),
$this->equalTo('baz')
$this->equalTo($expectedString)
);
return $command;
}
/**
* Test the simplest possible success case.
*
* @return void
*/
public function testSuccessWithMinimalParameters()
{
$command = $this->getSuccessfulMockCommand();
$commandTester = new CommandTester($command);
$commandTester->execute(['source' => 'foo::bar', 'target' => 'foo::xyzzy']);
$this->assertEquals(
......@@ -102,6 +115,53 @@ class CopyStringCommandTest extends \PHPUnit\Framework\TestCase
$this->assertEquals(0, $commandTester->getStatusCode());
}
/**
* Test success with the replace option set.
*
* @return void
*/
public function testSuccessWithReplaceOptionAndDefaultDelimiter()
{
$command = $this->getSuccessfulMockCommand('transformed');
$commandTester = new CommandTester($command);
$commandTester->execute(
[
'source' => 'foo::bar',
'target' => 'foo::xyzzy',
'--replace' => 'baz/transformed'
]
);
$this->assertEquals(
"Processing en.ini...\nProcessing en.ini...\n",
$commandTester->getDisplay()
);
$this->assertEquals(0, $commandTester->getStatusCode());
}
/**
* Test success with the replace and replaceDelimiter options set.
*
* @return void
*/
public function testSuccessWithReplaceOptionAndCustomDelimiter()
{
$command = $this->getSuccessfulMockCommand('transformed');
$commandTester = new CommandTester($command);
$commandTester->execute(
[
'source' => 'foo::bar',
'target' => 'foo::xyzzy',
'--replace' => 'baz|transformed',
'--replaceDelimiter' => '|',
]
);
$this->assertEquals(
"Processing en.ini...\nProcessing en.ini...\n",
$commandTester->getDisplay()
);
$this->assertEquals(0, $commandTester->getStatusCode());
}
/**
* Test failure due to missing text domain.
*
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment