Rename @literal to @value, bug fixes, use json-ld.org test-suite.

This commit is contained in:
Dave Longley 2012-01-11 22:56:26 -05:00
parent 9b87179143
commit c091c4cc7b
2 changed files with 93 additions and 116 deletions

View file

@ -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);
}
}
}

View file

@ -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'))