Skip to content

Commit 098d709

Browse files
committed
Added support for specifying the list of strings as JSON
1 parent fcb6311 commit 098d709

File tree

9 files changed

+211
-4
lines changed

9 files changed

+211
-4
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ $ ./build-regexp.phar --infile strings.txt
3737
(?:one|t(?:hree|wo))
3838
```
3939

40+
Alternatively, the list of strings can be passed as a JSON array:
41+
```
42+
$ echo '["foo","bar"]' > strings.json
43+
$ ./build-regexp.phar --infile strings.json --infile-format json
44+
(?:bar|foo)
45+
```
46+
4047
By default, the result is output in the terminal directly. Alternatively, it can be saved to a file specified via the `outfile` option. In the following example, we save the result to a `out.txt` file before checking its content:
4148
```
4249
$ ./build-regexp.phar --outfile out.txt foo bar baz

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
},
2121
"autoload-dev": {
2222
"psr-4": {
23-
"s9e\\RegexpBuilder\\Tests\\Command\\": "tests"
23+
"s9e\\RegexpBuilder\\Command\\Tests\\": "tests"
2424
}
2525
},
2626
"scripts": {

src/Build.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Console\Output\OutputInterface;
1717
use UnhandledMatchError;
1818
use s9e\RegexpBuilder\Builder;
19+
use s9e\RegexpBuilder\Command\InputFormatter\InputFormatterInterface;
1920

2021
class Build extends Command
2122
{
@@ -28,7 +29,8 @@ protected function configure(): void
2829
null,
2930
InputOption::VALUE_REQUIRED,
3031
'Regexp preset: "java", "javascript", "pcre", "raw", or "re2"',
31-
'pcre'
32+
'pcre',
33+
['java', 'javascript', 'pcre', 'raw', 're2']
3234
);
3335
$this->addOption(
3436
'flags',
@@ -49,6 +51,14 @@ protected function configure(): void
4951
InputOption::VALUE_REQUIRED,
5052
'Input file'
5153
);
54+
$this->addOption(
55+
'infile-format',
56+
null,
57+
InputOption::VALUE_REQUIRED,
58+
'Format of the input file: "json" or "lsv" (line-separated values)',
59+
'lsv',
60+
['json', 'lsv']
61+
);
5262
$this->addOption(
5363
'outfile',
5464
null,
@@ -147,7 +157,18 @@ protected function getStrings(InputInterface $input): array
147157

148158
$text = ($filepath === '-') ? $this->readStdin($input) : $this->readFile($filepath);
149159

150-
return preg_split('(\\r?\\n)', $text, -1, PREG_SPLIT_NO_EMPTY);
160+
return $this->getInputFormatter($input)->format($text);
161+
}
162+
163+
protected function getInputFormatter(InputInterface $input): InputFormatterInterface
164+
{
165+
$className = __NAMESPACE__ . '\\InputFormatter\\' . ucfirst(strtolower($input->getOption('infile-format')));
166+
if (!class_exists($className))
167+
{
168+
throw new RuntimeException('Unsupported infile-format');
169+
}
170+
171+
return new $className;
151172
}
152173

153174
protected function readFile(string $filepath): string
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @package s9e\RegexpBuilderCommand
5+
* @copyright Copyright (c) 2022 The s9e authors
6+
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
7+
*/
8+
namespace s9e\RegexpBuilder\Command\InputFormatter;
9+
10+
interface InputFormatterInterface
11+
{
12+
public function format(string $text): array;
13+
}

src/InputFormatter/Json.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @package s9e\RegexpBuilderCommand
5+
* @copyright Copyright (c) 2022 The s9e authors
6+
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
7+
*/
8+
namespace s9e\RegexpBuilder\Command\InputFormatter;
9+
10+
use RuntimeException;
11+
12+
class Json implements InputFormatterInterface
13+
{
14+
public function format(string $text): array
15+
{
16+
$values = json_decode($text);
17+
if ($values === null)
18+
{
19+
throw new RuntimeException('Input is not valid JSON');
20+
}
21+
if (!is_array($values))
22+
{
23+
throw new RuntimeException('Input is not a JSON array');
24+
}
25+
foreach ($values as $value)
26+
{
27+
if (!is_string($value))
28+
{
29+
throw new RuntimeException('Input contains non-string values');
30+
}
31+
}
32+
33+
return $values;
34+
}
35+
}

src/InputFormatter/Lsv.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @package s9e\RegexpBuilderCommand
5+
* @copyright Copyright (c) 2022 The s9e authors
6+
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
7+
*/
8+
namespace s9e\RegexpBuilder\Command\InputFormatter;
9+
10+
class Lsv implements InputFormatterInterface
11+
{
12+
public function format(string $text): array
13+
{
14+
return preg_split('(\\r?\\n)', $text, -1, PREG_SPLIT_NO_EMPTY);
15+
}
16+
}

tests/BuildTest.php

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
*/
1515
class BuildTest extends TestCase
1616
{
17-
1817
public function testWriteFile()
1918
{
2019
vfsStream::setup('root');
@@ -167,6 +166,28 @@ function (CommandTester $commandTester): void
167166
file_put_contents(vfsStream::url('root/strings.txt'), "a\nb");
168167
}
169168
],
169+
[
170+
[
171+
'--infile' => vfsStream::url('root/strings.txt'),
172+
'--infile-format' => 'lsv'
173+
],
174+
'[ab]',
175+
function (CommandTester $commandTester): void
176+
{
177+
file_put_contents(vfsStream::url('root/strings.txt'), "a\nb");
178+
}
179+
],
180+
[
181+
[
182+
'--infile' => vfsStream::url('root/strings.json'),
183+
'--infile-format' => 'json'
184+
],
185+
'[abd]',
186+
function (CommandTester $commandTester): void
187+
{
188+
file_put_contents(vfsStream::url('root/strings.json'), '["a","b","d"]');
189+
}
190+
],
170191
[
171192
[
172193
'--infile' => '-'
@@ -272,6 +293,28 @@ function ()
272293
chmod($path, 0);
273294
}
274295
],
296+
[
297+
[
298+
'--infile' => vfsStream::url('root/invalid.json'),
299+
'--infile-format' => 'json'
300+
],
301+
new RuntimeException('Input is not valid JSON'),
302+
function (): void
303+
{
304+
file_put_contents(vfsStream::url('root/invalid.json'), 'invalid');
305+
}
306+
],
307+
[
308+
[
309+
'--infile' => vfsStream::url('root/file.txt'),
310+
'--infile-format' => 'idk'
311+
],
312+
new RuntimeException('Unsupported infile-format'),
313+
function (): void
314+
{
315+
file_put_contents(vfsStream::url('root/file.txt'), '');
316+
}
317+
],
275318
];
276319
}
277320
}

