Skip to content

Commit

Permalink
Merge pull request #1512 from DannyvdSluijs/add-justin-rainbow-json-s…
Browse files Browse the repository at this point in the history
…chema

Add PHP justinrainbow/json-schema implementation
  • Loading branch information
Julian committed Sep 10, 2024
2 parents 2e03793 + e3bcc65 commit 584c631
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ updates:
schedule:
interval: "daily"

- package-ecosystem: "composer"
directory: "/implementations/php-justinrainbow-json-schema"
schedule:
interval: "daily"

- package-ecosystem: "cargo"
directory: "/implementations/rust-jsonschema"
schedule:
Expand Down Expand Up @@ -242,6 +247,11 @@ updates:
schedule:
interval: "daily"

- package-ecosystem: "docker"
directory: "/implementations/php-justinrainbow-json-schema"
schedule:
interval: "daily"

- package-ecosystem: "docker"
directory: "/implementations/python-fastjsonschema"
schedule:
Expand Down
1 change: 1 addition & 0 deletions implementations/php-justinrainbow-json-schema/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/vendor
19 changes: 19 additions & 0 deletions implementations/php-justinrainbow-json-schema/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM composer:2.7 AS builder

WORKDIR /usr/src/json-schema

COPY ./src ./src
COPY ./bootstrap.php .
COPY composer.* .
RUN composer install --no-dev --no-scripts --no-interaction --prefer-dist --optimize-autoloader
RUN composer dump-autoload --no-dev --optimize --classmap-authoritative

FROM php:8.3-alpine

WORKDIR /usr/src/json-schema

COPY ./src ./src
COPY ./bootstrap.php .
COPY --from=builder /usr/src/json-schema/vendor /usr/src/json-schema/vendor

CMD ["php", "bootstrap.php"]
14 changes: 14 additions & 0 deletions implementations/php-justinrainbow-json-schema/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

use JsonRainbow\TestHarness;

ini_set('display_errors', 'stderr');
require_once 'vendor/autoload.php';

$in = fopen('php://stdin', 'rb');
$out = fopen('php://stdout', 'wb');
$debug = fopen('php://stderr', 'wb');
$testHarness = new TestHarness($in, $out, $debug);
$testHarness();
33 changes: 33 additions & 0 deletions implementations/php-justinrainbow-json-schema/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "justinrainbow/bowtie-json-schema-test-harness",
"description": "These sources contains the test harness implementation for Bowtie",
"license": "MIT",
"require": {
"justinrainbow/json-schema": "dev-master"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.10"
},
"autoload": {
"psr-4": {
"JsonRainbow\\": "./src"
}
},
"config": {
"lock": false,
"sort-packages": true
},
"scripts": {
"code-style": "phpcs . --ignore=*/vendor/* --standard=PSR12",
"build-container": "docker build . -t localhost/php-justinrainbow-json-schema",
"run-interactive-container": "docker run --rm -it localhost/php-justinrainbow-json-schema",
"run-suite-draft3": "bowtie suite -i localhost/php-justinrainbow-json-schema https://github.com/json-schema-org/JSON-Schema-Test-Suite/tree/main/tests/draft3",
"run-suite-draft4": "bowtie suite -i localhost/php-justinrainbow-json-schema https://github.com/json-schema-org/JSON-Schema-Test-Suite/tree/main/tests/draft4"
},
"scripts-descriptions": {
"build-container": "Build the container imsage using Docker.",
"run-interactive-container": "Run the container interactivly",
"run-suite-draft3": "Run the test suite for draft-3 againt the test harness",
"run-suite-draft4": "Run the test suite for draft-4 againt the test harness"
}
}
140 changes: 140 additions & 0 deletions implementations/php-justinrainbow-json-schema/src/TestHarness.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

declare(strict_types=1);

namespace JsonRainbow;

use Composer\InstalledVersions;
use JsonSchema\Constraints\Factory;
use JsonSchema\SchemaStorage;
use JsonSchema\Validator;
use RuntimeException;
use stdClass;
use Throwable;

class TestHarness
{
private mixed $in;
private mixed $out;
private mixed $debug;

public function __construct($in, $out, $debug)
{
get_resource_type($in) !== 'stream' && throw new RuntimeException('Param #1 $in must be a stream');
get_resource_type($out) !== 'stream' && throw new RuntimeException('Param #2 $out must be a stream');
get_resource_type($debug) !== 'stream' && throw new RuntimeException('Param #3 $debug must be a stream');

$this->in = $in;
$this->out = $out;
$this->debug = $debug;
}

public function __invoke(): void
{
$this->debug('Test harness is being invoked');

while (true) {
$next = fgets($this->in);
if ($next === false || $next === '') {
throw new RuntimeException('Unable to read from input');
}
$request = json_decode($next, false, 512, JSON_THROW_ON_ERROR);

$response = match ($request->cmd) {
'start' => $this->start($request),
'stop' => $this->stop(),
'dialect' => $this->dialect(),
'run' => $this->run($request),
default => [
'seq' => $request->seq,
'results' => [[
'errored' => true,
'context' => [
'message' => sprintf('Received unsupported command: %s', $request->cmd),
],
]],
],
};

fwrite($this->out, json_encode($response, JSON_THROW_ON_ERROR) . PHP_EOL);
}
}

private function start(stdClass $request): array
{
if ($request->version !== 1) {
throw new RuntimeException('Unsupported IHOP version');
}

$this->debug(
'Starting with justinrainbow/json-schema version %s',
InstalledVersions::getVersion('justinrainbow/json-schema')
);

return [
'version' => 1,
'implementation' => [
'language' => 'php',
'name' => 'justinrainbow-json-schema',
'version' => InstalledVersions::getVersion('justinrainbow/json-schema'),
'homepage' => 'https://github.com/jsonrainbow/json-schema',
'documentation' => 'https://github.com/jsonrainbow/json-schema/wiki',
'source' => 'https://github.com/jsonrainbow/json-schema',
'issues' => 'https://github.com/jsonrainbow/json-schema/issues',
'dialects' => [
'http://json-schema.org/draft-04/schema#',
'http://json-schema.org/draft-03/schema#',
],
'os' => PHP_OS,
'os_version' => php_uname('r'),
'language_version' => PHP_VERSION,
],
];
}

private function stop(): never
{
$this->debug('Stopping test harness');
exit(0);
}

private function dialect(): array
{
return ['ok' => true];
}

private function run(stdClass $request): array
{
$this->debug('Running test case');

$schemaStorage = new SchemaStorage();
$validator = new Validator(new Factory($schemaStorage));

$results = [];

foreach ($request->case->tests as $test) {
$schemaStorage->addSchema('internal://mySchema', $test);
try {
$validator->validate(
$test->instance,
$request->case->schema
);
$results[] = ['valid' => $validator->isValid()];
} catch (Throwable $e) {
$results[] = [
'errored' => true,
'context' => [
'message' => $e->getMessage(),
'traceback' => $e->getTraceAsString(),
],
];
}
}
return ['seq' => $request->seq, 'results' => $results];
}

private function debug(string $format, ...$values): void
{
fwrite($this->debug, sprintf($format, ...$values) . PHP_EOL);
}
}

0 comments on commit 584c631

Please sign in to comment.