diff --git a/jsonld-tests.php b/jsonld-tests.php index 111d445..7c98f3f 100644 --- a/jsonld-tests.php +++ b/jsonld-tests.php @@ -8,19 +8,27 @@ */ require_once('jsonld.php'); +// determine EOL for output based on command line php or webpage php +$isCli = defined('STDIN'); +$eol = $isCli ? "\n" : '
'; + function error_handler($errno, $errstr, $errfile, $errline) { - echo "
$errstr
"; + global $eol; + echo "$eol$errstr$eol"; array_walk( debug_backtrace(), create_function( '$a,$b', 'echo "{$a[\'function\']}()' . - '(".basename($a[\'file\']).":{$a[\'line\']});
";')); + '(".basename($a[\'file\']).":{$a[\'line\']}); ' . $eol . '";')); throw new Exception(); return false; } -set_error_handler('error_handler'); +if(!$isCli) +{ + set_error_handler('error_handler'); +} function _sortKeys($obj) { @@ -78,6 +86,7 @@ function _stringifySorted($obj, $indent) function _readTestJson($file, $filepath) { $rval; + global $eol; try { @@ -86,7 +95,7 @@ function _readTestJson($file, $filepath) } catch(Exception $e) { - echo "Exception while parsing file: '$file'
"; + echo "Exception while parsing file: '$file'$eol"; throw $e; } @@ -144,6 +153,8 @@ class TestRunner public function check($expect, $result, $indent=false) { + global $eol; + // sort and use given indent level $expect = _stringifySorted($expect, $indent); $result = _stringifySorted($result, $indent); @@ -159,18 +170,18 @@ class TestRunner $fail = true; } - echo $line . '
'; + echo "$line$eol"; if($fail) { - echo 'Expect: ' . print_r($expect, true) . '
'; - echo 'Result: ' . print_r($result, true) . '
'; + echo 'Expect: ' . print_r($expect, true) . $eol; + echo 'Result: ' . print_r($result, true) . $eol; /* $flags = JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT; echo 'Legible Expect: ' . - json_encode(json_decode(expect, $flags)) . '
'; + json_encode(json_decode(expect, $flags)) . $eol; echo 'Legible Result: ' . - json_encode(json_decode(result, $flags)) . '
'; + json_encode(json_decode(result, $flags)) . $eol; */ // FIXME: remove me @@ -180,11 +191,12 @@ class TestRunner public function load($filepath) { + global $eol; $tests = array(); // get full path $filepath = realpath($filepath); - echo "Reading test files from: '$filepath'
"; + echo "Reading test files from: '$filepath'$eol"; // read each test file from the directory $files = array(); @@ -210,7 +222,7 @@ class TestRunner $info = pathinfo($file); if($info['extension'] == 'test') { - echo "Reading test file: '$file'
"; + echo "Reading test file: '$file'$eol"; try { @@ -218,7 +230,7 @@ class TestRunner } catch(Exception $e) { - echo "Exception while parsing file: '$file'
"; + echo "Exception while parsing file: '$file'$eol"; throw $e; } @@ -230,7 +242,7 @@ class TestRunner } } - echo count($tests) . ' test file(s) read.
'; + echo count($tests) . " test file(s) read.$eol"; return $tests; } @@ -324,6 +336,6 @@ $tr = new TestRunner(); $tr->group('JSON-LD'); $tr->run($tr->load('tests')); $tr->ungroup(); -echo 'All tests complete.
'; +echo "All tests complete.$eol"; ?> diff --git a/jsonld.php b/jsonld.php index 9277536..92459b4 100644 --- a/jsonld.php +++ b/jsonld.php @@ -912,7 +912,7 @@ function _expand($ctx, $property, $value, $expandSubjects) $coerce = _getCoerceType($ctx, $property, null); // automatic coercion for basic JSON types - if($coerce === null and !is_string($value) && + if($coerce === null and !is_string($value) and (is_numeric($value) or is_bool($value))) { if(is_bool($value)) @@ -1019,8 +1019,8 @@ function _compare($v1, $v2) /** * Compares two keys in an object. If the key exists in one object - * and not the other, that object is less. If the key exists in both objects, - * then the one with the lesser value is less. + * and not the other, the object with the key is less. If the key exists in + * both objects, then the one with the lesser value is less. * * @param o1 the first object. * @param o2 the second object. @@ -1298,16 +1298,6 @@ function _flatten($parent, $parentProperty, $value, $subjects) { _flatten($parent, $parentProperty, $v, $subjects); } - - // if value is a list of objects, sort them - if(count($value) > 0 and - (is_string($value[0]) or - (is_object($value[0]) and - (isset($value[0]->{'@literal'}) or isset($value[0]->{'@iri'}))))) - { - // sort values - usort($value, '_compareObjects'); - } } else if(is_object($value)) { @@ -1899,7 +1889,7 @@ class JsonLdProcessor { $rval .= '|'; } - if(is_object($obj) and isset($obj->{'@iri'}) && + if(is_object($obj) and isset($obj->{'@iri'}) and _isBlankNodeIri($obj->{'@iri'})) { $rval .= '_:'; @@ -2424,6 +2414,18 @@ function _isType($input, $frame) return $rval; } +/** + * Filters non-keywords. + * + * @param e the element to check. + * + * @return true if the element is a non-keyword. + */ +function _filterNonKeyWords($e) +{ + return strpos($e, '@') !== 0; +} + /** * Returns true if the given input matches the given frame via duck-typing. * @@ -2440,7 +2442,7 @@ function _isDuckType($input, $frame) if(!isset($frame->{JSONLD_RDF_TYPE})) { // get frame properties that must exist on input - $props = array_keys((array)$frame); + $props = array_filter(array_keys((array)$frame), '_filterNonKeywords'); if(count($props) === 0) { // input always matches if there are no properties @@ -2485,6 +2487,10 @@ function _frame($subjects, $input, $frame, $embeds, $options) { $rval = array(); $frames = $frame; + if(count($frames) == 0) + { + $frames[] = new stdClass(); + } } else { @@ -2510,10 +2516,18 @@ function _frame($subjects, $input, $frame, $embeds, $options) $v = array(); for($n = 0; $n < $inLen and $limit !== 0; ++$n) { - // add input to list if it matches frame specific type or duck-type - if(_isType($input[$n], $frame) or _isDuckType($input[$n], $frame)) + // dereference input if it refers to a subject + $next = $input[$n]; + if(is_object($next) and isset($next->{'@iri'}) and + isset($subjects->{$next->{'@iri'}})) { - $v[] = $input[$n]; + $next = $subjects->{$next->{'@iri'}}; + } + + // add input to list if it matches frame specific type or duck-type + if(_isType($next, $frame) or _isDuckType($next, $frame)) + { + $v[] = $next; --$limit; } }