tests/InputFormatter/JsonTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace s9e\RegexpBuilder\Command\Tests;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use s9e\RegexpBuilder\Command\InputFormatter\Json;
7+
8+
/**
9+
* @covers s9e\RegexpBuilder\Command\InputFormatter\Json
10+
*/
11+
class JsonTest extends TestCase
12+
{
13+
public function test()
14+
{
15+
$this->assertEquals(
16+
['foo', 'bar', 'baz'],
17+
(new Json)->format('["foo","bar","baz"]')
18+
);
19+
}
20+
21+
public function testUnicode()
22+
{
23+
$this->assertEquals(
24+
["\xF0\x9F\x98\x80"],
25+
(new Json)->format('["\\uD83D\\uDE00"]')
26+
);
27+
}
28+
29+
public function testInvalidJson()
30+
{
31+
$this->expectException('RuntimeException');
32+
$this->expectExceptionMessage('Input is not valid JSON');
33+
34+
(new Json)->format('invalid');
35+
}
36+
37+
public function testInvalidJsonType()
38+
{
39+
$this->expectException('RuntimeException');
40+
$this->expectExceptionMessage('Input is not a JSON array');
41+
42+
(new Json)->format('{"foo":"bar"}');
43+
}
44+
45+
public function testInvalidJsonValue()
46+
{
47+
$this->expectException('RuntimeException');
48+
$this->expectExceptionMessage('Input contains non-string values');
49+
50+
(new Json)->format('["foo",1]');
51+
}
52+
}

tests/InputFormatter/LsvTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace s9e\RegexpBuilder\Command\Tests;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use s9e\RegexpBuilder\Command\InputFormatter\Lsv;
7+
8+
/**
9+
* @covers s9e\RegexpBuilder\Command\InputFormatter\Lsv
10+
*/
11+
class LsvTest extends TestCase
12+
{
13+
public function test()
14+
{
15+
$this->assertEquals(
16+
['foo', 'bar', 'baz'],
17+
(new Lsv)->format("foo\nbar\r\nbaz")
18+
);
19+
}
20+
}

0 commit comments

Comments
 (0)