convert to print_function, and start adding unicode_literals future as well
[htsworkflow.git] / htsworkflow / util / test / test_rdfhelp.py
1 from __future__ import print_function, unicode_literals
2
3 import os
4 import types
5 from unittest import TestCase
6
7 from datetime import datetime
8
9 from htsworkflow.util.rdfhelp import \
10      add_default_schemas, \
11      blankOrUri, \
12      dcNS, \
13      dump_model, \
14      fromTypedNode, \
15      get_model, \
16      guess_parser, \
17      guess_parser_by_extension, \
18      load_string_into_model, \
19      owlNS, \
20      rdfNS, \
21      rdfsNS, \
22      remove_schemas, \
23      toTypedNode, \
24      strip_namespace, \
25      simplify_uri, \
26      sanitize_literal, \
27      xsdNS
28
29 try:
30     import RDF
31
32     class TestRDFHelp(TestCase):
33         def test_from_none(self):
34           self.assertEqual(fromTypedNode(None), None)
35
36         def test_typed_node_boolean(self):
37             node = toTypedNode(True)
38             self.assertIn(node.literal_value['string'], (u'1', u'true'))
39             self.assertEqual(str(node.literal_value['datatype']),
40                                  'http://www.w3.org/2001/XMLSchema#boolean')
41
42         def test_bad_boolean(self):
43             node = RDF.Node(literal='bad', datatype=xsdNS['boolean'].uri)
44             # older versions of librdf ~< 1.0.16 left the literal
45             # alone. and thus should fail the fromTypedNode call
46             # newer versions coerced the odd value to false.
47             try:
48                 self.assertFalse(fromTypedNode(node))
49             except ValueError as e:
50                 pass
51
52         def test_typed_node_string(self):
53             node = toTypedNode('hello')
54             self.assertEqual(node.literal_value['string'], u'hello')
55             self.assertTrue(node.literal_value['datatype'] is None)
56
57         def test_typed_real_like(self):
58             num = 3.14
59             node = toTypedNode(num)
60             self.assertEqual(fromTypedNode(node), num)
61
62         def test_typed_integer(self):
63             num = 3
64             node = toTypedNode(num)
65             self.assertEqual(fromTypedNode(node), num)
66             self.assertEqual(type(fromTypedNode(node)), type(num))
67
68         def test_typed_node_string(self):
69             s = "Argh matey"
70             node = toTypedNode(s)
71             self.assertEqual(fromTypedNode(node), s)
72             self.assertEqual(type(fromTypedNode(node)), types.UnicodeType)
73
74         def test_blank_or_uri_blank(self):
75             node = blankOrUri()
76             self.assertEqual(node.is_blank(), True)
77
78         def test_blank_or_uri_url(self):
79             s = 'http://google.com'
80             node = blankOrUri(s)
81             self.assertEqual(node.is_resource(), True)
82             self.assertEqual(str(node.uri), s)
83
84         def test_blank_or_uri_node(self):
85             s = RDF.Node(RDF.Uri('http://google.com'))
86             node = blankOrUri(s)
87             self.assertEqual(node.is_resource(), True)
88             self.assertEqual(node, s)
89
90         def test_unicode_node_roundtrip(self):
91             literal = u'\u5927'
92             roundtrip = fromTypedNode(toTypedNode(literal))
93             self.assertEqual(roundtrip, literal)
94             self.assertEqual(type(roundtrip), types.UnicodeType)
95
96         def test_datetime_no_microsecond(self):
97             dateTimeType = xsdNS['dateTime'].uri
98             short_isostamp = '2011-12-20T11:44:25'
99             short_node = RDF.Node(literal=short_isostamp,
100                                  datatype=dateTimeType)
101             short_datetime = datetime(2011,12,20,11,44,25)
102
103             self.assertEqual(fromTypedNode(short_node), short_datetime)
104             self.assertEqual(toTypedNode(short_datetime), short_node)
105             self.assertEqual(fromTypedNode(toTypedNode(short_datetime)),
106                              short_datetime)
107
108         def test_datetime_with_microsecond(self):
109             dateTimeType = xsdNS['dateTime'].uri
110             long_isostamp = '2011-12-20T11:44:25.081776'
111             long_node = RDF.Node(literal=long_isostamp,
112                                  datatype=dateTimeType)
113             long_datetime = datetime(2011,12,20,11,44,25,81776)
114
115             self.assertEqual(fromTypedNode(long_node), long_datetime)
116             self.assertEqual(toTypedNode(long_datetime), long_node)
117             self.assertEqual(fromTypedNode(toTypedNode(long_datetime)),
118                              long_datetime)
119
120         def test_strip_namespace_uri(self):
121             nsOrg = RDF.NS('example.org/example#')
122             nsCom = RDF.NS('example.com/example#')
123
124             term = 'foo'
125             node = nsOrg[term]
126             self.assertEqual(strip_namespace(nsOrg, node), term)
127             self.assertEqual(strip_namespace(nsCom, node), None)
128             self.assertEqual(strip_namespace(nsOrg, node.uri), term)
129
130         def test_strip_namespace_exceptions(self):
131             nsOrg = RDF.NS('example.org/example#')
132             nsCom = RDF.NS('example.com/example#')
133
134             node = toTypedNode('bad')
135             self.assertRaises(ValueError, strip_namespace, nsOrg, node)
136             self.assertRaises(ValueError, strip_namespace, nsOrg, nsOrg)
137
138         def test_simplify_uri(self):
139             DATA = [('http://asdf.org/foo/bar', 'bar'),
140                     ('http://asdf.org/foo/bar#bleem', 'bleem'),
141                     ('http://asdf.org/foo/bar/', 'bar'),
142                     ('http://asdf.org/foo/bar?was=foo', 'was=foo')]
143
144             for uri, expected in DATA:
145                 self.assertEqual(simplify_uri(uri), expected)
146
147             for uri, expected in DATA:
148                 n = RDF.Uri(uri)
149                 self.assertEqual(simplify_uri(n), expected)
150
151             for uri, expected in DATA:
152                 n = RDF.Node(RDF.Uri(uri))
153                 self.assertEqual(simplify_uri(n), expected)
154
155             # decoding literals is questionable
156             n = toTypedNode('http://foo/bar')
157             self.assertRaises(ValueError, simplify_uri, n)
158
159         def test_owl_import(self):
160             path, name = os.path.split(__file__)
161             #loc = 'file://'+os.path.abspath(path)+'/'
162             loc = os.path.abspath(path)+'/'
163             model = get_model()
164             fragment = '''
165 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
166 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
167 @prefix owl: <http://www.w3.org/2002/07/owl#> .
168
169 _:a owl:imports "{loc}extra.turtle" .
170 '''.format(loc=loc)
171             load_string_into_model(model, 'turtle', fragment, loc)
172             tc = RDF.Node(RDF.Uri('http://jumpgate.caltech.edu/wiki/TestCase'))
173             query = RDF.Statement(tc, rdfsNS['label'], None)
174             result = list(model.find_statements(query))
175             self.assertEqual(len(result), 1)
176             self.assertEqual(str(result[0].object), 'TestCase')
177
178         def test_sanitize_literal_text(self):
179             self.assertRaises(ValueError, sanitize_literal, "hi")
180             hello_text = "hello"
181             hello_none = RDF.Node(hello_text)
182             self.assertEqual(str(sanitize_literal(hello_none)),
183                                  hello_text)
184             hello_str = RDF.Node(literal=hello_text,
185                                  datatype=xsdNS['string'].uri)
186             hello_clean = sanitize_literal(hello_str)
187             self.assertEqual(hello_clean.literal_value['string'],
188                                  hello_text)
189
190         def test_sanitize_literal_empty_string(self):
191             value = ""
192             value_node = RDF.Node(value)
193             self.assertEqual(str(sanitize_literal(value_node)), value)
194
195         def test_sanitize_literal_html(self):
196             hello = "hello <a onload='javascript:alert(\"foo\");' href='http://google.com'>google.com</a>, whats up?"
197             hello_clean = 'hello <a href="http://google.com">google.com</a>, whats up?'
198             hello_node = RDF.Node(literal=hello,
199                                   datatype=xsdNS['string'].uri)
200             hello_sanitized = sanitize_literal(hello_node)
201             self.assertEqual(hello_sanitized.literal_value['string'],
202                                  hello_clean)
203
204             hostile = "hi <b>there</b><script type='text/javascript>alert('boo');</script><a href='javascript:alert('poke')>evil</a> scammer"
205             hostile_node = RDF.Node(hostile)
206             hostile_sanitized = sanitize_literal(hostile_node)
207             # so it drops the stuff after the javascript link.
208             # I suppose it could be worse
209             hostile_result = """hi <b>there</b>"""
210             self.assertEqual(str(hostile_sanitized), hostile_result)
211
212         def test_guess_parser_from_file(self):
213             DATA = [
214                 ('/a/b/c.rdf', 'rdfxml'),
215                 ('/a/b/c.xml', 'rdfxml'),
216                 ('/a/b/c.html', 'rdfa'),
217                 ('/a/b/c.turtle', 'turtle'),
218                 ('http://foo.bar/bleem.turtle', 'turtle')]
219             for path, parser in DATA:
220                 self.assertEqual(guess_parser_by_extension(path), parser)
221                 self.assertEqual(guess_parser(None, path), parser)
222
223             DATA = [
224                 ('application/rdf+xml', 'http://a.org/b/c', 'rdfxml'),
225                 ('application/x-turtle', 'http://a.org/b/c', 'turtle'),
226                 ('text/html', 'http://a.org/b/c', 'rdfa'),
227                 ('text/html', 'http://a.org/b/c.html', 'rdfa'),
228                 ('text/plain', 'http://a.org/b/c.turtle', 'turtle'),
229                 ('text/plain', 'http://a.org/b/c', 'guess')
230             ]
231             for contenttype, url, parser in DATA:
232                 self.assertEqual(guess_parser(contenttype, url), parser)
233
234     class TestRDFSchemas(TestCase):
235         def test_rdf_schema(self):
236             """Does it basically work?
237             """
238             model = get_model()
239             self.assertEqual(model.size(), 0)
240             add_default_schemas(model)
241             self.assertTrue(model.size() > 0)
242             remove_schemas(model)
243             self.assertEqual(model.size(), 0)
244
245         def test_included_schemas(self):
246             model = get_model()
247             add_default_schemas(model)
248
249             # rdf test
250             s = RDF.Statement(rdfNS[''], dcNS['title'], None)
251             title = model.get_target(rdfNS[''], dcNS['title'])
252             self.assertTrue(title is not None)
253
254             s = RDF.Statement(rdfNS['Property'], rdfNS['type'], rdfsNS['Class'])
255             self.assertTrue(model.contains_statement(s))
256
257             # rdfs test
258             s = RDF.Statement(rdfsNS['Class'], rdfNS['type'], rdfsNS['Class'])
259             self.assertTrue(model.contains_statement(s))
260
261             s = RDF.Statement(owlNS['inverseOf'], rdfNS['type'],
262                               rdfNS['Property'])
263             self.assertTrue(model.contains_statement(s))
264
265
266 except ImportError as e:
267     print("Unable to test rdfhelp")
268
269 def suite():
270     from unittest import TestSuite, defaultTestLoader
271     suite = TestSuite()
272     suite.addTests(defaultTestLoader.loadTestsFromTestCase(TestRDFHelp))
273     suite.addTests(defaultTestLoader.loadTestsFromTestCase(TestRDFSchemas))
274     return suite
275
276
277 if __name__ == "__main__":
278     from unittest import main
279     main(defaultTest="suite")