Merged 0.3.1 preparations from branches/version-0.3.x.
[joel/kofoto.git] / src / test / shelftests.py
1 #! /usr/bin/env python
2
3 import gc
4 import os
5 import shutil
6 import sys
7 import threading
8 import unittest
9 import Image as PILImage
10
11 if __name__ == "__main__":
12     cwd = os.getcwd()
13     libdir = unicode(os.path.realpath(
14         os.path.join(os.path.dirname(sys.argv[0]), "..", "lib")))
15     os.chdir(libdir)
16     sys.path.insert(0, libdir)
17 from kofoto.shelf import *
18
19 PICDIR = unicode(os.path.realpath(
20     os.path.join("..", "reference_pictures", "working")))
21
22 ######################################################################
23
24 db = "shelf.tmp"
25 codeset = "latin1"
26
27 def removeTmpDb():
28     for x in [db, db + "-journal"]:
29         if os.path.exists(x):
30             os.unlink(x)
31
32 class LockerThread(threading.Thread):
33     def __init__(self, mContinue, ltContinue):
34         threading.Thread.__init__(self)
35         self.mContinue = mContinue
36         self.ltContinue = ltContinue
37
38     def run(self):
39         s = Shelf(db, codeset)
40         s.create()
41         s.begin()
42         self.mContinue.set()
43         self.ltContinue.wait()
44         s.rollback()
45
46 ######################################################################
47
48 class TestPublicShelfFunctions(unittest.TestCase):
49     def test_computeImageHash(self):
50         s = computeImageHash(os.path.join(PICDIR, "arlaharen.png"))
51         assert s == "39a1266d2689f53d48b09a5e0ca0af1f"
52         try:
53             computeImageHash("nonexisting")
54         except IOError:
55             pass
56         else:
57             assert False, s
58
59     def test_verifyValidAlbumTag(self):
60         # Valid tags.
61         for x in ("foo", "1foo", "and", "exactly", "not", "or"):
62             try:
63                 verifyValidAlbumTag(x)
64             except:
65                 assert False, x
66         # Invalid tags.
67         for x in (None, 1, 1L, "1" "foo " "@foo"):
68             try:
69                 verifyValidAlbumTag(x)
70             except BadAlbumTagError:
71                 pass
72             else:
73                 assert False, x
74
75     def test_verifyValidCategoryTag(self):
76         # Valid tags.
77         for x in ("foo", "1foo"):
78             try:
79                 verifyValidCategoryTag(x)
80             except:
81                 assert False, x
82         # Invalid tags.
83         for x in (None, 1, 1L, "1" "foo " "@foo",
84                   "and", "exactly", "not", "or"):
85             try:
86                 verifyValidCategoryTag(x)
87             except BadCategoryTagError:
88                 pass
89             else:
90                 assert False, x
91
92     def test_makeValidTag(self):
93         for tag, validTag in [("", "_"),
94                               ("@", "_"),
95                               (" ", "_"),
96                               ("1", "1_"),
97                               ("@foo_", "foo_"),
98                               ("fo@o __", "fo@o__")]:
99             assert makeValidTag(tag) == validTag, (tag, validTag)
100
101 class TestNegativeShelfOpens(unittest.TestCase):
102     def tearDown(self):
103         removeTmpDb()
104
105     def test_NonexistingShelf(self):
106         try:
107             s = Shelf(db, codeset)
108             s.begin()
109         except ShelfNotFoundError:
110             pass
111         else:
112             assert False
113         assert not os.path.exists(db)
114
115     def test_BadShelf(self):
116         file(db, "w") # Create empty file.
117         try:
118             s = Shelf(db, codeset)
119             s.begin()
120         except UnsupportedShelfError:
121             pass
122         else:
123             assert False
124
125     def test_LockedShelf(self):
126         mContinue = threading.Event()
127         ltContinue = threading.Event()
128         lt = LockerThread(mContinue, ltContinue)
129         lt.start()
130         mContinue.wait()
131         try:
132             try:
133                 s = Shelf(db, codeset)
134                 s.begin()
135             except ShelfLockedError:
136                 pass
137             else:
138                 assert False
139         finally:
140             ltContinue.set()
141             lt.join()
142
143 class TestShelfCreation(unittest.TestCase):
144     def tearDown(self):
145         removeTmpDb()
146
147     def test_CreateShelf1(self):
148         s = Shelf(db, codeset)
149         s.create()
150         assert os.path.exists(db)
151
152     def test_CreateShelf2(self):
153         file(db, "w") # Create empty file.
154         s = Shelf(db, codeset)
155         try:
156             s.create()
157         except FailedWritingError:
158             pass
159         else:
160             assert False
161
162 class TestShelfMemoryLeakage(unittest.TestCase):
163     def tearDown(self):
164         removeTmpDb()
165
166     def test_MemoryLeak1(self):
167         s = Shelf(db, codeset)
168         s.create()
169         assert gc.collect() == 0
170
171     def test_MemoryLeak2(self):
172         s = Shelf(db, codeset)
173         s.create()
174         s.begin()
175         s.getObject(0)
176         s.rollback()
177         assert gc.collect() == 0
178
179     def test_MemoryLeak3(self):
180         s = Shelf(db, codeset)
181         s.create()
182         s.begin()
183         s.getObject(0)
184         s.commit()
185         assert gc.collect() == 0
186
187 class TestShelfTransactions(unittest.TestCase):
188     def tearDown(self):
189         removeTmpDb()
190
191     def test_commit(self):
192         s = Shelf(db, codeset)
193         s.create()
194         s.begin()
195         s.createAlbum(u"foo")
196         assert s.getAlbum(u"foo")
197         s.commit()
198         s = Shelf(db, codeset)
199         s.begin()
200         assert s.getAlbum(u"foo")
201         s.rollback()
202
203     def test_rollback(self):
204         s = Shelf(db, codeset)
205         s.create()
206         s.begin()
207         s.createAlbum(u"foo")
208         s.rollback()
209         s.begin()
210         try:
211             s.getAlbum(u"foo")
212         except AlbumDoesNotExistError:
213             pass
214         else:
215             assert False
216
217     def test_isModified(self):
218         s = Shelf(db, codeset)
219         s.create()
220         s.begin()
221         assert not s.isModified()
222         s.createAlbum(u"foo")
223         assert s.isModified()
224         s.rollback()
225         s.begin()
226         assert not s.isModified()
227         s.rollback()
228
229     def test_registerModificationCallback(self):
230         res = [False]
231         def f(x):
232             res[0] = True
233         s = Shelf(db, codeset)
234         s.create()
235         s.begin()
236         s.registerModificationCallback(f)
237         assert not res[0]
238         s.createAlbum(u"foo")
239         assert res[0]
240         s.rollback()
241         res[0] = False
242         s.begin()
243         assert not res[0]
244         s.unregisterModificationCallback(f)
245         s.createAlbum(u"foo")
246         assert not res[0]
247         s.rollback()
248
249 class TestShelfFixture(unittest.TestCase):
250     def setUp(self):
251         self.shelf = Shelf(db, codeset)
252         self.shelf.create()
253         self.shelf.begin()
254         root = self.shelf.getRootAlbum()
255         alpha = self.shelf.createAlbum(u"alpha")
256         beta = self.shelf.createAlbum(u"beta")
257         children = [beta]
258         for x in os.listdir(PICDIR):
259             loc = os.path.join(PICDIR, x)
260             if not os.path.isfile(loc):
261                 continue
262             children.append(self.shelf.createImage(loc))
263         del children[-1] # The last image becomes orphaned.
264         alpha.setChildren(children)
265         beta.setChildren(list(beta.getChildren()) + [children[-1]])
266         root.setChildren(list(root.getChildren()) + [alpha, beta])
267         self.shelf.createAlbum(u"epsilon", u"plain") # Orphaned album.
268         zeta = self.shelf.createAlbum(u"zeta", u"search")
269         zeta.setAttribute(u"query", u"a")
270         root.setChildren(list(root.getChildren()) + [zeta])
271
272         cat_a = self.shelf.createCategory(u"a", u"A")
273         cat_b = self.shelf.createCategory(u"b", u"B")
274         cat_c = self.shelf.createCategory(u"c", u"C")
275         cat_d = self.shelf.createCategory(u"d", u"D")
276         cat_a.connectChild(cat_b)
277         cat_a.connectChild(cat_c)
278         cat_b.connectChild(cat_d)
279         cat_c.connectChild(cat_d)
280
281         self.shelf.flushObjectCache()
282         self.shelf.flushCategoryCache()
283
284     def tearDown(self):
285         self.shelf.rollback()
286         removeTmpDb()
287
288 class TestShelfMethods(TestShelfFixture):
289     def test_flushCaches(self):
290         self.shelf.flushCategoryCache()
291         self.shelf.flushObjectCache()
292
293     def test_getStatistics(self):
294         s = self.shelf.getStatistics()
295         assert s["nalbums"] == 6
296         assert s["nimages"] == 11
297
298     def test_createdObjects(self):
299         root = self.shelf.getRootAlbum()
300         children = list(root.getChildren())
301         assert len(children) == 4
302         orphans, alpha, beta, zeta = children
303         assert self.shelf.getObject(u"alpha") == alpha
304         assert self.shelf.getAlbum(u"beta") == beta
305         assert len(list(alpha.getChildren())) == 11
306         assert len(list(beta.getChildren())) == 1
307
308     def test_createdAttributes(self):
309         image = self.shelf.getImage(
310             os.path.join(PICDIR, "Canon_Digital_IXUS.jpg"))
311         assert image.getAttribute(u"captured") == "2002-02-02 22:20:51"
312         assert image.getAttribute(u"cameramake") == "Canon"
313         assert image.getAttribute(u"cameramodel") == "Canon DIGITAL IXUS"
314
315     def test_negativeAlbumCreation(self):
316         try:
317             self.shelf.createAlbum(u"beta")
318         except AlbumExistsError:
319             pass
320         else:
321             assert False
322
323     def test_getAlbum(self):
324         album = self.shelf.getAlbum(u"alpha")
325         album = self.shelf.getAlbum(album.getTag())
326         album = self.shelf.getAlbum(album.getId())
327
328     def test_negativeGetAlbum(self):
329         try:
330             self.shelf.getAlbum(u"nonexisting")
331         except AlbumDoesNotExistError:
332             pass
333         else:
334             assert False
335
336     def test_getRootAlbum(self):
337         root = self.shelf.getRootAlbum()
338         assert root == self.shelf.getAlbum(u"root")
339
340     def test_getAllAlbums(self):
341         albums = list(self.shelf.getAllAlbums())
342         assert len(albums) == 6
343
344     def test_getAllImages(self):
345         images = list(self.shelf.getAllImages())
346         assert len(images) == 11
347
348     def test_getImagesInDirectory(self):
349         images = list(self.shelf.getImagesInDirectory(u"."))
350         assert len(images) == 0
351         images = list(self.shelf.getImagesInDirectory(PICDIR))
352         assert len(images) == 11
353
354     def test_deleteAlbum(self):
355         self.shelf.deleteAlbum(u"beta")
356
357     def test_negativeRootAlbumDeletion(self):
358         try:
359             self.shelf.deleteAlbum(u"root")
360         except UndeletableAlbumError:
361             pass
362         else:
363             assert False
364
365     def test_negativeAlbumDeletion(self):
366         try:
367             self.shelf.deleteAlbum(u"nonexisting")
368         except AlbumDoesNotExistError:
369             pass
370         else:
371             assert False
372
373     def test_negativeImageCreation(self):
374         try:
375             self.shelf.createImage(os.path.join(PICDIR, "arlaharen.png"))
376         except ImageExistsError:
377             pass
378         else:
379             assert False
380
381     def test_getImage(self):
382         image = self.shelf.getImage(os.path.join(PICDIR, "arlaharen.png"))
383         image = self.shelf.getImage(image.getHash())
384         image = self.shelf.getImage(image.getId())
385
386     def test_negativeGetImage(self):
387         try:
388             self.shelf.getImage(u"nonexisting")
389         except ImageDoesNotExistError:
390             pass
391         else:
392             assert False
393
394     def test_deleteImage(self):
395         self.shelf.deleteImage(os.path.join(PICDIR, "arlaharen.png"))
396
397     def test_negativeImageDeletion(self):
398         try:
399             self.shelf.deleteImage(u"nonexisting")
400         except ImageDoesNotExistError:
401             pass
402         else:
403             assert False
404
405     def test_getObject(self):
406         album = self.shelf.getObject(u"alpha")
407         album = self.shelf.getObject(album.getTag())
408         album = self.shelf.getObject(album.getId())
409         image = self.shelf.getObject(os.path.join(PICDIR, "arlaharen.png"))
410         image = self.shelf.getObject(image.getHash())
411         image = self.shelf.getObject(image.getId())
412
413     def test_deleteObject(self):
414         self.shelf.deleteObject(u"beta")
415         self.shelf.deleteObject(os.path.join(PICDIR, "arlaharen.png"))
416
417     def test_getAllAttributeNames(self):
418         attrnames = list(self.shelf.getAllAttributeNames())
419         attrnames.sort()
420         assert attrnames == [
421             "cameramake", "cameramodel", "captured", "description",
422             "digitalzoom", "exposurebias", "exposureprogram", "exposuretime",
423             "flash", "fnumber", "focallength", "iso", "orientation", "query",
424             "title"
425             ], attrnames
426
427     def test_negativeCreateCategory(self):
428         try:
429             self.shelf.createCategory(u"a", u"Foo")
430         except CategoryExistsError:
431             pass
432         else:
433             assert False
434
435     def test_deleteCategory(self):
436         self.shelf.deleteCategory(u"a")
437
438     def test_negativeDeleteCategory(self):
439         try:
440             self.shelf.deleteCategory(u"nonexisting")
441         except CategoryDoesNotExistError:
442             pass
443         else:
444             assert False
445
446     def test_getRootCategories(self):
447         categories = list(self.shelf.getRootCategories())
448         cat_a = self.shelf.getCategory(u"a")
449         cat_events = self.shelf.getCategory(u"events")
450         cat_locations = self.shelf.getCategory(u"locations")
451         cat_people = self.shelf.getCategory(u"people")
452         categories.sort(lambda x, y: cmp(x.getTag(), y.getTag()))
453         assert categories == [cat_a, cat_events, cat_locations, cat_people], \
454                categories
455
456 class TestCategory(TestShelfFixture):
457     def test_categoryMethods(self):
458         cat_a = self.shelf.getCategory(u"a")
459         cat_b = self.shelf.getCategory(u"b")
460         cat_c = self.shelf.getCategory(u"c")
461         cat_d = self.shelf.getCategory(u"d")
462
463         assert self.shelf.getCategory(cat_a.getTag()) == cat_a
464         assert self.shelf.getCategory(cat_a.getId()) == cat_a
465         cat_a.setTag(u"foo")
466         assert self.shelf.getCategory(u"foo") == cat_a
467
468         assert cat_a.getDescription() == "A"
469         cat_a.setDescription(u"foo")
470         assert cat_a.getDescription() == "foo"
471
472         a_children = list(cat_a.getChildren())
473         a_children.sort(lambda x, y: cmp(x.getId(), y.getId()))
474         assert a_children == [cat_b, cat_c]
475         b_children = list(cat_b.getChildren())
476         assert b_children == [cat_d]
477         d_children = list(cat_d.getChildren())
478         assert d_children == []
479
480         a_parents = list(cat_a.getParents())
481         assert a_parents == []
482         b_parents = list(cat_b.getParents())
483         assert b_parents == [cat_a]
484         d_parents = list(cat_d.getParents())
485         d_parents.sort(lambda x, y: cmp(x.getTag(), y.getTag()))
486         assert d_parents == [cat_b, cat_c]
487
488         assert not cat_a.isChildOf(cat_a)
489         assert cat_b.isChildOf(cat_a)
490         assert cat_c.isChildOf(cat_a)
491         assert not cat_d.isChildOf(cat_a)
492         assert cat_a.isChildOf(cat_a, recursive=True)
493         assert cat_b.isChildOf(cat_a, recursive=True)
494         assert cat_c.isChildOf(cat_a, recursive=True)
495         assert cat_d.isChildOf(cat_a, recursive=True)
496
497         assert not cat_d.isParentOf(cat_d)
498         assert cat_b.isParentOf(cat_d)
499         assert cat_c.isParentOf(cat_d)
500         assert not cat_a.isParentOf(cat_d)
501         assert cat_d.isParentOf(cat_d, recursive=True)
502         assert cat_b.isParentOf(cat_d, recursive=True)
503         assert cat_c.isParentOf(cat_d, recursive=True)
504         assert cat_a.isParentOf(cat_d, recursive=True)
505
506     def test_negativeCategoryConnectChild(self):
507         cat_a = self.shelf.getCategory(u"a")
508         cat_b = self.shelf.getCategory(u"b")
509         try:
510             cat_a.connectChild(cat_b)
511         except CategoriesAlreadyConnectedError:
512             pass
513         else:
514             assert False
515         try:
516             cat_b.connectChild(cat_a)
517         except CategoryLoopError:
518             pass
519         else:
520             assert False
521
522     def test_categoryDisconnectChild(self):
523         cat_a = self.shelf.getCategory(u"a")
524         cat_b = self.shelf.getCategory(u"b")
525         cat_a.disconnectChild(cat_b)
526         assert not cat_a.isParentOf(cat_b)
527
528     def test_negativeCategoryDisconnectChild(self):
529         cat_a = self.shelf.getCategory(u"a")
530         cat_d = self.shelf.getCategory(u"d")
531         cat_a.disconnectChild(cat_d) # No exception.
532
533 class TestObject(TestShelfFixture):
534     def test_getParents(self):
535         root = self.shelf.getRootAlbum()
536         alpha = self.shelf.getAlbum(u"alpha")
537         beta = self.shelf.getAlbum(u"beta")
538         parents = list(beta.getParents())
539         parents.sort(lambda x, y: cmp(x.getTag(), y.getTag()))
540         assert parents == [alpha, root]
541
542     def test_getAttribute(self):
543         orphans = self.shelf.getAlbum(u"orphans")
544         assert orphans.getAttribute(u"title")
545         assert orphans.getAttribute(u"description")
546         assert not orphans.getAttribute(u"nonexisting")
547
548     def test_getAttributeMap(self):
549         orphans = self.shelf.getAlbum(u"orphans")
550         map = orphans.getAttributeMap()
551         assert "description" in map
552         assert "title" in map
553
554     def test_getAttributeNames(self):
555         orphans = self.shelf.getAlbum(u"orphans")
556         names = list(orphans.getAttributeNames())
557         names.sort()
558         assert names == ["description", "title"]
559
560     def test_setAttribute(self):
561         orphans = self.shelf.getAlbum(u"orphans")
562         orphans.setAttribute(u"foo", u"fie") # New.
563         assert orphans.getAttribute(u"foo") == u"fie"
564         assert u"foo" in orphans.getAttributeMap()
565         assert u"foo" in orphans.getAttributeNames()
566         assert orphans.getAttribute(u"title")
567         orphans.setAttribute(u"title", u"gazonk") # Existing
568         assert orphans.getAttribute(u"title") == u"gazonk"
569         assert u"foo" in orphans.getAttributeMap()
570         assert u"foo" in orphans.getAttributeNames()
571
572     def test_deleteAttribute(self):
573         orphans = self.shelf.getAlbum(u"orphans")
574         orphans.deleteAttribute(u"nonexisting") # No exception.
575         assert orphans.getAttribute(u"title")
576         orphans.deleteAttribute(u"title")
577         assert not orphans.getAttribute(u"title")
578
579     def test_addCategory(self):
580         orphans = self.shelf.getAlbum(u"orphans")
581         cat_a = self.shelf.getCategory(u"a")
582         assert list(orphans.getCategories()) == []
583         orphans.addCategory(cat_a)
584         assert list(orphans.getCategories()) == [cat_a]
585         try:
586             orphans.addCategory(cat_a)
587         except CategoryPresentError:
588             pass
589         else:
590             assert False
591         assert list(orphans.getCategories()) == [cat_a]
592
593     def test_removeCategory(self):
594         orphans = self.shelf.getAlbum(u"orphans")
595         assert list(orphans.getCategories()) == []
596         cat_a = self.shelf.getCategory(u"a")
597         orphans.addCategory(cat_a)
598         assert list(orphans.getCategories()) == [cat_a]
599         orphans.removeCategory(cat_a)
600         assert list(orphans.getCategories()) == []
601
602     def test_deleteCategoryInvalidatesCategoryCache(self):
603         orphans = self.shelf.getAlbum(u"orphans")
604         assert list(orphans.getCategories()) == []
605         cat_a = self.shelf.getCategory(u"a")
606         orphans.addCategory(cat_a)
607         assert list(orphans.getCategories()) == [cat_a]
608         self.shelf.deleteCategory(cat_a.getId())
609         assert list(orphans.getCategories()) == []
610
611 class TestAlbum(TestShelfFixture):
612     def test_getType(self):
613         alpha = self.shelf.getAlbum(u"alpha")
614         assert alpha.getType() == "plain"
615
616     def test_isMutable(self):
617         alpha = self.shelf.getAlbum(u"alpha")
618         assert alpha.isMutable()
619
620     def test_getTag(self):
621         alpha = self.shelf.getAlbum(u"alpha")
622         assert alpha.getTag() == u"alpha"
623
624     def test_setTag(self):
625         alpha = self.shelf.getAlbum(u"alpha")
626         alpha.setTag(u"alfa")
627         assert alpha.getTag() == u"alfa"
628
629     def test_getAlbumParents(self):
630         root = self.shelf.getRootAlbum()
631         alpha = self.shelf.getAlbum(u"alpha")
632         parents = list(alpha.getAlbumParents())
633         parents.sort(lambda x, y: cmp(x.getTag(), y.getTag()))
634         assert parents == [root]
635
636     def test_isAlbum(self):
637         assert self.shelf.getRootAlbum().isAlbum()
638
639 class TestPlainAlbum(TestShelfFixture):
640     def test_getType(self):
641         alpha = self.shelf.getAlbum(u"alpha")
642         assert alpha.getType() == "plain"
643
644     def test_isMutable(self):
645         alpha = self.shelf.getAlbum(u"alpha")
646         assert alpha.isMutable()
647
648     def test_getChildren(self):
649         epsilon = self.shelf.getAlbum(u"epsilon")
650         alpha = self.shelf.getAlbum(u"alpha")
651         beta = self.shelf.getAlbum(u"beta")
652         assert list(epsilon.getChildren()) == []
653         alphaChildren = list(alpha.getChildren())
654         assert list(beta.getChildren()) == [alphaChildren[-1]]
655
656     def test_getAlbumChildren(self):
657         alpha = self.shelf.getAlbum(u"alpha")
658         beta = self.shelf.getAlbum(u"beta")
659         epsilon = self.shelf.getAlbum(u"epsilon")
660         alphaAlbumChildren = list(alpha.getAlbumChildren())
661         assert alphaAlbumChildren == [beta]
662         assert list(epsilon.getAlbumChildren()) == []
663
664     def test_setChildren(self):
665         root = self.shelf.getRootAlbum()
666         beta = self.shelf.getAlbum(u"beta")
667         assert list(beta.getChildren()) != []
668         beta.setChildren([beta, root])
669         assert list(beta.getChildren()) == [beta, root]
670         beta.setChildren([]) # Break the cycle.
671         assert list(beta.getChildren()) == []
672
673 class TestImage(TestShelfFixture):
674     def test_getHash(self):
675         image = self.shelf.getImage(os.path.join(PICDIR, "arlaharen.png"))
676         assert image.getHash() == "39a1266d2689f53d48b09a5e0ca0af1f"
677
678     def test_getLocation(self):
679         location = os.path.join(PICDIR, "arlaharen.png")
680         image = self.shelf.getImage(location)
681         assert image.getLocation() == os.path.realpath(location)
682
683     def test_getModificationTime(self):
684         image = self.shelf.getImage(os.path.join(PICDIR, "arlaharen.png"))
685         t = image.getModificationTime()
686         assert isinstance(t, int)
687         assert t > 0
688
689     def test_getSize(self):
690         image = self.shelf.getImage(os.path.join(PICDIR, "arlaharen.png"))
691         assert image.getSize() == (304, 540)
692
693     def test_contentChanged(self):
694         path = os.path.join(PICDIR, "arlaharen.png")
695         self.shelf.deleteImage(path)
696         newpath = u"tmp.png"
697         try:
698             shutil.copy2(path, newpath)
699             image = self.shelf.createImage(newpath)
700             oldmtime = image.getModificationTime()
701             pilimg = PILImage.open(newpath)
702             pilimg.thumbnail((100, 100))
703             pilimg.save(newpath, "PNG")
704             image.contentChanged()
705             assert image.getHash() == "d55a9cc74371c09d484b163c71497cab"
706             assert image.getSize() == (56, 100)
707             assert image.getModificationTime() > oldmtime
708         finally:
709             try:
710                 os.unlink(newpath)
711             except OSError:
712                 pass
713
714     def test_locationChanged(self):
715         location = os.path.join(PICDIR, "arlaharen.png")
716         image = self.shelf.getImage(location)
717         image.locationChanged(u"/foo/../bar")
718         assert image.getLocation() == "/bar"
719
720     def test_isAlbum(self):
721         image = self.shelf.getImage(os.path.join(PICDIR, "arlaharen.png"))
722         assert not image.isAlbum()
723
724     def test_importExifTags(self):
725         image = self.shelf.getImage(os.path.join(PICDIR, "arlaharen.png"))
726         image.importExifTags() # TODO: Test more.
727
728 class TestOrphansAlbum(TestShelfFixture):
729     def test_getType(self):
730         orphans = self.shelf.getAlbum(u"orphans")
731         assert orphans.getType() == "orphans"
732
733     def test_isMutable(self):
734         orphans = self.shelf.getAlbum(u"orphans")
735         assert not orphans.isMutable()
736
737     def test_getChildren(self):
738         orphans = self.shelf.getAlbum(u"orphans")
739         assert len(list(orphans.getChildren())) == 2
740
741     def test_getAlbumChildren(self):
742         orphans = self.shelf.getAlbum(u"orphans")
743         epsilon = self.shelf.getAlbum(u"epsilon")
744         assert list(orphans.getAlbumChildren()) == [epsilon]
745
746     def test_setChildren(self):
747         orphans = self.shelf.getAlbum(u"orphans")
748         try:
749             orphans.setChildren([])
750         except UnsettableChildrenError:
751             pass
752         else:
753             assert False
754
755     def test_isAlbum(self):
756         assert self.shelf.getAlbum(u"orphans").isAlbum()
757
758 class TestSearchAlbum(TestShelfFixture):
759     def test_getType(self):
760         zeta = self.shelf.getAlbum(u"zeta")
761         assert zeta.getType() == "search"
762
763     def test_isMutable(self):
764         zeta = self.shelf.getAlbum(u"zeta")
765         assert not zeta.isMutable()
766
767     def test_getChildren(self):
768         alpha = self.shelf.getAlbum(u"alpha")
769         image1, image2 = list(alpha.getChildren())[0:2]
770         cat_a = self.shelf.getCategory(u"a")
771         cat_b = self.shelf.getCategory(u"b")
772         image1.addCategory(cat_a)
773         image2.addCategory(cat_b)
774         zeta = self.shelf.getAlbum(u"zeta")
775         assert zeta
776         zeta.setAttribute(u"query", u"b")
777         children = zeta.getChildren()
778         assert list(children) == [image2]
779
780     def test_getAlbumChildren(self):
781         alpha = self.shelf.getAlbum(u"alpha")
782         image1, image2 = list(alpha.getChildren())[0:2]
783         cat_a = self.shelf.getCategory(u"a")
784         cat_b = self.shelf.getCategory(u"b")
785         image1.addCategory(cat_a)
786         image2.addCategory(cat_b)
787         zeta = self.shelf.getAlbum(u"zeta")
788         assert zeta
789         zeta.setAttribute(u"query", u"b")
790         children = zeta.getAlbumChildren()
791         l = list(children)
792         assert list(children) == []
793
794     def test_setChildren(self):
795         zeta = self.shelf.getAlbum(u"zeta")
796         try:
797             zeta.setChildren([])
798         except UnsettableChildrenError:
799             pass
800         else:
801             assert False
802
803     def test_isAlbum(self):
804         assert self.shelf.getAlbum(u"zeta").isAlbum()
805
806 ######################################################################
807
808 removeTmpDb()
809 if __name__ == "__main__":
810     unittest.main()