forked from friendica/php-json-ld
Rename @literal to @value, bug fixes, use json-ld.org test-suite.
This commit is contained in:
parent
9b87179143
commit
c091c4cc7b
124
jsonld-tests.php
124
jsonld-tests.php
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* @author Dave Longley
|
||||
*
|
||||
* Copyright (c) 2011 Digital Bazaar, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2012 Digital Bazaar, Inc. All rights reserved.
|
||||
*/
|
||||
require_once('jsonld.php');
|
||||
|
||||
|
@ -192,11 +192,11 @@ class TestRunner
|
|||
public function load($filepath)
|
||||
{
|
||||
global $eol;
|
||||
$tests = array();
|
||||
$manifests = array();
|
||||
|
||||
// get full path
|
||||
$filepath = realpath($filepath);
|
||||
echo "Reading test files from: '$filepath'$eol";
|
||||
echo "Reading manifest files from: '$filepath'$eol";
|
||||
|
||||
// read each test file from the directory
|
||||
$files = array();
|
||||
|
@ -220,13 +220,15 @@ class TestRunner
|
|||
foreach($files as $file)
|
||||
{
|
||||
$info = pathinfo($file);
|
||||
if($info['extension'] == 'test')
|
||||
// FIXME: hackish, manifests are now JSON-LD
|
||||
if(strstr($info['basename'], 'manifest') !== false and
|
||||
$info['extension'] == 'jsonld')
|
||||
{
|
||||
echo "Reading test file: '$file'$eol";
|
||||
echo "Reading manifest file: '$file'$eol";
|
||||
|
||||
try
|
||||
{
|
||||
$test = json_decode(file_get_contents($file));
|
||||
$manifest = json_decode(file_get_contents($file));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
|
@ -234,108 +236,80 @@ class TestRunner
|
|||
throw $e;
|
||||
}
|
||||
|
||||
if(!isset($test->filepath))
|
||||
{
|
||||
$test->filepath = $filepath;
|
||||
}
|
||||
$tests[] = $test;
|
||||
$manifest->filepath = $filepath;
|
||||
$manifests[] = $manifest;
|
||||
}
|
||||
}
|
||||
|
||||
echo count($tests) . " test file(s) read.$eol";
|
||||
echo count($manifests) . " manifest file(s) read.$eol";
|
||||
|
||||
return $tests;
|
||||
return $manifests;
|
||||
}
|
||||
|
||||
public function run($tests, $filepath='jsonld')
|
||||
public function run($manifests)
|
||||
{
|
||||
/* Test format:
|
||||
/* Manifest format:
|
||||
{
|
||||
group: <optional group name>,
|
||||
tests: [{
|
||||
name: <optional manifest name>,
|
||||
sequence: [{
|
||||
'name': <test name>,
|
||||
'type': <type of test>,
|
||||
'@type': ["test:TestCase", "jld:<type of test>"],
|
||||
'input': <input file for test>,
|
||||
'context': <context file for add context test type>,
|
||||
'frame': <frame file for frame test type>,
|
||||
'expect': <expected result file>,
|
||||
}]
|
||||
}
|
||||
|
||||
If 'group' is present, then 'tests' must be present and list all of the
|
||||
tests in the group. If 'group' is not present then 'name' must be present
|
||||
as well as 'input' and 'expect'. Groups may be embedded.
|
||||
*/
|
||||
|
||||
global $eol;
|
||||
|
||||
foreach($tests as $test)
|
||||
foreach($manifests as $manifest)
|
||||
{
|
||||
if(isset($test->group))
|
||||
$this->group($manifest->name);
|
||||
$filepath = $manifest->filepath;
|
||||
|
||||
foreach($manifest->sequence as $test)
|
||||
{
|
||||
$this->group($test->group);
|
||||
$this->run($test->tests, $test->filepath);
|
||||
$this->ungroup();
|
||||
}
|
||||
else if(!isset($test->name))
|
||||
{
|
||||
throw new Exception(
|
||||
'"group" or "name" must be specified in test file.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->test($test->name);
|
||||
|
||||
$type = $test->type;
|
||||
|
||||
if($type === 'triples')
|
||||
// read test input files
|
||||
$indent = 2;
|
||||
$type = $test->{'@type'};
|
||||
if(in_array('jld:NormalizeTest', $type))
|
||||
{
|
||||
echo "SKIP$eol";
|
||||
continue;
|
||||
$indent = 0;
|
||||
$input = _readTestJson($test->input, $filepath);
|
||||
$test->expect = _readTestJson($test->expect, $filepath);
|
||||
$result = jsonld_normalize($input);
|
||||
}
|
||||
|
||||
// use parent test filepath as necessary
|
||||
if(!isset($test->filepath))
|
||||
else if(in_array('jld:ExpandTest', $type))
|
||||
{
|
||||
$test->filepath = realpath($filepath);
|
||||
$input = _readTestJson($test->input, $filepath);
|
||||
$test->expect = _readTestJson($test->expect, $filepath);
|
||||
$result = jsonld_expand($input);
|
||||
}
|
||||
|
||||
// read test files
|
||||
$input = _readTestJson($test->input, $test->filepath);
|
||||
$test->expect = _readTestJson($test->expect, $test->filepath);
|
||||
if(isset($test->context))
|
||||
else if(in_array('jld:CompactTest', $type))
|
||||
{
|
||||
$test->context = _readTestJson($test->context, $test->filepath);
|
||||
$input = _readTestJson($test->input, $filepath);
|
||||
$test->context = _readTestJson($test->context, $filepath);
|
||||
$test->expect = _readTestJson($test->expect, $filepath);
|
||||
$result = jsonld_compact($test->context->{'@context'}, $input);
|
||||
}
|
||||
if(isset($test->frame))
|
||||
else if(in_array('jld:FrameTest', $type))
|
||||
{
|
||||
$test->frame = _readTestJson($test->frame, $test->filepath);
|
||||
}
|
||||
|
||||
// perform test
|
||||
if($type === 'normalize')
|
||||
{
|
||||
$input = jsonld_normalize($input);
|
||||
}
|
||||
else if($type === 'expand')
|
||||
{
|
||||
$input = jsonld_expand($input);
|
||||
}
|
||||
else if($type === 'compact')
|
||||
{
|
||||
$input = jsonld_compact($test->context, $input);
|
||||
}
|
||||
else if($type === 'frame')
|
||||
{
|
||||
$input = jsonld_frame($input, $test->frame);
|
||||
$input = _readTestJson($test->input, $filepath);
|
||||
$test->frame = _readTestJson($test->frame, $filepath);
|
||||
$test->expect = _readTestJson($test->expect, $filepath);
|
||||
$result = jsonld_frame($input, $test->frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unknown test type: '$type'");
|
||||
echo 'Skipping test "' . $test->name . '" of type: ' .
|
||||
json_encode($type) . $eol;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check results (only indent output on non-normalize tests)
|
||||
$this->check($test->expect, $input, $test->type !== 'normalize');
|
||||
$this->test($test->name);
|
||||
$this->check($test->expect, $result, $indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
85
jsonld.php
85
jsonld.php
|
@ -58,44 +58,34 @@ function jsonld_compact($ctx, $input)
|
|||
// fully expand input
|
||||
$input = jsonld_expand($input);
|
||||
|
||||
if(is_array($input))
|
||||
{
|
||||
$rval = array();
|
||||
$tmp = $input;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp = array($input);
|
||||
}
|
||||
|
||||
// merge context if it is an array
|
||||
if(is_array($ctx))
|
||||
{
|
||||
$ctx = jsonld_merge_contexts(new stdClass, $ctx);
|
||||
}
|
||||
|
||||
foreach($tmp as $value)
|
||||
// setup output context
|
||||
$ctxOut = new stdClass();
|
||||
|
||||
// compact
|
||||
$p = new JsonLdProcessor();
|
||||
$rval = $out = $p->compact(_clone($ctx), null, $input, $ctxOut);
|
||||
|
||||
// add context if used
|
||||
if(count(array_keys((array)$ctxOut)) > 0)
|
||||
{
|
||||
// setup output context
|
||||
$ctxOut = new stdClass();
|
||||
|
||||
// compact
|
||||
$p = new JsonLdProcessor();
|
||||
$out = $p->compact(_clone($ctx), null, $value, $ctxOut);
|
||||
|
||||
// add context if used
|
||||
if(count(array_keys((array)$ctxOut)) > 0)
|
||||
$rval = new stdClass();
|
||||
$rval->{'@context'} = $ctxOut;
|
||||
if(is_array($out))
|
||||
{
|
||||
$out->{'@context'} = $ctxOut;
|
||||
}
|
||||
|
||||
if($rval === null)
|
||||
{
|
||||
$rval = $out;
|
||||
$rval->{_getKeywords($ctxOut)->{'@id'}} = $out;
|
||||
}
|
||||
else
|
||||
{
|
||||
$rval[] = $out;
|
||||
foreach($out as $k => $v)
|
||||
{
|
||||
$rval->{$k} = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -255,7 +245,20 @@ function jsonld_frame($input, $frame, $options=null)
|
|||
// apply context
|
||||
if($ctx !== null and $rval !== null)
|
||||
{
|
||||
$rval = jsonld_compact($ctx, $rval);
|
||||
// preserve top-level array by compacting individual entries
|
||||
if(is_array($rval))
|
||||
{
|
||||
$tmp = $rval;
|
||||
$rval = array();
|
||||
foreach($tmp as $value)
|
||||
{
|
||||
$rval[] = jsonld_compact($ctx, $value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$rval = jsonld_compact($ctx, $rval);
|
||||
}
|
||||
}
|
||||
|
||||
return $rval;
|
||||
|
@ -384,7 +387,7 @@ function _getKeywords($ctx)
|
|||
$rval = (object)array(
|
||||
'@id' => '@id',
|
||||
'@language' => '@language',
|
||||
'@literal' => '@literal',
|
||||
'@value' => '@value',
|
||||
'@type' => '@type'
|
||||
);
|
||||
|
||||
|
@ -674,10 +677,10 @@ function _isSubject($value)
|
|||
|
||||
// Note: A value is a subject if all of these hold true:
|
||||
// 1. It is an Object.
|
||||
// 2. It is not a literal.
|
||||
// 2. It is not a literal (@value).
|
||||
// 3. It has more than 1 key OR any existing key is not '@id'.
|
||||
if($value !== null and is_object($value) and
|
||||
!property_exists($value, '@literal'))
|
||||
!property_exists($value, '@value'))
|
||||
{
|
||||
$keyCount = count(get_object_vars($value));
|
||||
$rval = ($keyCount > 1 or !property_exists($value, '@id'));
|
||||
|
@ -796,10 +799,10 @@ function _compareObjects($o1, $o2)
|
|||
}
|
||||
else
|
||||
{
|
||||
$rval = _compareObjectKeys($o1, $o2, '@literal');
|
||||
$rval = _compareObjectKeys($o1, $o2, '@value');
|
||||
if($rval === 0)
|
||||
{
|
||||
if(property_exists($o1, '@literal'))
|
||||
if(property_exists($o1, '@value'))
|
||||
{
|
||||
$rval = _compareObjectKeys($o1, $o2, '@type');
|
||||
if($rval === 0)
|
||||
|
@ -845,12 +848,12 @@ function _compareBlankNodeObjects($a, $b)
|
|||
/*
|
||||
3. For each property, compare sorted object values.
|
||||
3.1. The bnode with fewer objects is first.
|
||||
3.2. For each object value, compare only literals and non-bnodes.
|
||||
3.2. For each object value, compare only literals (@values) and non-bnodes.
|
||||
3.2.1. The bnode with fewer non-bnodes is first.
|
||||
3.2.2. The bnode with a string object is first.
|
||||
3.2.3. The bnode with the alphabetically-first string is first.
|
||||
3.2.4. The bnode with a @literal is first.
|
||||
3.2.5. The bnode with the alphabetically-first @literal is first.
|
||||
3.2.4. The bnode with a @value is first.
|
||||
3.2.5. The bnode with the alphabetically-first @value is first.
|
||||
3.2.6. The bnode with the alphabetically-first @type is first.
|
||||
3.2.7. The bnode with a @language is first.
|
||||
3.2.8. The bnode with the alphabetically-first @language is first.
|
||||
|
@ -1031,7 +1034,7 @@ function _flatten($parent, $parentProperty, $value, $subjects)
|
|||
else if(is_object($value))
|
||||
{
|
||||
// already-expanded value or special-case reference-only @type
|
||||
if(property_exists($value, '@literal') or $parentProperty === '@type')
|
||||
if(property_exists($value, '@value') or $parentProperty === '@type')
|
||||
{
|
||||
$flattened = _clone($value);
|
||||
}
|
||||
|
@ -1427,9 +1430,9 @@ class JsonLdProcessor
|
|||
{
|
||||
$rval = $value->{'@id'};
|
||||
}
|
||||
else if(property_exists($value, '@literal'))
|
||||
else if(property_exists($value, '@value'))
|
||||
{
|
||||
$rval = $value->{'@literal'};
|
||||
$rval = $value->{'@value'};
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1604,7 +1607,7 @@ class JsonLdProcessor
|
|||
{
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
$rval->{'@literal'} = '' . $value;
|
||||
$rval->{'@value'} = '' . $value;
|
||||
}
|
||||
}
|
||||
// nothing to coerce
|
||||
|
@ -2030,7 +2033,7 @@ class JsonLdProcessor
|
|||
// literal
|
||||
else
|
||||
{
|
||||
$rval .= '"' . $obj->{'@literal'} . '"';
|
||||
$rval .= '"' . $obj->{'@value'} . '"';
|
||||
|
||||
// type literal
|
||||
if(property_exists($obj, '@type'))
|
||||
|
|
Loading…
Reference in a new issue