Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/main/php/text/json/Format.class.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php namespace text\json;

use StdClass, Traversable;
use io\Blob;
use lang\{IllegalArgumentException, Value};

/**
Expand All @@ -9,9 +10,9 @@
* @test text.json.unittest.FormatFactoryTest
*/
abstract class Format implements Value {
const ESCAPE_SLASHES = -65; // ~JSON_UNESCAPED_SLASHES
const ESCAPE_UNICODE = -257; // ~JSON_UNESCAPED_UNICODE
const ESCAPE_ENTITIES = 11; // JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT
const ESCAPE_SLASHES= -65; // ~JSON_UNESCAPED_SLASHES
const ESCAPE_UNICODE= -257; // ~JSON_UNESCAPED_UNICODE
const ESCAPE_ENTITIES= 11; // JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT

public static $DEFAULT;
public $comma, $colon, $options;
Expand Down Expand Up @@ -130,8 +131,14 @@ public function tokensOf($value) {
yield 'true';
} else if (false === $value) {
yield 'false';
} else if ($value instanceof JsonObject || $value instanceof StdClass) {
} else if ($value instanceof StdClass) {
goto map;
} else if ($value instanceof Blob) {
yield '"';
foreach ($value as $bytes) {
yield substr(json_encode($bytes), 1, -1);
}
yield '"';
} else if ($value instanceof Traversable) {
$i= 0;
$map= null;
Expand Down
22 changes: 22 additions & 0 deletions src/test/php/text/json/unittest/JsonOutputTest.class.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php namespace text\json\unittest;

use ArrayIterator;
use io\Blob;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires XP 12.9+ but composer.json still reads:

  "require" : {
    "xp-framework/core": "^12.0 | ^11.0 | ^10.0",
    "php" : ">=7.4.0"
  },

We could backport this class to XP 11; or we rewrite the tests to work without the Blob class.

use lang\IllegalArgumentException;
use test\{Assert, After, Before, Expect, Test, Values};
use text\json\Types;
Expand Down Expand Up @@ -55,6 +56,16 @@ private function generators() {
yield ['{"key":"value"}', function() { yield 'key' => 'value'; }];
}

/** @return iterable */
private function blobs() {
yield ['""', new Blob()];
yield ['"Test"', new Blob(['Test'])];
yield ['"Test \"the\" west"', new Blob(['Test', ' "the" ', 'west'])];
yield ['"Test\t"', new Blob(['Test', "\t"])];
yield ['"Tested"', new Blob(['Test', 'ed'])];
yield ['"Tested"', new Blob((function() { yield 'Test'; yield 'ed'; })())];
}

#[Before]
public function usePrecision() {
self::$precision= ini_set('precision', 14);
Expand Down Expand Up @@ -147,6 +158,17 @@ public function write_generator($expected, $write) {
Assert::equals($expected, $this->write($write()));
}

#[Test, Values(from: 'blobs')]
public function write_blob($expected, $write) {
Assert::equals($expected, $this->write($write));
}

/** @see https://bugs.php.net/bug.php?id=77069 */
#[Test, Runtime(php: '>=7.4.14')]
public function write_encoded_blob() {
Assert::equals('"VGVzdA=="', $this->write((new Blob('Test'))->encoded('convert.base64-encode')));
}

#[Test, Expect(IllegalArgumentException::class)]
public function cannot_write_closures() {
$this->write(function() { });
Expand Down
Loading