Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add n-triples tests and update triples function.

- triples() now returns an iterator instead of a list
- a bit of cleanup
- added docs for triples
  • Loading branch information...
commit 32a3d4322fa881061ada3f8edab5832221e33958 1 parent 2870283
@davidlehn davidlehn authored
Showing with 99 additions and 47 deletions.
  1. +1 −0  docs/index.rst
  2. +40 −28 lib/pyld/jsonld.py
  3. +58 −19 tests/TestRunner.py
View
1  docs/index.rst
@@ -20,6 +20,7 @@ API Reference
.. autofunction:: expand
.. autofunction:: frame
.. autofunction:: normalize
+.. autofunction:: triples
Indices and tables
------------------
View
68 lib/pyld/jsonld.py
@@ -15,7 +15,7 @@
__copyright__ = "Copyright (c) 2011 Digital Bazaar, Inc."
__license__ = "New BSD licence"
-__all__ = ["compact", "expand", "frame", "normalize"]
+__all__ = ["compact", "expand", "frame", "normalize", "triples"]
import copy
@@ -1738,33 +1738,6 @@ def _compareSerializations(s1, s2):
rval = _compare(s1, s2[0:len(s1)])
return rval
-
-def triples(input, callback=None):
- normalized = normalize(input)
- rval = None
-
- # normalize input
- if (callback == None):
- rval = []
- def callback(s,p,o):
- rval.append({'s':s, 'p':p, 'o':o })
- return True
-
- quit = False
- for e in normalized:
- s = e['@subject']['@iri']
- for p, obj in e.iteritems():
- if p == '@subject': continue
- if not isinstance(obj, list):
- obj = [obj]
- for o2 in obj:
- quit = callback(s, p, o2)==False
- if quit: break
- if quit: break
- if quit: break
-
- return rval
-
def normalize(input):
"""
Normalizes a JSON-LD object.
@@ -1954,3 +1927,42 @@ def frame(input, frame, options=None):
:return: the framed output.
"""
return Processor().frame(input, frame, options)
+
+def _defaultTriplesCallback(s, p, o):
+ return {'s':s, 'p':p, 'o':o}
+
+def triples(input, callback=_defaultTriplesCallback):
+ """
+ Generates triples given a JSON-LD input. Each triple that is generated
+ results in a call to the given callback. The callback takes 3 parameters:
+ subject, property, and object. If the callback returns False then this
+ method will stop generating triples and return. If the callback is null,
+ then triple objects containing "s", "p", "o" properties will be generated.
+
+ The object or "o" property will be a JSON-LD formatted object.
+
+ :param input: the JSON-LD input.
+ :param callback: the triple callback.
+ :param options: framing options to use.
+
+ :return: an iterator of triples.
+ """
+ normalized = normalize(input)
+
+ quit = False
+ for e in normalized:
+ s = e['@subject']['@iri']
+ for p, obj in e.iteritems():
+ if p == '@subject': continue
+ if not isinstance(obj, list):
+ obj = [obj]
+ for o2 in obj:
+ triple = callback(s, p, o2)
+ quit = (triple == False)
+ if quit:
+ break
+ else:
+ yield triple
+ if quit: break
+ if quit: break
+
View
77 tests/TestRunner.py
@@ -14,6 +14,20 @@
from pyld import jsonld
##
+# jsonld.triples callback to create ntriples lines
+def _ntriple(s, p, o):
+ if isinstance(o, basestring):
+ # simple literal
+ return "<%s> <%s> \"%s\" ." % (s, p, o)
+ elif "@iri" in o:
+ # object is an IRI
+ return "<%s> <%s> <%s> ." % (s, p, o["@iri"])
+ else:
+ # object is a literal
+ return "<%s> <%s> \"%s\"^^<%s> ." % \
+ (s, p, o["@literal"], o["@datatype"])
+
+##
# TestRunner unit testing class.
# Loads test files and runs groups of tests.
class TestRunner:
@@ -106,41 +120,66 @@ def main(self):
count += 1
# open the input and expected result json files
- inputFd = open(join(self.testdir, test['input']))
- expectFd = open(join(self.testdir, test['expect']))
- inputJson = json.load(inputFd)
- expectJson = json.load(expectFd)
-
- resultJson = None
+ inputFile = open(join(self.testdir, test['input']))
+ expectFile = open(join(self.testdir, test['expect']))
+ inputJson = json.load(inputFile)
+ expectType = os.path.splitext(test['expect'])[1][1:]
+ if expectType == 'json':
+ expect = json.load(expectFile)
+ elif expectType == 'nt':
+ # read, strip non-data lines, stripe front/back whitespace, and sort
+ # FIXME: only handling strict nt format here
+ expectLines = []
+ for line in expectFile.readlines():
+ line = line.strip()
+ if len(line) == 0 or line[0] == '#':
+ continue
+ expectLines.append(line)
+ expect = '\n'.join(sorted(expectLines))
+
+ result = None
testType = test['type']
if testType == 'normalize':
- resultJson = jsonld.normalize(inputJson)
+ result = jsonld.normalize(inputJson)
elif testType == 'expand':
- resultJson = jsonld.expand(inputJson)
+ result = jsonld.expand(inputJson)
elif testType == 'compact':
- contextFd = open(join(self.testdir, test['context']))
- contextJson = json.load(contextFd)
- resultJson = jsonld.compact(contextJson, inputJson)
+ contextFile = open(join(self.testdir, test['context']))
+ contextJson = json.load(contextFile)
+ result = jsonld.compact(contextJson, inputJson)
elif testType == 'frame':
- frameFd = open(join(self.testdir, test['frame']))
- frameJson = json.load(frameFd)
- resultJson = jsonld.frame(inputJson, frameJson)
+ frameFile = open(join(self.testdir, test['frame']))
+ frameJson = json.load(frameFile)
+ result = jsonld.frame(inputJson, frameJson)
+ elif testType == 'triples':
+ result = '\n'.join(
+ sorted(jsonld.triples(inputJson, callback=_ntriple)))
else:
print "Unknown test type."
# check the expected value against the test result
- if expectJson == resultJson:
+ if expect == result:
passed += 1
print 'PASS'
if self.options.verbose:
- print 'Expect:', json.dumps(expectJson, indent=4)
- print 'Result:', json.dumps(resultJson, indent=4)
+ print 'Expect:', json.dumps(expect, indent=4)
+ print 'Result:',
+ if expectType == 'json':
+ print json.dumps(result, indent=4)
+ else:
+ print
+ print result
else:
failed += 1
print 'FAIL'
- print 'Expect:', json.dumps(expectJson, indent=4)
- print 'Result:', json.dumps(resultJson, indent=4)
+ print 'Expect:', json.dumps(expect, indent=4)
+ print 'Result:',
+ if expectType == 'json':
+ print json.dumps(result, indent=4)
+ else:
+ print
+ print result
print "Tests run: %d, Tests passed: %d, Tests Failed: %d" % (run, passed, failed)
Please sign in to comment.
Something went wrong with that request. Please try again.