PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/core/src/test/java/com/github/jsonldjava/core/JSONLDProcessorTest.java

http://github.com/tristan/jsonld-java
Java | 547 lines | 458 code | 33 blank | 56 comment | 113 complexity | 5ed3c37b904f28504ade4b4ff1c59cf3 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. package com.github.jsonldjava.core;
  2. import static org.junit.Assert.assertFalse;
  3. import static org.junit.Assert.assertNotNull;
  4. import static org.junit.Assert.assertTrue;
  5. import java.io.BufferedReader;
  6. import java.io.File;
  7. import java.io.FileInputStream;
  8. import java.io.FileOutputStream;
  9. import java.io.FilenameFilter;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.io.InputStreamReader;
  13. import java.io.OutputStreamWriter;
  14. import java.net.URISyntaxException;
  15. import java.text.SimpleDateFormat;
  16. import java.util.ArrayList;
  17. import java.util.Arrays;
  18. import java.util.Collection;
  19. import java.util.Collections;
  20. import java.util.Date;
  21. import java.util.Iterator;
  22. import java.util.LinkedHashMap;
  23. import java.util.List;
  24. import java.util.Map;
  25. import org.junit.AfterClass;
  26. import org.junit.BeforeClass;
  27. import org.junit.Test;
  28. import org.junit.runner.RunWith;
  29. import org.junit.runners.Parameterized;
  30. import org.junit.runners.Parameterized.Parameters;
  31. import com.fasterxml.jackson.core.JsonGenerationException;
  32. import com.fasterxml.jackson.databind.JsonMappingException;
  33. import com.github.jsonldjava.impl.TurtleTripleCallback;
  34. import com.github.jsonldjava.utils.JSONUtils;
  35. @RunWith(Parameterized.class)
  36. public class JSONLDProcessorTest {
  37. private static final String TEST_DIR = "json-ld.org";
  38. private static Map<String, Object> REPORT;
  39. private static List<Object> REPORT_GRAPH;
  40. private static String ASSERTOR = "http://tristan.github.com/foaf#me";
  41. @BeforeClass
  42. public static void prepareReportFrame() {
  43. REPORT = new LinkedHashMap<String, Object>() {
  44. {
  45. // context
  46. put("@context", new LinkedHashMap<String, Object>() {
  47. {
  48. put("@vocab", "http://www.w3.org/ns/earl#");
  49. put("foaf", "http://xmlns.com/foaf/0.1/");
  50. put("earl", "http://www.w3.org/ns/earl#");
  51. put("doap", "http://usefulinc.com/ns/doap#");
  52. put("dc", "http://purl.org/dc/terms/");
  53. put("xsd", "http://www.w3.org/2001/XMLSchema#");
  54. put("foaf:homepage", new LinkedHashMap<String, Object>() {
  55. {
  56. put("@type", "@id");
  57. }
  58. });
  59. put("doap:homepage", new LinkedHashMap<String, Object>() {
  60. {
  61. put("@type", "@id");
  62. }
  63. });
  64. }
  65. });
  66. put("@graph", new ArrayList<Object>() {
  67. {
  68. // asserter
  69. add(new LinkedHashMap<String, Object>() {
  70. {
  71. put("@id", "http://tristan.github.com/foaf#me");
  72. put("@type", new ArrayList<Object>() {
  73. {
  74. add("foaf:Person");
  75. add("earl:Assertor");
  76. }
  77. });
  78. put("foaf:name", "Tristan King");
  79. put("foaf:title", "Implementor");
  80. put("foaf:homepage", "http://tristan.github.com");
  81. }
  82. });
  83. // project
  84. add(new LinkedHashMap<String, Object>() {
  85. {
  86. put("@id", "http://github.com/jsonld-java/jsonld-java");
  87. put("@type", new ArrayList<Object>() {
  88. {
  89. add("doap:Project");
  90. add("earl:TestSubject");
  91. add("earl:Software");
  92. }
  93. });
  94. put("doap:name", "JSONLD-Java");
  95. put("doap:homepage", "http://github.com/jsonld-java/jsonld-java");
  96. put("doap:description", new LinkedHashMap<String, Object>() {
  97. {
  98. put("@value",
  99. "An Implementation of the JSON-LD Specification for Java");
  100. put("@language", "en");
  101. }
  102. });
  103. put("doap:programming-language", "Java");
  104. put("doap:developer", new ArrayList<Object>() {
  105. {
  106. add(new LinkedHashMap<String, Object>() {
  107. {
  108. put("@id", "http://tristan.github.com/foaf#me");
  109. }
  110. });
  111. add(new LinkedHashMap<String, Object>() {
  112. {
  113. put("@id", "https://github.com/ansell/foaf#me");
  114. put("foaf:name", "Peter Ansell");
  115. put("foaf:title", "Contributor");
  116. }
  117. });
  118. }
  119. });
  120. put("doap:title", "JSONLD-Java");
  121. put("dc:date", new LinkedHashMap<String, Object>() {
  122. {
  123. put("@type", "xsd:date");
  124. put("@value", "2013-05-16");
  125. }
  126. });
  127. put("dc:creator", new LinkedHashMap<String, Object>() {
  128. {
  129. put("@id", "http://tristan.github.com/foaf#me");
  130. }
  131. });
  132. }
  133. });
  134. }
  135. });
  136. }
  137. };
  138. REPORT_GRAPH = (List<Object>) REPORT.get("@graph");
  139. }
  140. private static final String reportOutputFile = "reports/report";
  141. @AfterClass
  142. public static void writeReport() throws JsonGenerationException, JsonMappingException,
  143. IOException, JSONLDProcessingError {
  144. // Only write reports if "-Dreport.format=..." is set
  145. String reportFormat = System.getProperty("report.format");
  146. if (reportFormat != null) {
  147. reportFormat = reportFormat.toLowerCase();
  148. } else {
  149. return; // nothing to do
  150. }
  151. if ("application/ld+json".equals(reportFormat) || "jsonld".equals(reportFormat)
  152. || "*".equals(reportFormat)) {
  153. System.out.println("Generating JSON-LD Report");
  154. JSONUtils.writePrettyPrint(new OutputStreamWriter(new FileOutputStream(reportOutputFile
  155. + ".jsonld")), REPORT);
  156. }
  157. if ("text/plain".equals(reportFormat) || "nquads".equals(reportFormat)
  158. || "nq".equals(reportFormat) || "nt".equals(reportFormat)
  159. || "ntriples".equals(reportFormat) || "*".equals(reportFormat)) {
  160. System.out.println("Generating Nquads Report");
  161. final Options options = new Options("") {
  162. {
  163. this.format = "application/nquads";
  164. }
  165. };
  166. final String rdf = (String) JSONLD.toRDF(REPORT, options);
  167. final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(
  168. reportOutputFile + ".nq"));
  169. writer.write(rdf);
  170. writer.close();
  171. }
  172. if ("text/turtle".equals(reportFormat) || "turtle".equals(reportFormat)
  173. || "ttl".equals(reportFormat) || "*".equals(reportFormat)) { // write
  174. // turtle
  175. System.out.println("Generating Turtle Report");
  176. final Options options = new Options("") {
  177. {
  178. format = "text/turtle";
  179. useNamespaces = true;
  180. }
  181. };
  182. final String rdf = (String) JSONLD.toRDF(REPORT, new TurtleTripleCallback(), options);
  183. final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(
  184. reportOutputFile + ".ttl"));
  185. writer.write(rdf);
  186. writer.close();
  187. }
  188. }
  189. @Parameters(name = "{0}{1}")
  190. public static Collection<Object[]> data() throws URISyntaxException, IOException {
  191. // TODO: look into getting the test data from github, which will help
  192. // more
  193. // with keeping up to date with the spec.
  194. // perhaps use http://develop.github.com/p/object.html
  195. // to pull info from
  196. // https://github.com/json-ld/json-ld.org/tree/master/test-suite/tests
  197. final ClassLoader cl = Thread.currentThread().getContextClassLoader();
  198. final File f = new File(cl.getResource(TEST_DIR).toURI());
  199. final List<File> manifestfiles = Arrays.asList(f.listFiles(new FilenameFilter() {
  200. @Override
  201. public boolean accept(File dir, String name) {
  202. if (name.contains("manifest") && name.endsWith(".jsonld")) {
  203. // System.out.println("Using manifest: " + dir + " "
  204. // + name);
  205. return true;
  206. }
  207. return false;
  208. }
  209. }));
  210. final Collection<Object[]> rdata = new ArrayList<Object[]>();
  211. final int count = 0;
  212. for (final File in : manifestfiles) {
  213. // System.out.println("Reading: " + in.getCanonicalPath());
  214. final FileInputStream manifestfile = new FileInputStream(in);
  215. final Map<String, Object> manifest = (Map<String, Object>) JSONUtils
  216. .fromInputStream(manifestfile);
  217. for (final Map<String, Object> test : (List<Map<String, Object>>) manifest
  218. .get("sequence")) {
  219. final List<String> testType = (List<String>) test.get("@type");
  220. if (
  221. // "#t0001".equals(test.get("@id")) &&
  222. testType.contains("jld:ExpandTest") || testType.contains("jld:CompactTest")
  223. || testType.contains("jld:FlattenTest")
  224. || testType.contains("jld:FrameTest") || testType.contains("jld:ToRDFTest")
  225. || testType.contains("jld:NormalizeTest")
  226. || testType.contains("jld:FromRDFTest")) {
  227. // System.out.println("Adding test: " + test.get("name"));
  228. rdata.add(new Object[] {
  229. (String) manifest.get("baseIri") + (String) manifest.get("name")
  230. + "-manifest.jsonld", test.get("@id"), test });
  231. } else {
  232. // TODO: many disabled while implementation is incomplete
  233. // System.out.println("Skipping test: " + test.get("name"));
  234. }
  235. // Uncomment this to print a list of all the tests (may make
  236. // debugging easier
  237. // System.out.println("Added Test[" + count++ + "]: " +
  238. // testgroup.get("group") + " " + test.get("name") + "..."
  239. // + " (" + test.get("input") + "," + test.get("expect") + ")"
  240. // );
  241. }
  242. }
  243. return rdata;
  244. }
  245. private final String group;
  246. private final Map<String, Object> test;
  247. public JSONLDProcessorTest(final String group, final String id, final Map<String, Object> test) {
  248. this.group = group;
  249. this.test = test;
  250. }
  251. public static String join(Collection<String> list, String delim) {
  252. final StringBuilder builder = new StringBuilder();
  253. final Iterator<String> iter = list.iterator();
  254. while (iter.hasNext()) {
  255. builder.append(iter.next());
  256. if (!iter.hasNext()) {
  257. break;
  258. }
  259. builder.append(delim);
  260. }
  261. return builder.toString();
  262. }
  263. @Test
  264. public void runTest() throws URISyntaxException, IOException, JSONLDProcessingError {
  265. // System.out.println("running test: " + group + test.get("@id") +
  266. // " :: " + test.get("name"));
  267. final ClassLoader cl = Thread.currentThread().getContextClassLoader();
  268. final List<String> testType = (List<String>) test.get("@type");
  269. final String inputFile = (String) test.get("input");
  270. final InputStream inputStream = cl.getResourceAsStream(TEST_DIR + "/" + inputFile);
  271. assertNotNull("unable to find input file: " + test.get("input"), inputStream);
  272. final String inputType = inputFile.substring(inputFile.lastIndexOf(".") + 1);
  273. Object input = null;
  274. if (inputType.equals("jsonld")) {
  275. input = JSONUtils.fromInputStream(inputStream);
  276. } else if (inputType.equals("nt") || inputType.equals("nq")) {
  277. final List<String> inputLines = new ArrayList<String>();
  278. final BufferedReader buf = new BufferedReader(new InputStreamReader(inputStream,
  279. "UTF-8"));
  280. String line;
  281. while ((line = buf.readLine()) != null) {
  282. line = line.trim();
  283. if (line.length() == 0 || line.charAt(0) == '#') {
  284. continue;
  285. }
  286. inputLines.add(line);
  287. }
  288. // Collections.sort(inputLines);
  289. input = join(inputLines, "\n");
  290. }
  291. Object expect = null;
  292. String sparql = null;
  293. Boolean failure_expected = false;
  294. final String expectFile = (String) test.get("expect");
  295. final String sparqlFile = (String) test.get("sparql");
  296. if (expectFile != null) {
  297. final InputStream expectStream = cl.getResourceAsStream(TEST_DIR + "/" + expectFile);
  298. if (expectStream == null && testType.contains("jld:NegativeEvaluationTest")) {
  299. // in the case of negative evaluation tests the expect field can
  300. // be a description of what should happen
  301. expect = expectFile;
  302. failure_expected = true;
  303. } else if (expectStream == null) {
  304. assertFalse("Unable to find expect file: " + expectFile, true);
  305. } else {
  306. final String expectType = expectFile.substring(expectFile.lastIndexOf(".") + 1);
  307. if (expectType.equals("jsonld")) {
  308. expect = JSONUtils.fromInputStream(expectStream);
  309. } else if (expectType.equals("nt") || expectType.equals("nq")) {
  310. final List<String> expectLines = new ArrayList<String>();
  311. final BufferedReader buf = new BufferedReader(new InputStreamReader(
  312. expectStream, "UTF-8"));
  313. String line;
  314. while ((line = buf.readLine()) != null) {
  315. line = line.trim();
  316. if (line.length() == 0 || line.charAt(0) == '#') {
  317. continue;
  318. }
  319. expectLines.add(line);
  320. }
  321. Collections.sort(expectLines);
  322. expect = join(expectLines, "\n");
  323. } else {
  324. expect = "";
  325. assertFalse("Unknown expect type: " + expectType, true);
  326. }
  327. }
  328. } else if (sparqlFile != null) {
  329. final InputStream sparqlStream = cl.getResourceAsStream(TEST_DIR + "/" + sparqlFile);
  330. assertNotNull("unable to find expect file: " + sparqlFile, sparqlStream);
  331. final BufferedReader buf = new BufferedReader(new InputStreamReader(sparqlStream,
  332. "UTF-8"));
  333. String buffer = null;
  334. while ((buffer = buf.readLine()) != null) {
  335. sparql += buffer + "\n";
  336. }
  337. } else if (testType.contains("jld:NegativeEvaluationTest")) {
  338. // TODO: this is hacky, but works for the limited number of negative
  339. // evaluation tests that are currently present
  340. failure_expected = true;
  341. } else {
  342. assertFalse("Nothing to expect from this test, thus nothing to test if it works", true);
  343. }
  344. Object result = null;
  345. final Options options = new Options("http://json-ld.org/test-suite/tests/"
  346. + test.get("input"));
  347. try {
  348. if (testType.contains("jld:NormalizeTest")) {
  349. options.format = "application/nquads";
  350. result = JSONLD.normalize(input, options);
  351. result = ((String) result).trim();
  352. } else if (testType.contains("jld:ExpandTest")) {
  353. result = JSONLD.expand(input, options);
  354. } else if (testType.contains("jld:CompactTest")) {
  355. final InputStream contextStream = cl.getResourceAsStream(TEST_DIR + "/"
  356. + test.get("context"));
  357. final Object contextJson = JSONUtils.fromInputStream(contextStream);
  358. result = JSONLD.compact(input, contextJson, options);
  359. } else if (testType.contains("jld:FlattenTest")) {
  360. if (test.containsKey("context")) {
  361. final InputStream contextStream = cl.getResourceAsStream(TEST_DIR + "/"
  362. + test.get("context"));
  363. final Object contextJson = JSONUtils.fromInputStream(contextStream);
  364. result = JSONLD.flatten(input, contextJson, options);
  365. } else {
  366. result = JSONLD.flatten(input, options);
  367. }
  368. } else if (testType.contains("jld:FrameTest")) {
  369. final InputStream frameStream = cl.getResourceAsStream(TEST_DIR + "/"
  370. + test.get("frame"));
  371. final Map<String, Object> frameJson = (Map<String, Object>) JSONUtils
  372. .fromInputStream(frameStream);
  373. result = JSONLD.frame(input, frameJson, options);
  374. } else if (testType.contains("jld:ToRDFTest")) {
  375. options.format = "application/nquads";
  376. result = JSONLD.toRDF(input, options);
  377. result = ((String) result).trim();
  378. } else if (testType.contains("jld:FromRDFTest")) {
  379. // result = JSONLD.fromRDF(input, new NQuadJSONLDSerializer());
  380. result = JSONLD.fromRDF(input, options);
  381. } else if (testType.contains("jld:SimplifyTest")) {
  382. result = JSONLD.simplify(input, options);
  383. } else {
  384. assertFalse("Unknown test type", true);
  385. }
  386. } catch (final JSONLDProcessingError e) {
  387. result = e;
  388. }
  389. Boolean testpassed = false;
  390. try {
  391. // TODO: for tests that are supposed to fail, a more detailed check
  392. // that it failed in the right way is needed
  393. testpassed = JSONUtils.equals(expect, result) || failure_expected;
  394. if (testpassed == false) {
  395. // System.out.println("failed test!!! details:");
  396. // jsonDiff("/", expect, result);
  397. // Map<String,Object> pp = new LinkedHashMap<String, Object>();
  398. // pp.put("expected", expect);
  399. // pp.put("result", result);
  400. // System.out.println("{\"expected\": " +
  401. // JSONUtils.toString(expect) + "\n,\"result\": " +
  402. // JSONUtils.toString(result) + "}");
  403. // JSONUtils.writePrettyPrint(new
  404. // OutputStreamWriter(System.out), pp);
  405. }
  406. } catch (final Exception e) {
  407. e.printStackTrace();
  408. }
  409. // write details to report
  410. final String manifest = this.group;
  411. final String id = (String) this.test.get("@id");
  412. final Date d = new Date();
  413. final String dateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(d);
  414. String zone = new SimpleDateFormat("Z").format(d);
  415. zone = zone.substring(0, 3) + ":" + zone.substring(3);
  416. final String dateTimeZone = dateTime + zone;
  417. final Boolean passed = testpassed;
  418. REPORT_GRAPH.add(new LinkedHashMap<String, Object>() {
  419. {
  420. put("@type", "earl:Assertion");
  421. put("earl:assertedBy", new LinkedHashMap<String, Object>() {
  422. {
  423. put("@id", ASSERTOR);
  424. }
  425. });
  426. put("earl:subject", new LinkedHashMap<String, Object>() {
  427. {
  428. put("@id", "http://github.com/jsonld-java/jsonld-java");
  429. }
  430. });
  431. put("earl:test", new LinkedHashMap<String, Object>() {
  432. {
  433. put("@id", manifest + id);
  434. }
  435. });
  436. put("earl:result", new LinkedHashMap<String, Object>() {
  437. {
  438. put("@type", "earl:TestResult");
  439. put("earl:outcome", passed ? "earl:passed" : "earl:failed");
  440. put("dc:date", new LinkedHashMap<String, Object>() {
  441. {
  442. put("@value", dateTimeZone);
  443. put("@type", "xsd:dateTime");
  444. }
  445. });
  446. }
  447. });
  448. // for error expand the correct error is thrown, but the test
  449. // suite doesn't yet automatically figure that out.
  450. put("earl:mode", "http://json-ld.org/test-suite/tests/error-expand-manifest.jsonld"
  451. .equals(manifest) ? "earl:semiAuto" : "earl:automatic");
  452. }
  453. });
  454. assertTrue(
  455. "\nFailed test: " + group + test.get("@id") + " " + test.get("name") + " ("
  456. + test.get("input") + "," + test.get("expect") + ")\n" + "expected: "
  457. + JSONUtils.toString(expect) + "\nresult: " + JSONUtils.toString(result),
  458. testpassed);
  459. }
  460. /**
  461. * compares the expected and resulting objects and prints out differences of
  462. * the two
  463. *
  464. * @param parent
  465. * @param expect
  466. * @param result
  467. */
  468. private void jsonDiff(String parent, Object expect, Object result) {
  469. if (expect == null) {
  470. if (result != null) {
  471. System.out.println(parent + " expected null, got: " + result);
  472. }
  473. } else if (expect instanceof Map && result instanceof Map) {
  474. final Map<String, Object> e = (Map<String, Object>) expect;
  475. final Map<String, Object> r = (Map<String, Object>) JSONLDUtils.clone(result);
  476. for (final String k : e.keySet()) {
  477. if (r.containsKey(k)) {
  478. jsonDiff(parent + "/" + k, e.get(k), r.remove(k));
  479. } else {
  480. System.out.println(parent + " result missing key: " + k);
  481. }
  482. }
  483. for (final String k : r.keySet()) {
  484. System.out.println(parent + " result has extra key: " + k);
  485. }
  486. }
  487. // List diffs are hard if we aren't strict with array ordering!
  488. else if (expect instanceof List && result instanceof List) {
  489. final List<Object> e = (List<Object>) expect;
  490. final List<Object> r = (List<Object>) JSONLDUtils.clone(result);
  491. if (e.size() != r.size()) {
  492. System.out.println(parent + " results are not the same size");
  493. }
  494. int i = 0;
  495. for (final Object o : e) {
  496. final int j = r.indexOf(o);
  497. if (j < 0) {
  498. System.out.println(parent + " result missing value at index: " + i);
  499. } else {
  500. r.remove(j);
  501. }
  502. i++;
  503. }
  504. for (final Object o : r) {
  505. System.out.println(parent + " result has extra items");
  506. }
  507. } else {
  508. if (expect != null && !expect.equals(result)) {
  509. System.out.println(parent + " results are not equal: \"" + expect + "\" != \""
  510. + result + "\"");
  511. }
  512. }
  513. }
  514. }