1
|
1 |
|
import json |
2
|
1 |
|
import datetime |
3
|
|
|
|
4
|
1 |
|
from ppp_datamodel import AbstractNode, Triple, Resource, Missing |
5
|
1 |
|
from ppp_datamodel import List, Union, Intersection |
6
|
1 |
|
from ppp_datamodel import exceptions |
7
|
|
|
|
8
|
1 |
|
from unittest import TestCase |
9
|
|
|
|
10
|
1 |
|
R = Resource |
11
|
1 |
|
r = lambda x:{'type': 'resource', 'value': x} |
12
|
1 |
|
M = Missing |
13
|
1 |
|
m = lambda:{'type': 'missing'} |
14
|
|
|
|
15
|
1 |
|
class BaseAbstractNodeTests(TestCase): |
16
|
1 |
|
def testAbstract(self): |
17
|
1 |
|
self.assertRaises(TypeError, AbstractNode) |
18
|
|
|
|
19
|
1 |
|
def testBasicConstructor(self): |
20
|
1 |
|
n = Triple(subject=R('s'), predicate=R('p'), object=R('o')) |
21
|
1 |
|
self.assertEqual(n.subject, R('s')) |
22
|
1 |
|
self.assertEqual(n['subject'], R('s')) |
23
|
1 |
|
self.assertRaises(AttributeError, lambda: n.foobar) |
24
|
|
|
|
25
|
1 |
|
def testSet(self): |
26
|
1 |
|
n = Triple(subject=R('s'), predicate=R('p'), object=R('o')) |
27
|
1 |
|
with self.assertRaises(TypeError): |
28
|
1 |
|
n.predicate = R('test') |
29
|
1 |
|
with self.assertRaises(TypeError): |
30
|
1 |
|
del n.predicate |
31
|
|
|
|
32
|
|
|
|
33
|
1 |
|
def testEmptyConstructor(self): |
34
|
1 |
|
n = Triple() |
35
|
1 |
|
self.assertRaises(exceptions.AttributeNotProvided, |
36
|
|
|
lambda: n.predicate) |
37
|
|
|
|
38
|
1 |
|
def testInvalidConstrutorAttribute(self): |
39
|
1 |
|
self.assertRaises(TypeError, Triple, foo='bar') |
40
|
|
|
|
41
|
1 |
|
def testToJsonPerfect(self): |
42
|
1 |
|
n = Triple(subject=R('s'), predicate=R('p'), object=R('o')) |
43
|
1 |
|
self.assertEqual(json.loads(n.as_json()), {'type': 'triple', |
44
|
|
|
'subject': r('s'), 'predicate': r('p'), 'object': r('o')}) |
45
|
|
|
|
46
|
1 |
|
def testToJsonMissing(self): |
47
|
1 |
|
n = Triple(subject=R('s'), predicate=R('p')) |
48
|
1 |
|
self.assertEqual(json.loads(n.as_json()), {'type': 'triple', |
49
|
|
|
'subject': r('s'), 'predicate': r('p')}) |
50
|
|
|
|
51
|
1 |
|
def testToJsonNone(self): |
52
|
1 |
|
n = Triple(subject=R('s'), predicate=R('p'), object=Missing()) |
53
|
1 |
|
self.assertEqual(json.loads(n.as_json()), {'type': 'triple', |
54
|
|
|
'subject': r('s'), 'predicate': r('p'), 'object': m()}) |
55
|
|
|
|
56
|
1 |
|
def testFromJsonPerfect(self): |
57
|
1 |
|
d = {'type': 'triple', |
58
|
|
|
'subject': r('s'), 'predicate': r('p'), 'object': r('o')} |
59
|
1 |
|
self.assertIsInstance(AbstractNode.from_dict(d), Triple) |
60
|
1 |
|
self.assertIsInstance(AbstractNode.from_json(json.dumps(d)), Triple) |
61
|
1 |
|
self.assertEqual(d, json.loads(AbstractNode.from_dict(d).as_json())) |
62
|
1 |
|
self.assertEqual(d, json.loads(AbstractNode.from_json(json.dumps(d)).as_json())) |
63
|
1 |
|
self.assertIsInstance(AbstractNode.from_json(json.dumps(d)).subject, Resource) |
64
|
1 |
|
self.assertEqual(AbstractNode.from_json(json.dumps(d)).subject.value, 's') |
65
|
|
|
|
66
|
1 |
|
def testFromJsonMissing(self): |
67
|
1 |
|
d = {'type': 'triple', |
68
|
|
|
'subject': r('s'), 'predicate': r('p')} |
69
|
1 |
|
n = AbstractNode.from_dict(d) |
70
|
1 |
|
self.assertEqual(d, json.loads(n.as_json())) |
71
|
1 |
|
self.assertEqual(n.predicate, r('p')) |
72
|
1 |
|
self.assertNotIn('object', n) |
73
|
|
|
|
74
|
1 |
|
def testFromJsonNone(self): |
75
|
1 |
|
d = {'type': 'triple', |
76
|
|
|
'subject': r('s'), 'predicate': r('p'), 'object': m()} |
77
|
1 |
|
n = AbstractNode.from_dict(d) |
78
|
1 |
|
self.assertEqual(d, json.loads(n.as_json())) |
79
|
1 |
|
self.assertIn('object', n) |
80
|
1 |
|
self.assertEqual(n.object, M()) |
81
|
|
|
|
82
|
1 |
|
def testFromJsonTypeNotProvided(self): |
83
|
1 |
|
d = {'subject': r('s'), 'predicate': r('p'), 'object': m()} |
84
|
1 |
|
self.assertRaises(exceptions.AttributeNotProvided, |
85
|
|
|
AbstractNode.from_dict, d) |
86
|
|
|
|
87
|
1 |
|
def testFromJsonTypeInvalid(self): |
88
|
1 |
|
d = {'type': 'foobar', |
89
|
|
|
'subject': r('s'), 'predicate': r('p'), 'object': m()} |
90
|
1 |
|
self.assertRaises(exceptions.UnknownNodeType, |
91
|
|
|
AbstractNode.from_dict, d) |
92
|
|
|
|
93
|
1 |
|
def testCheckType(self): |
94
|
1 |
|
self.assertRaises(TypeError, Triple, {}) |
95
|
|
|
|
96
|
1 |
|
def testEq(self): |
97
|
1 |
|
self.assertEqual(Missing(), Missing()) |
98
|
1 |
|
self.assertEqual(Resource('foo'), Resource('foo')) |
99
|
1 |
|
self.assertNotEqual(Missing(), Resource('foo')) |
100
|
1 |
|
self.assertEqual(Missing(), {'type': 'missing'}) |
101
|
1 |
|
self.assertNotEqual(Missing(), {'type': 'missing', 'f': 'b'}) |
102
|
1 |
|
self.assertEqual(Resource('foo'), {'type': 'resource', |
103
|
|
|
'value': 'foo'}) |
104
|
1 |
|
self.assertNotEqual(Missing(), '') |
105
|
|
|
|
106
|
1 |
|
def testList(self): |
107
|
1 |
|
r1 = {'type': 'resource', 'value': 'foo'} |
108
|
1 |
|
r2 = {'type': 'resource', 'value': 'bar'} |
109
|
1 |
|
d = {'type': 'list', 'list': [r1, r2]} |
110
|
1 |
|
o = AbstractNode.from_dict(d) |
111
|
1 |
|
self.assertEqual(o.list, [Resource('foo'), Resource('bar')]) |
112
|
1 |
|
self.assertIsInstance(o.list[1], Resource) |
113
|
1 |
|
self.assertEqual(o.as_dict(), d) |
114
|
|
|
|
115
|
1 |
|
def testSerialize(self): |
116
|
1 |
|
d = {'type': 'resource', 'value': 'foo', 'value-type': 'bar', 'baz-qux': 'quux'} |
117
|
1 |
|
self.assertEqual(AbstractNode.from_dict(d).as_dict(), d) |
118
|
|
|
|
119
|
1 |
|
def testTraverse(self): |
120
|
1 |
|
def pred(tree): |
121
|
1 |
|
if isinstance(tree, Resource): |
122
|
1 |
|
return Resource('foo') |
123
|
1 |
|
elif isinstance(tree, Triple): |
124
|
1 |
|
return Triple(tree.subject, Resource('bar'), tree.object) |
125
|
1 |
|
elif isinstance(tree, Missing): |
126
|
1 |
|
return Resource('m') |
127
|
|
|
else: |
128
|
1 |
|
return tree |
129
|
1 |
|
f = Resource('foo') |
130
|
1 |
|
b = Resource('bar') |
131
|
1 |
|
m = Resource('m') |
132
|
1 |
|
self.assertEqual(Resource('baz').traverse(pred), f) |
133
|
1 |
|
tree = Triple(Resource('1'), Resource('2'), Missing()) |
134
|
1 |
|
self.assertEqual(tree.traverse(pred), Triple(f, b, m)) |
135
|
1 |
|
tree = List([ |
136
|
|
|
Resource('4'), |
137
|
|
|
Resource('5') |
138
|
|
|
]) |
139
|
1 |
|
self.assertEqual(tree.traverse(pred), |
140
|
|
|
List([ |
141
|
|
|
f, |
142
|
|
|
f |
143
|
|
|
])) |
144
|
1 |
|
tree = Triple( |
145
|
|
|
Triple(Resource('1'), Resource('2'), Missing()), |
146
|
|
|
Resource('3'), |
147
|
|
|
List([ |
148
|
|
|
Resource('4'), |
149
|
|
|
Resource('5') |
150
|
|
|
])) |
151
|
1 |
|
self.assertEqual(tree.traverse(pred), |
152
|
|
|
Triple( |
153
|
|
|
Triple(f, b, m), |
154
|
|
|
b, |
155
|
|
|
List([ |
156
|
|
|
f, |
157
|
|
|
f, |
158
|
|
|
]))) |
159
|
1 |
|
tree = Union([List([Resource('1')]), List([Resource('2')])]) |
160
|
1 |
|
self.assertEqual(tree.traverse(pred), |
161
|
|
|
Union([List([f]), List([f])])) |
162
|
1 |
|
tree = Intersection([List([Resource('1')]), List([Resource('2')])]) |
163
|
1 |
|
self.assertEqual(tree.traverse(pred), |
164
|
|
|
Intersection([List([f]), List([f])])) |
165
|
|
|
|
166
|
1 |
|
def testTraverseContract(self): |
167
|
1 |
|
f = Resource('foo') |
168
|
1 |
|
def pred(tree): |
169
|
1 |
|
if isinstance(tree, List): |
170
|
1 |
|
return Resource('foo') |
171
|
1 |
|
elif isinstance(tree, Intersection): |
172
|
1 |
|
self.assertEqual(tree, Intersection([f, f])) |
173
|
1 |
|
return tree |
174
|
1 |
|
elif isinstance(tree, Resource): |
175
|
1 |
|
return tree |
176
|
|
|
else: |
177
|
|
|
raise AssertionError(tree) |
178
|
1 |
|
tree = Intersection([List([Resource('1')]), List([Resource('2')])]) |
179
|
1 |
|
self.assertEqual(tree.traverse(pred), |
180
|
|
|
Intersection([f, f])) |
181
|
|
|
|
182
|
1 |
|
def testTripleIntersection(self): |
183
|
1 |
|
t = Intersection([ |
184
|
|
|
Triple( |
185
|
|
|
Resource('a'), |
186
|
|
|
Resource('b'), |
187
|
|
|
Missing()), |
188
|
|
|
Triple( |
189
|
|
|
Resource('c'), |
190
|
|
|
Resource('d'), |
191
|
|
|
Missing())]) |
192
|
|
|
AbstractNode.from_dict(t.as_dict()) |
193
|
|
|
|