PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/test.php

http://github.com/digitalbazaar/php-json-ld
PHP | 765 lines | 540 code | 67 blank | 158 comment | 70 complexity | 956fc58928edd9a372c3b42387f9de5e MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * PHP unit tests for JSON-LD.
  4. *
  5. * @author Dave Longley
  6. *
  7. * Copyright (c) 2013-2014 Digital Bazaar, Inc. All rights reserved.
  8. */
  9. require_once('jsonld.php');
  10. class JsonLdTestCase extends PHPUnit_Framework_TestCase {
  11. /**
  12. * Runs this test case. Overridden to attach to EARL report w/o need for
  13. * an external XML configuration file.
  14. *
  15. * @param PHPUnit_Framework_TestResult $result the test result.
  16. */
  17. public function run(PHPUnit_Framework_TestResult $result = NULL) {
  18. global $EARL;
  19. $EARL->attach($result);
  20. $this->result = $result;
  21. parent::run($result);
  22. }
  23. /**
  24. * Tests expansion.
  25. *
  26. * @param JsonLdTest $test the test to run.
  27. *
  28. * @group expand
  29. * @group json-ld.org
  30. * @dataProvider expandProvider
  31. */
  32. public function testExpand($test) {
  33. $this->test = $test;
  34. $input = $test->readUrl('input');
  35. $options = $test->createOptions();
  36. $test->run('jsonld_expand', array($input, $options));
  37. }
  38. /**
  39. * Tests compaction.
  40. *
  41. * @param JsonLdTest $test the test to run.
  42. *
  43. * @group compact
  44. * @group json-ld.org
  45. * @dataProvider compactProvider
  46. */
  47. public function testCompact($test) {
  48. $this->test = $test;
  49. $input = $test->readUrl('input');
  50. $context = $test->readProperty('context');
  51. $options = $test->createOptions();
  52. $test->run('jsonld_compact', array($input, $context, $options));
  53. }
  54. /**
  55. * Tests flatten.
  56. *
  57. * @param JsonLdTest $test the test to run.
  58. *
  59. * @group flatten
  60. * @group json-ld.org
  61. * @dataProvider flattenProvider
  62. */
  63. public function testFlatten($test) {
  64. $this->test = $test;
  65. $input = $test->readUrl('input');
  66. $context = $test->readProperty('context');
  67. $options = $test->createOptions();
  68. $test->run('jsonld_flatten', array($input, $context, $options));
  69. }
  70. /**
  71. * Tests serialization to RDF.
  72. *
  73. * @param JsonLdTest $test the test to run.
  74. *
  75. * @group toRdf
  76. * @group json-ld.org
  77. * @dataProvider toRdfProvider
  78. */
  79. public function testToRdf($test) {
  80. $this->test = $test;
  81. $input = $test->readUrl('input');
  82. $options = $test->createOptions(array('format' => 'application/nquads'));
  83. $test->run('jsonld_to_rdf', array($input, $options));
  84. }
  85. /**
  86. * Tests deserialization from RDF.
  87. *
  88. * @param JsonLdTest $test the test to run.
  89. *
  90. * @group fromRdf
  91. * @group json-ld.org
  92. * @dataProvider fromRdfProvider
  93. */
  94. public function testFromRdf($test) {
  95. $this->test = $test;
  96. $input = $test->readProperty('input');
  97. $options = $test->createOptions(array('format' => 'application/nquads'));
  98. $test->run('jsonld_from_rdf', array($input, $options));
  99. }
  100. /**
  101. * Tests framing.
  102. *
  103. * @param JsonLdTest $test the test to run.
  104. *
  105. * @group frame
  106. * @group json-ld.org
  107. * @dataProvider frameProvider
  108. */
  109. public function testFrame($test) {
  110. $this->test = $test;
  111. $input = $test->readUrl('input');
  112. $frame = $test->readProperty('frame');
  113. $options = $test->createOptions();
  114. $test->run('jsonld_frame', array($input, $frame, $options));
  115. }
  116. /**
  117. * Tests normalization.
  118. *
  119. * @param JsonLdTest $test the test to run.
  120. *
  121. * @group normalize
  122. * @group json-ld.org
  123. * @dataProvider normalizeProvider
  124. */
  125. public function testNormalize($test) {
  126. $this->test = $test;
  127. $input = $test->readUrl('input');
  128. $options = $test->createOptions(array('format' => 'application/nquads'));
  129. $test->run('jsonld_normalize', array($input, $options));
  130. }
  131. /**
  132. * Tests URGNA2012 normalization.
  133. *
  134. * @param JsonLdTest $test the test to run.
  135. *
  136. * @group normalize
  137. * @group normalization
  138. * @dataProvider urgna2012Provider
  139. */
  140. public function testUrgna2012($test) {
  141. $this->test = $test;
  142. $input = $test->readProperty('action');
  143. $options = $test->createOptions(array(
  144. 'algorithm' => 'URGNA2012',
  145. 'inputFormat' => 'application/nquads',
  146. 'format' => 'application/nquads'));
  147. $test->run('jsonld_normalize', array($input, $options));
  148. }
  149. /**
  150. * Tests URDNA2015 normalization.
  151. *
  152. * @param JsonLdTest $test the test to run.
  153. *
  154. * @group normalize
  155. * @group normalization
  156. * @dataProvider urdna2015Provider
  157. */
  158. public function testUrdna2015($test) {
  159. $this->test = $test;
  160. $input = $test->readProperty('action');
  161. $options = $test->createOptions(array(
  162. 'algorithm' => 'URDNA2015',
  163. 'inputFormat' => 'application/nquads',
  164. 'format' => 'application/nquads'));
  165. $test->run('jsonld_normalize', array($input, $options));
  166. }
  167. public function expandProvider() {
  168. return new JsonLdTestIterator('jld:ExpandTest');
  169. }
  170. public function compactProvider() {
  171. return new JsonLdTestIterator('jld:CompactTest');
  172. }
  173. public function flattenProvider() {
  174. return new JsonLdTestIterator('jld:FlattenTest');
  175. }
  176. public function toRdfProvider() {
  177. return new JsonLdTestIterator('jld:ToRDFTest');
  178. }
  179. public function fromRdfProvider() {
  180. return new JsonLdTestIterator('jld:FromRDFTest');
  181. }
  182. public function normalizeProvider() {
  183. return new JsonLdTestIterator('jld:NormalizeTest');
  184. }
  185. public function frameProvider() {
  186. return new JsonLdTestIterator('jld:FrameTest');
  187. }
  188. public function urgna2012Provider() {
  189. return new JsonLdTestIterator('rdfn:Urgna2012EvalTest');
  190. }
  191. public function urdna2015Provider() {
  192. return new JsonLdTestIterator('rdfn:Urdna2015EvalTest');
  193. }
  194. }
  195. class JsonLdManifest {
  196. public function __construct($data, $filename) {
  197. $this->data = $data;
  198. $this->filename = $filename;
  199. $this->dirname = dirname($filename);
  200. }
  201. public function load(&$tests) {
  202. $entries = array_merge(
  203. JsonLdProcessor::getValues($this->data, 'sequence'),
  204. JsonLdProcessor::getValues($this->data, 'entries'));
  205. $includes = JsonLdProcessor::getValues($this->data, 'include');
  206. foreach($includes as $include) {
  207. array_push($entries, $include . '.jsonld');
  208. }
  209. foreach($entries as $entry) {
  210. if(is_string($entry)) {
  211. $filename = join(
  212. DIRECTORY_SEPARATOR, array($this->dirname, $entry));
  213. $entry = Util::readJson($filename);
  214. } else {
  215. $filename = $this->filename;
  216. }
  217. if(JsonLdProcessor::hasValue($entry, '@type', 'mf:Manifest') ||
  218. JsonLdProcessor::hasValue($entry, 'type', 'mf:Manifest')) {
  219. // entry is another manifest
  220. $manifest = new JsonLdManifest($entry, $filename);
  221. $manifest->load($tests);
  222. } else {
  223. // assume entry is a test
  224. $test = new JsonLdTest($this, $entry, $filename);
  225. $types = array_merge(
  226. JsonLdProcessor::getValues($test->data, '@type'),
  227. JsonLdProcessor::getValues($test->data, 'type'));
  228. foreach($types as $type) {
  229. if(!isset($tests[$type])) {
  230. $tests[$type] = array();
  231. }
  232. $tests[$type][] = $test;
  233. }
  234. }
  235. }
  236. }
  237. }
  238. class JsonLdTest {
  239. public function __construct($manifest, $data, $filename) {
  240. $this->manifest = $manifest;
  241. $this->data = $data;
  242. $this->filename = $filename;
  243. $this->dirname = dirname($filename);
  244. $this->isPositive =
  245. JsonLdProcessor::hasValue(
  246. $data, '@type', 'jld:PositiveEvaluationTest') ||
  247. JsonLdProcessor::hasValue(
  248. $data, 'type', 'jld:PositiveEvaluationTest');
  249. $this->isNegative =
  250. JsonLdProcessor::hasValue(
  251. $data, '@type', 'jld:NegativeEvaluationTest') ||
  252. JsonLdProcessor::hasValue(
  253. $data, 'type', 'jld:NegativeEvaluationTest');
  254. // generate test name
  255. if(isset($manifest->data->name)) {
  256. $manifestLabel = $manifest->data->name;
  257. } else if(isset($manifest->data->label)) {
  258. $manifestLabel = $manifest->data->label;
  259. } else {
  260. $manifestLabel = 'UNNAMED';
  261. }
  262. if(isset($this->data->id)) {
  263. $testId = $this->data->id;
  264. } else {
  265. $testId = $this->data->{'@id'};
  266. }
  267. if(isset($this->data->name)) {
  268. $testLabel = $this->data->name;
  269. } else if(isset($this->data->label)) {
  270. $testLabel = $this->data->label;
  271. } else {
  272. $testLabel = 'UNNAMED';
  273. }
  274. $this->name = $manifestLabel . ' ' . $testId . ' - ' . $testLabel;
  275. // expand @id and input base
  276. if(isset($manifest->data->baseIri)) {
  277. $data->{'@id'} = ($manifest->data->baseIri .
  278. basename($manifest->filename) . $data->{'@id'});
  279. $this->base = $manifest->data->baseIri . $data->input;
  280. }
  281. }
  282. private function _getResultProperty() {
  283. if(isset($this->data->expect)) {
  284. return 'expect';
  285. } else if(isset($this->data->result)) {
  286. return 'result';
  287. } else {
  288. throw new Exception('No test result property found.');
  289. }
  290. }
  291. public function run($fn, $params) {
  292. // read expected data
  293. if($this->isNegative) {
  294. $this->expected = $this->data->expect;
  295. } else {
  296. $this->expected = $this->readProperty($this->_getResultProperty());
  297. }
  298. try {
  299. $this->actual = call_user_func_array($fn, $params);
  300. if($this->isNegative) {
  301. throw new Exception('Expected an error; one was not raised.');
  302. }
  303. PHPUnit_Framework_TestCase::assertEquals($this->expected, $this->actual);
  304. } catch(Exception $e) {
  305. // assume positive test
  306. if($this->isNegative) {
  307. $this->actual = $this->getJsonLdErrorCode($e);
  308. PHPUnit_Framework_TestCase::assertEquals(
  309. $this->expected, $this->actual);
  310. } else {
  311. throw $e;
  312. }
  313. }
  314. }
  315. public function readUrl($property) {
  316. if(!property_exists($this->data, $property)) {
  317. return null;
  318. }
  319. return $this->manifest->data->baseIri . $this->data->{$property};
  320. }
  321. public function readProperty($property) {
  322. $data = $this->data;
  323. if(!property_exists($data, $property)) {
  324. return null;
  325. }
  326. $filename = join(
  327. DIRECTORY_SEPARATOR, array($this->dirname, $data->{$property}));
  328. $extension = pathinfo($filename, PATHINFO_EXTENSION);
  329. if($extension === 'jsonld') {
  330. return Util::readJson($filename);
  331. }
  332. return Util::readFile($filename);
  333. }
  334. public function createOptions($opts=array()) {
  335. $http_options = array(
  336. 'contentType', 'httpLink', 'httpStatus', 'redirectTo');
  337. $test_options = (property_exists($this->data, 'option') ?
  338. $this->data->option : array());
  339. $options = array();
  340. foreach($test_options as $k => $v) {
  341. if(!in_array($k, $http_options)) {
  342. $options[$k] = $v;
  343. }
  344. }
  345. $options['documentLoader'] = $this->createDocumentLoader();
  346. $options = array_merge($options, $opts);
  347. if(isset($options['expandContext'])) {
  348. $filename = join(
  349. DIRECTORY_SEPARATOR, array($this->dirname, $options['expandContext']));
  350. $options['expandContext'] = Util::readJson($filename);
  351. }
  352. return $options;
  353. }
  354. public function createDocumentLoader() {
  355. $base = 'http://json-ld.org/test-suite';
  356. $test = $this;
  357. $load_locally = function($url) use ($test, $base) {
  358. $doc = (object)array(
  359. 'contextUrl' => null, 'documentUrl' => $url, 'document' => null);
  360. $options = (property_exists($test->data, 'option') ?
  361. $test->data->option : null);
  362. if($options and $url === $test->base) {
  363. if(property_exists($options, 'redirectTo') &&
  364. property_exists($options, 'httpStatus') &&
  365. $options->httpStatus >= '300') {
  366. $doc->documentUrl = ($test->manifest->data->baseIri .
  367. $options->redirectTo);
  368. } else if(property_exists($options, 'httpLink')) {
  369. $content_type = (property_exists($options, 'contentType') ?
  370. $options->contentType : null);
  371. $extension = pathinfo($url, PATHINFO_EXTENSION);
  372. if(!$content_type && $extension === 'jsonld') {
  373. $content_type = 'application/ld+json';
  374. }
  375. $link_header = $options->httpLink;
  376. if(is_array($link_header)) {
  377. $link_header = join(',', $link_header);
  378. }
  379. $link_header = jsonld_parse_link_header($link_header);
  380. if(isset($link_header['http://www.w3.org/ns/json-ld#context'])) {
  381. $link_header = $link_header['http://www.w3.org/ns/json-ld#context'];
  382. } else {
  383. $link_header = null;
  384. }
  385. if($link_header && $content_type !== 'application/ld+json') {
  386. if(is_array($link_header)) {
  387. throw new Exception('multiple context link headers');
  388. }
  389. $doc->contextUrl = $link_header->target;
  390. }
  391. }
  392. }
  393. global $ROOT_MANIFEST_DIR;
  394. if(strpos($doc->documentUrl, ':') === false) {
  395. $filename = join(
  396. DIRECTORY_SEPARATOR, array(
  397. $ROOT_MANIFEST_DIR, $doc->documentUrl));
  398. $doc->documentUrl = 'file://' . $filename;
  399. } else {
  400. $filename = join(
  401. DIRECTORY_SEPARATOR, array(
  402. $ROOT_MANIFEST_DIR, substr($doc->documentUrl, strlen($base))));
  403. }
  404. try {
  405. $doc->document = Util::readJson($filename);
  406. } catch(Exception $e) {
  407. throw new Exception('loading document failed');
  408. }
  409. return $doc;
  410. };
  411. $local_loader = function($url) use ($test, $base, $load_locally) {
  412. // always load remote-doc and non-base tests remotely
  413. if((strpos($url, $base) !== 0 && strpos($url, ':') !== false) ||
  414. $test->manifest->data->name === 'Remote document') {
  415. return call_user_func('jsonld_default_document_loader', $url);
  416. }
  417. // attempt to load locally
  418. return call_user_func($load_locally, $url);
  419. };
  420. return $local_loader;
  421. }
  422. public function getJsonLdErrorCode($err) {
  423. if($err instanceof JsonLdException) {
  424. if($err->getCode()) {
  425. return $err->getCode();
  426. }
  427. if($err->cause) {
  428. return $this->getJsonLdErrorCode($err->cause);
  429. }
  430. }
  431. return $err->getMessage();
  432. }
  433. }
  434. class JsonLdTestIterator implements Iterator {
  435. /**
  436. * The current test index.
  437. */
  438. protected $index = 0;
  439. /**
  440. * The total number of tests.
  441. */
  442. protected $count = 0;
  443. /**
  444. * Creates a TestIterator.
  445. *
  446. * @param string $type the type of tests to iterate over.
  447. */
  448. public function __construct($type) {
  449. global $TESTS;
  450. if(isset($TESTS[$type])) {
  451. $this->tests = $TESTS[$type];
  452. } else {
  453. $this->tests = array();
  454. }
  455. $this->count = count($this->tests);
  456. }
  457. /**
  458. * Gets the parameters for the next test.
  459. *
  460. * @return assoc the parameters for the next test.
  461. */
  462. public function current() {
  463. return array('test' => $this->tests[$this->index]);
  464. }
  465. /**
  466. * Gets the current test number.
  467. *
  468. * @return int the current test number.
  469. */
  470. public function key() {
  471. return $this->index;
  472. }
  473. /**
  474. * Proceeds to the next test.
  475. */
  476. public function next() {
  477. $this->index += 1;
  478. }
  479. /**
  480. * Rewinds to the first test.
  481. */
  482. public function rewind() {
  483. $this->index = 0;
  484. }
  485. /**
  486. * Returns true if there are more tests to be run.
  487. *
  488. * @return bool true if there are more tests to be run.
  489. */
  490. public function valid() {
  491. return $this->index < $this->count;
  492. }
  493. }
  494. class EarlReport extends PHPUnit_Util_Printer
  495. implements PHPUnit_Framework_TestListener {
  496. public function __construct() {
  497. $this->filename = null;
  498. $this->attached = false;
  499. $this->report = (object)array(
  500. '@context' => (object)array(
  501. 'doap' => 'http://usefulinc.com/ns/doap#',
  502. 'foaf' => 'http://xmlns.com/foaf/0.1/',
  503. 'dc' => 'http://purl.org/dc/terms/',
  504. 'earl' => 'http://www.w3.org/ns/earl#',
  505. 'xsd' => 'http://www.w3.org/2001/XMLSchema#',
  506. 'doap:homepage' => (object)array('@type' => '@id'),
  507. 'doap:license' => (object)array('@type' => '@id'),
  508. 'dc:creator' => (object)array('@type' => '@id'),
  509. 'foaf:homepage' => (object)array('@type' => '@id'),
  510. 'subjectOf' => (object)array('@reverse' => 'earl:subject'),
  511. 'earl:assertedBy' => (object)array('@type' => '@id'),
  512. 'earl:mode' => (object)array('@type' => '@id'),
  513. 'earl:test' => (object)array('@type' => '@id'),
  514. 'earl:outcome' => (object)array('@type' => '@id'),
  515. 'dc:date' => (object)array('@type' => 'xsd:date')
  516. ),
  517. '@id' => 'https://github.com/digitalbazaar/php-json-ld',
  518. '@type' => array('doap:Project', 'earl:TestSubject', 'earl:Software'),
  519. 'doap:name' => 'php-json-ld',
  520. 'dc:title' => 'php-json-ld',
  521. 'doap:homepage' => 'https://github.com/digitalbazaar/php-json-ld',
  522. 'doap:license' => 'https://github.com/digitalbazaar/php-json-ld/blob/master/LICENSE',
  523. 'doap:description' => 'A JSON-LD processor for PHP',
  524. 'doap:programming-language' => 'PHP',
  525. 'dc:creator' => 'https://github.com/dlongley',
  526. 'doap:developer' => (object)array(
  527. '@id' => 'https://github.com/dlongley',
  528. '@type' => array('foaf:Person', 'earl:Assertor'),
  529. 'foaf:name' => 'Dave Longley',
  530. 'foaf:homepage' => 'https://github.com/dlongley'
  531. ),
  532. 'dc:date' => array(
  533. '@value' => gmdate('Y-m-d'),
  534. '@type' => 'xsd:date'
  535. ),
  536. 'subjectOf' => array()
  537. );
  538. }
  539. /**
  540. * Attaches to the given test result, if not yet attached.
  541. *
  542. * @param PHPUnit_Framework_Test $result the result to attach to.
  543. */
  544. public function attach(PHPUnit_Framework_TestResult $result) {
  545. if(!$this->attached && $this->filename) {
  546. $this->attached = true;
  547. $result->addListener($this);
  548. }
  549. }
  550. /**
  551. * Adds an assertion to this EARL report.
  552. *
  553. * @param JsonLdTest $test the JsonLdTest for the assertion is for.
  554. * @param bool $passed whether or not the test passed.
  555. */
  556. public function addAssertion($test, $passed) {
  557. $this->report->{'subjectOf'}[] = (object)array(
  558. '@type' => 'earl:Assertion',
  559. 'earl:assertedBy' => $this->report->{'doap:developer'}->{'@id'},
  560. 'earl:mode' => 'earl:automatic',
  561. 'earl:test' => $test->data->{'@id'},
  562. 'earl:result' => (object)array(
  563. '@type' => 'earl:TestResult',
  564. 'dc:date' => gmdate(DateTime::ISO8601),
  565. 'earl:outcome' => $passed ? 'earl:passed' : 'earl:failed'
  566. )
  567. );
  568. return $this;
  569. }
  570. /**
  571. * Writes this EARL report to a file.
  572. */
  573. public function flush() {
  574. if($this->filename) {
  575. printf("\nWriting EARL report to: %s\n", $this->filename);
  576. $fd = fopen($this->filename, 'w');
  577. fwrite($fd, Util::jsonldEncode($this->report));
  578. fclose($fd);
  579. }
  580. }
  581. public function endTest(PHPUnit_Framework_Test $test, $time) {
  582. $this->addAssertion($test->test, true);
  583. }
  584. public function addError(
  585. PHPUnit_Framework_Test $test, Exception $e, $time) {
  586. $this->addAssertion($test->test, false);
  587. }
  588. public function addFailure(
  589. PHPUnit_Framework_Test $test,
  590. PHPUnit_Framework_AssertionFailedError $e, $time) {
  591. $this->addAssertion($test->test, false);
  592. if($test->result->shouldStop()) {
  593. if(isset($test->test->name)) {
  594. $name = $test->test->name;
  595. } else if(isset($test->test->label)) {
  596. $name = $test->test->label;
  597. } else {
  598. $name = 'UNNAMED';
  599. }
  600. printf("\n\nFAILED\n");
  601. printf("Test: %s\n", $name);
  602. printf("Purpose: %s\n", $test->test->data->purpose);
  603. printf("EXPECTED: %s\n", Util::jsonldEncode($test->test->expected));
  604. printf("ACTUAL: %s\n", Util::jsonldEncode($test->test->actual));
  605. }
  606. }
  607. public function addIncompleteTest(
  608. PHPUnit_Framework_Test $test, Exception $e, $time) {
  609. $this->addAssertion($test->test, false);
  610. }
  611. public function addRiskyTest(
  612. PHPUnit_Framework_Test $test, Exception $e, $time) {}
  613. public function addSkippedTest(
  614. PHPUnit_Framework_Test $test, Exception $e, $time) {}
  615. public function startTest(PHPUnit_Framework_Test $test) {}
  616. public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
  617. public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {}
  618. }
  619. class Util {
  620. public static function readFile($filename) {
  621. $rval = @file_get_contents($filename);
  622. if($rval === false) {
  623. throw new Exception('File read error: ' . $filename);
  624. }
  625. return $rval;
  626. }
  627. public static function readJson($filename) {
  628. $rval = json_decode(self::readFile($filename));
  629. if($rval === null) {
  630. throw new Exception('JSON parse error');
  631. }
  632. return $rval;
  633. }
  634. public static function readNQuads($filename) {
  635. return self::readFile($filename);
  636. }
  637. public static function jsonldEncode($input) {
  638. // newer PHP has a flag to avoid escaped '/'
  639. if(defined('JSON_UNESCAPED_SLASHES')) {
  640. $options = JSON_UNESCAPED_SLASHES;
  641. if(defined('JSON_PRETTY_PRINT')) {
  642. $options |= JSON_PRETTY_PRINT;
  643. }
  644. $json = json_encode($input, $options);
  645. } else {
  646. // use a simple string replacement of '\/' to '/'.
  647. $json = str_replace('\\/', '/', json_encode($input));
  648. }
  649. return $json;
  650. }
  651. }
  652. // tests to skip
  653. $SKIP_TESTS = array();
  654. // root manifest directory
  655. $ROOT_MANIFEST_DIR;
  656. // parsed tests; keyed by type
  657. $TESTS = array();
  658. // parsed command line options
  659. $OPTIONS = array();
  660. // parse command line options
  661. global $argv;
  662. $args = $argv;
  663. $total = count($args);
  664. $start = false;
  665. for($i = 0; $i < $total; ++$i) {
  666. $arg = $args[$i];
  667. if(!$start) {
  668. if(realpath($arg) === realpath(__FILE__)) {
  669. $start = true;
  670. }
  671. continue;
  672. }
  673. if($arg[0] !== '-') {
  674. break;
  675. }
  676. $i += 1;
  677. $OPTIONS[$arg] = $args[$i];
  678. }
  679. if(!isset($OPTIONS['-d'])) {
  680. $dvar = 'path to json-ld.org/test-suite';
  681. $evar = 'file to write EARL report to';
  682. echo "php-json-ld Tests\n";
  683. echo "Usage: phpunit test.php -d <$dvar> [-e <$evar>]\n\n";
  684. exit(0);
  685. }
  686. // EARL Report
  687. $EARL = new EarlReport();
  688. if(isset($OPTIONS['-e'])) {
  689. $EARL->filename = $OPTIONS['-e'];
  690. }
  691. // load root manifest
  692. $ROOT_MANIFEST_DIR = realpath($OPTIONS['-d']);
  693. $filename = join(
  694. DIRECTORY_SEPARATOR, array($ROOT_MANIFEST_DIR, 'manifest.jsonld'));
  695. $root_manifest = Util::readJson($filename);
  696. $manifest = new JsonLdManifest($root_manifest, $filename);
  697. $manifest->load($TESTS);
  698. /* end of file, omit ?> */