1
|
|
|
from mock import Mock |
2
|
|
|
from tests.ditest import DependencyInjectionTestBase |
3
|
|
|
import datetime, random |
4
|
|
|
|
5
|
|
|
|
6
|
|
|
class JsonFileTest(DependencyInjectionTestBase): |
7
|
|
|
|
8
|
|
|
def setUp(self): |
9
|
|
|
super(JsonFileTest, self).setUp() |
10
|
|
|
self.dependencies.getConfiguration().database_url = '' |
11
|
|
|
|
12
|
|
|
def imageWithProvenance(self, prov): |
13
|
|
|
img = Mock() |
14
|
|
|
img.provenance = prov |
15
|
|
|
if 'location' in prov: |
16
|
|
|
img.location.toString.return_value = prov['location'] |
17
|
|
|
return img |
18
|
|
|
|
19
|
|
View Code Duplication |
def test_Add(self): |
|
|
|
|
20
|
|
|
from niprov.jsonfile import JsonFile |
21
|
|
|
repo = JsonFile(self.dependencies) |
22
|
|
|
img1 = self.imageWithProvenance({'location':'1','foo':'baz'}) |
23
|
|
|
repo.all = Mock() |
24
|
|
|
repo.all.return_value = [img1] |
25
|
|
|
image = self.imageWithProvenance({'location': '2','foo':'bar'}) |
26
|
|
|
repo.add(image) |
27
|
|
|
self.serializer.serializeList.assert_called_with( |
28
|
|
|
[img1, image]) |
29
|
|
|
self.filesys.write.assert_called_with(repo.datafile, |
30
|
|
|
self.serializer.serializeList()) |
31
|
|
|
|
32
|
|
View Code Duplication |
def test_Update(self): |
|
|
|
|
33
|
|
|
from niprov.jsonfile import JsonFile |
34
|
|
|
repo = JsonFile(self.dependencies) |
35
|
|
|
img1 = self.imageWithProvenance({'location':'1','path':'a'}) |
36
|
|
|
img2 = self.imageWithProvenance({'location':'2','path':'b'}) |
37
|
|
|
repo.all = Mock() |
38
|
|
|
repo.all.return_value = [img1, img2] |
39
|
|
|
image = self.imageWithProvenance({'location': '2','foo':'bar'}) |
40
|
|
|
repo.update(image) |
41
|
|
|
self.serializer.serializeList.assert_called_with( |
42
|
|
|
[img1,image]) |
43
|
|
|
self.filesys.write.assert_called_with(repo.datafile, |
44
|
|
|
self.serializer.serializeList()) |
45
|
|
|
|
46
|
|
|
def test_byLocation(self): |
47
|
|
|
from niprov.jsonfile import JsonFile |
48
|
|
|
repo = JsonFile(self.dependencies) |
49
|
|
|
img1 = self.imageWithProvenance({'location':'1','path':'a'}) |
50
|
|
|
img2 = self.imageWithProvenance({'location':'2','path':'b'}) |
51
|
|
|
repo.all = Mock() |
52
|
|
|
repo.all.return_value = [img1, img2] |
53
|
|
|
out = repo.byLocation('2') |
54
|
|
|
self.assertEqual(img2, out) |
55
|
|
|
|
56
|
|
|
def test_updateApproval(self): |
57
|
|
|
from niprov.jsonfile import JsonFile |
58
|
|
|
repo = JsonFile(self.dependencies) |
59
|
|
|
img = Mock() |
60
|
|
|
img.provenance = {'fiz':'baf','approval':'notsure'} |
61
|
|
|
def assertion(img): |
62
|
|
|
self.assertEqual({'fiz':'baf','approval':'excellent!'}, img.provenance) |
63
|
|
|
repo.byLocation = Mock() |
64
|
|
|
repo.byLocation.return_value = img |
65
|
|
|
repo.update = Mock() |
66
|
|
|
repo.update.side_effect = assertion |
67
|
|
|
repo.updateApproval('/p/f1','excellent!') |
68
|
|
|
|
69
|
|
|
def test_latest(self): |
70
|
|
|
from niprov.jsonfile import JsonFile |
71
|
|
|
repo = JsonFile(self.dependencies) |
72
|
|
|
img1 = self.imageWithProvenance({'added':datetime.datetime(1982, 1, 5)}) |
73
|
|
|
img2 = self.imageWithProvenance({'added':datetime.datetime(1982, 2, 5)}) |
74
|
|
|
img3 = self.imageWithProvenance({'added':datetime.datetime(1982, 3, 5)}) |
75
|
|
|
img4 = self.imageWithProvenance({'added':datetime.datetime(1982, 4, 5)}) |
76
|
|
|
img5 = self.imageWithProvenance({'added':datetime.datetime(1982, 5, 5)}) |
77
|
|
|
repo.all = Mock() |
78
|
|
|
repo.all.return_value = [img1,img2,img3,img4,img5] |
79
|
|
|
out = repo.latest(3) |
80
|
|
|
self.assertEqual([img5, img4, img3], out) |
81
|
|
|
|
82
|
|
|
def test_stats(self): |
83
|
|
|
from niprov.jsonfile import JsonFile |
84
|
|
|
repo = JsonFile(self.dependencies) |
85
|
|
|
repo.all = Mock() |
86
|
|
|
records = [{},{},{},{},{},{},{},{},{},{},{}] |
87
|
|
|
totalsize = 0 |
88
|
|
|
for r in records: |
89
|
|
|
r['size'] = random.randint(1,1000) |
90
|
|
|
totalsize += r['size'] |
91
|
|
|
repo.all.return_value = [self.imageWithProvenance(r) for r in records] |
92
|
|
|
out = repo.statistics() |
93
|
|
|
self.assertEqual(11, out['count']) |
94
|
|
|
self.assertEqual(totalsize, out['totalsize']) |
95
|
|
|
|
96
|
|
|
def test_stats_transient_file(self): |
97
|
|
|
from niprov.jsonfile import JsonFile |
98
|
|
|
repo = JsonFile(self.dependencies) |
99
|
|
|
repo.all = Mock() |
100
|
|
|
records = [{},{},{},{},{},{},{},{},{},{},{}] |
101
|
|
|
totalsize = 0 |
102
|
|
|
for r in records: |
103
|
|
|
r['size'] = random.randint(1,1000) |
104
|
|
|
totalsize += r['size'] |
105
|
|
|
totalsize -= records[3]['size'] |
106
|
|
|
del records[3]['size'] |
107
|
|
|
repo.all.return_value = [self.imageWithProvenance(r) for r in records] |
108
|
|
|
out = repo.statistics() |
109
|
|
|
self.assertEqual(totalsize, out['totalsize']) |
110
|
|
|
|
111
|
|
|
def test_byId(self): |
112
|
|
|
from niprov.jsonfile import JsonFile |
113
|
|
|
repo = JsonFile(self.dependencies) |
114
|
|
|
img1 = self.imageWithProvenance({'id':'1'}) |
115
|
|
|
img2 = self.imageWithProvenance({'id':'2'}) |
116
|
|
|
img3 = self.imageWithProvenance({'id':'3'}) |
117
|
|
|
repo.all = Mock() |
118
|
|
|
repo.all.return_value = [img1, img2, img3] |
119
|
|
|
out = repo.byId('2') |
120
|
|
|
self.assertEqual(img2, out) |
121
|
|
|
|
122
|
|
|
def test_byLocations(self): |
123
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['a'] |
124
|
|
|
from niprov.jsonfile import JsonFile |
125
|
|
|
repo = JsonFile(self.dependencies) |
126
|
|
|
img1 = self.imageWithProvenance({'location':'i'}) |
127
|
|
|
img2 = self.imageWithProvenance({'location':'j'}) |
128
|
|
|
img3 = self.imageWithProvenance({'location':'m'}) |
129
|
|
View Code Duplication |
img4 = self.imageWithProvenance({'location':'f'}) |
|
|
|
|
130
|
|
|
img5 = self.imageWithProvenance({'location':'x'}) |
131
|
|
|
repo.all = Mock() |
132
|
|
|
repo.all.return_value = [img1,img2,img3,img4,img5] |
133
|
|
|
out = repo.byLocations(['j','f','k']) |
134
|
|
|
self.assertEqual([img2, img4], out) |
135
|
|
|
|
136
|
|
|
def test_byParents(self): |
137
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
138
|
|
|
from niprov.jsonfile import JsonFile |
139
|
|
|
repo = JsonFile(self.dependencies) |
140
|
|
View Code Duplication |
img1 = self.imageWithProvenance({'parents':[],'l':'a'}) |
|
|
|
|
141
|
|
|
img2 = self.imageWithProvenance({'parents':['x','a'],'l':'b'}) |
142
|
|
|
img3 = self.imageWithProvenance({'parents':['b'],'l':'b'}) |
143
|
|
|
img4 = self.imageWithProvenance({'parents':['c','y'],'l':'d'}) |
144
|
|
|
img5 = self.imageWithProvenance({'parents':['d'],'l':'e'}) |
145
|
|
|
repo.all = Mock() |
146
|
|
|
repo.all.return_value = [img1, img2, img3, img4, img5] |
147
|
|
|
out = repo.byParents(['x','y']) |
148
|
|
|
self.assertEqual([img2, img4], out) |
149
|
|
|
|
150
|
|
|
def test_Will_tell_PictureCache_to_persist_known_Snapshot(self): |
151
|
|
|
from niprov.jsonfile import JsonFile |
152
|
|
|
repo = JsonFile(self.dependencies) |
153
|
|
|
img = self.imageWithProvenance({'location':'1','foo':'baz'}) |
154
|
|
|
repo.add(img) |
155
|
|
|
self.pictureCache.saveToDisk.assert_called_with(for_=img) |
156
|
|
|
|
157
|
|
|
def test_Query_with_value_field(self): |
158
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
159
|
|
|
from niprov.jsonfile import JsonFile |
160
|
|
|
repo = JsonFile(self.dependencies) |
161
|
|
|
img1 = self.imageWithProvenance({'a':'b'}) |
162
|
|
|
img2 = self.imageWithProvenance({'color':'red','a':'d'}) |
163
|
|
|
img3 = self.imageWithProvenance({'color':'blue','a':'f'}) |
164
|
|
|
img4 = self.imageWithProvenance({'color':'red','a':'d'}) |
165
|
|
|
repo.all = Mock() |
166
|
|
|
repo.all.return_value = [img1, img2, img3, img4] |
167
|
|
|
q = Mock() |
168
|
|
|
field1 = Mock() |
169
|
|
|
field1.name = 'color' |
170
|
|
|
field1.value = 'red' |
171
|
|
|
field1.all = False |
172
|
|
|
q.getFields.return_value = [field1] |
173
|
|
|
out = repo.inquire(q) |
174
|
|
|
self.assertEqual([img2, img4], out) |
175
|
|
|
|
176
|
|
|
def test_Search_only_returns_objects_which_have_needle(self): |
177
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
178
|
|
|
from niprov.jsonfile import JsonFile |
179
|
|
|
repo = JsonFile(self.dependencies) |
180
|
|
|
img1 = self.imageWithProvenance({'transformation':'green blue'}) |
181
|
|
|
img2 = self.imageWithProvenance({'transformation':'yellow red'}) |
182
|
|
|
repo.all = Mock() |
183
|
|
|
repo.all.return_value = [img1, img2] |
184
|
|
|
out = repo.search('red') |
185
|
|
|
self.assertEqual([img2], out) |
186
|
|
|
|
187
|
|
|
def test_Search_sorts_results_by_number_of_matches(self): |
188
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
189
|
|
|
from niprov.jsonfile import JsonFile |
190
|
|
|
repo = JsonFile(self.dependencies) |
191
|
|
|
img1 = self.imageWithProvenance({'transformation':'red bluered'}) |
192
|
|
|
img2 = self.imageWithProvenance({'transformation':'red and green'}) |
193
|
|
View Code Duplication |
img3 = self.imageWithProvenance({'transformation':'red pruple red red'}) |
|
|
|
|
194
|
|
|
img4 = self.imageWithProvenance({'transformation':'nuthin'}) |
195
|
|
|
repo.all = Mock() |
196
|
|
|
repo.all.return_value = [img1, img2, img3, img4] |
197
|
|
|
out = repo.search('red') |
198
|
|
|
self.assertEqual([img3, img1, img2], out) |
199
|
|
|
|
200
|
|
|
def test_Search_looks_through_multiple_fields(self): |
201
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
202
|
|
|
from niprov.jsonfile import JsonFile |
203
|
|
|
repo = JsonFile(self.dependencies) |
204
|
|
View Code Duplication |
i1 = self.imageWithProvenance({'color':'red'}) |
|
|
|
|
205
|
|
|
i2 = self.imageWithProvenance({'location':'redis'}) |
206
|
|
|
i3 = self.imageWithProvenance({'user':'reddit'}) |
207
|
|
|
i4 = self.imageWithProvenance({'subject':'red bastard'}) |
208
|
|
|
i5 = self.imageWithProvenance({'protocol':'reddish'}) |
209
|
|
|
i6 = self.imageWithProvenance({'transformation':'zoomed red'}) |
210
|
|
|
i7 = self.imageWithProvenance({'technique':'redshift'}) |
211
|
|
|
i8 = self.imageWithProvenance({'modality':'red'}) |
212
|
|
|
repo.all = Mock() |
213
|
|
|
repo.all.return_value = [i1,i2,i3,i4,i5,i6,i7,i8] |
214
|
|
|
out = repo.search('red') |
215
|
|
|
self.assertNotIn(i1, out) |
216
|
|
|
self.assertIn(i2, out) |
217
|
|
|
self.assertIn(i3, out) |
218
|
|
|
self.assertIn(i4, out) |
219
|
|
|
self.assertIn(i5, out) |
220
|
|
|
self.assertIn(i6, out) |
221
|
|
|
self.assertIn(i7, out) |
222
|
|
|
self.assertIn(i8, out) |
223
|
|
|
|
224
|
|
|
def test_Search_distinguishes_words_as_OR_search(self): |
225
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
226
|
|
|
from niprov.jsonfile import JsonFile |
227
|
|
|
repo = JsonFile(self.dependencies) |
228
|
|
|
i1 = self.imageWithProvenance({'transformation':'blue red red'}) #2 |
229
|
|
|
i2 = self.imageWithProvenance({'transformation':'red blue green red'}) #3 |
230
|
|
|
i3 = self.imageWithProvenance({'transformation':'green blue'}) #1 |
231
|
|
|
repo.all = Mock() |
232
|
|
|
repo.all.return_value = [i1,i2,i3] |
233
|
|
|
out = repo.search('red green') |
234
|
|
|
self.assertEqual([i2, i1, i3], out) |
235
|
|
|
|
236
|
|
|
def test_Search_returns_max_20_results(self): |
237
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
238
|
|
|
from niprov.jsonfile import JsonFile |
239
|
|
|
repo = JsonFile(self.dependencies) |
240
|
|
|
recs = [] |
241
|
|
View Code Duplication |
for i in range(35): |
|
|
|
|
242
|
|
|
recs.append(self.imageWithProvenance({'transformation':'red'})) |
243
|
|
|
repo.all = Mock() |
244
|
|
|
repo.all.return_value = recs |
245
|
|
|
out = repo.search('red') |
246
|
|
|
self.assertEqual(20, len(out)) |
247
|
|
|
|
248
|
|
|
def test_Query_with_ALL_field(self): |
249
|
|
|
self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p['l'] |
250
|
|
|
from niprov.jsonfile import JsonFile |
251
|
|
|
repo = JsonFile(self.dependencies) |
252
|
|
|
img1 = self.imageWithProvenance({'a':'b'}) |
253
|
|
View Code Duplication |
img2 = self.imageWithProvenance({'color':'red','a':'d'}) |
|
|
|
|
254
|
|
|
img3 = self.imageWithProvenance({'color':'blue','a':'f'}) |
255
|
|
|
img4 = self.imageWithProvenance({'color':'green','a':'d'}) |
256
|
|
|
img5 = self.imageWithProvenance({'color':'blue','a':'g'}) |
257
|
|
|
repo.all = Mock() |
258
|
|
|
repo.all.return_value = [img1, img2, img3, img4, img5] |
259
|
|
|
q = Mock() |
260
|
|
|
field1 = Mock() |
261
|
|
|
field1.name = 'color' |
262
|
|
|
field1.all = True |
263
|
|
|
q.getFields.return_value = [field1] |
264
|
|
|
out = repo.inquire(q) |
265
|
|
|
self.assertIn('red', out) |
266
|
|
|
self.assertIn('green', out) |
267
|
|
|
self.assertIn('blue', out) |
268
|
|
|
self.assertEqual(3, len(out)) |
269
|
|
|
|
270
|
|
|
def test_getSeries(self): |
271
|
|
|
from niprov.jsonfile import JsonFile |
272
|
|
|
repo = JsonFile(self.dependencies) |
273
|
|
|
img = Mock() |
274
|
|
|
img.getSeriesId.return_value = '2' |
275
|
|
|
img1 = self.imageWithProvenance({'seriesuid':'1','path':'a'}) |
276
|
|
|
img2 = self.imageWithProvenance({'seriesuid':'2','path':'b'}) |
277
|
|
|
repo.all = Mock() |
278
|
|
|
repo.all.return_value = [img1, img2] |
279
|
|
|
out = repo.getSeries(img) |
280
|
|
|
self.assertEqual(img2, out) |
281
|
|
|
|
282
|
|
|
def test_getSeries_returns_None_right_away_if_no_series_id(self): |
283
|
|
|
from niprov.jsonfile import JsonFile |
284
|
|
|
repo = JsonFile(self.dependencies) |
285
|
|
|
img = Mock() |
286
|
|
|
img.getSeriesId.return_value = None |
287
|
|
|
repo.all = Mock() |
288
|
|
View Code Duplication |
out = repo.getSeries(img) |
|
|
|
|
289
|
|
|
assert not repo.all.called, "Should not be called if no series id" |
290
|
|
|
self.assertEqual(None, out) |
291
|
|
|
|
292
|
|
|
|