Skip to content

Commit

Permalink
Enhancement: Allow to specify new-line character
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Apr 6, 2018
1 parent c30d19d commit 4619a52
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 5 deletions.
17 changes: 13 additions & 4 deletions src/Printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ final class Printer implements PrinterInterface
*
* - turn static method into an instance method
* - allow to specify indent
* - allow to specify new-line character sequence
*
* If you observe closely, the options for un-escaping unicode characters and slashes have been removed. Since this
* package requires PHP 7, there is no need to implement this in user-land code.
Expand All @@ -35,12 +36,13 @@ final class Printer implements PrinterInterface
*
* @param string $json
* @param string $indent
* @param string $newLine
*
* @throws \InvalidArgumentException
*
* @return string
*/
public function print(string $json, string $indent = ' '): string
public function print(string $json, string $indent = ' ', string $newLine = PHP_EOL): string
{
if (null === \json_decode($json) && JSON_ERROR_NONE !== \json_last_error()) {
throw new \InvalidArgumentException(\sprintf(
Expand All @@ -56,6 +58,13 @@ public function print(string $json, string $indent = ' '): string
));
}

if (1 !== \preg_match('/^(?>\r\n|\n|\r)$/', $newLine)) {
throw new \InvalidArgumentException(\sprintf(
'"%s" is not a valid new-line character sequence.',
$newLine
));
}

$printed = '';
$indentLevel = 0;
$length = \strlen($json);
Expand Down Expand Up @@ -116,7 +125,7 @@ public function print(string $json, string $indent = ' '): string
* Output a new line after "," character and and indent the next line.
*/
if (',' === $character) {
$printed .= $character . PHP_EOL . \str_repeat($indent, $indentLevel);
$printed .= $character . $newLine . \str_repeat($indent, $indentLevel);

continue;
}
Expand All @@ -127,7 +136,7 @@ public function print(string $json, string $indent = ' '): string
if ('{' === $character || '[' === $character) {
++$indentLevel;

$printed .= $character . PHP_EOL . \str_repeat($indent, $indentLevel);
$printed .= $character . $newLine . \str_repeat($indent, $indentLevel);

continue;
}
Expand All @@ -150,7 +159,7 @@ public function print(string $json, string $indent = ' '): string
continue;
}

$printed .= PHP_EOL . \str_repeat($indent, $indentLevel);
$printed .= $newLine . \str_repeat($indent, $indentLevel);
}

$printed .= $character;
Expand Down
3 changes: 2 additions & 1 deletion src/PrinterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ interface PrinterInterface
/**
* @param string $json
* @param string $indent
* @param string $newLine
*
* @throws \InvalidArgumentException
*
* @return string
*/
public function print(string $json, string $indent = ' '): string;
public function print(string $json, string $indent = ' ', string $newLine = PHP_EOL): string;
}
108 changes: 108 additions & 0 deletions test/Unit/PrinterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,53 @@ public function providerInvalidIndent(): \Generator
}
}

/**
* @dataProvider providerInvalidNewLine
*
* @param string $newLine
*/
public function testPrintRejectsInvalidNewLine(string $newLine)
{
$json = <<<'JSON'
["Andreas M\u00f6ller","🤓","https:\/\/localheinz.com"]
JSON;
$indent = ' ';

$printer = new Printer();

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(\sprintf(
'"%s" is not a valid new-line character sequence.',
$newLine
));

$printer->print(
$json,
$indent,
$newLine
);
}

public function providerInvalidNewLine(): \Generator
{
$values = [
"\t",
" \r ",
" \r\n ",
" \n ",
' ',
"\f",
"\x0b",
"\x85",
];

foreach ($values as $value) {
yield [
$value,
];
}
}

public function testPrintPrintsPretty()
{
$json = <<<'JSON'
Expand Down Expand Up @@ -135,6 +182,67 @@ public function testPrintPrintsPrettyWithIndent()
$this->assertSame($expected, $printed);
}

/**
* @dataProvider providerNewLine
*
* @param string $newLine
*/
public function testPrintPrintsPrettyWithIndentAndNewLine(string $newLine)
{
$json = <<<'JSON'
{"name":"Andreas M\u00f6ller","emoji":"🤓","urls":["https:\/\/localheinz.com","https:\/\/github.com\/localheinz","https:\/\/twitter.com\/localheinz"]}
JSON;
$indent = ' ';

$expected = <<<'JSON'
{
"name": "Andreas M\u00f6ller",
"emoji": "🤓",
"urls": [
"https:\/\/localheinz.com",
"https:\/\/github.com\/localheinz",
"https:\/\/twitter.com\/localheinz"
]
}
JSON;

$expectedWithNewLine = \str_replace(
PHP_EOL,
$newLine,
$expected
);

$printer = new Printer();

$printed = $printer->print(
$json,
$indent,
$newLine
);

$this->assertSame($expectedWithNewLine, $printed);
}

/**
* @see https://nikic.github.io/2011/12/10/PCRE-and-newlines.html
*
* @return \Generator
*/
public function providerNewLine(): \Generator
{
$values = [
"\r\n",
"\n",
"\r",
];

foreach ($values as $key => $value) {
yield $key => [
$value,
];
}
}

public function testPrintPrintsPrettyButDoesNotUnEscapeUnicodeCharactersAndSlashes()
{
$json = <<<'JSON'
Expand Down

0 comments on commit 4619a52

Please sign in to comment.