mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
new tests for DB and file operations
Also, new organization for tests and automatic loader. Fixed bugs uncovered by new tests. --HG-- extra : convert_revision : svn%3A41726ec3-264d-0410-9c23-a9f1637257cc/trunk%4069
This commit is contained in:
parent
9090ef25b5
commit
cd124d2dad
7 changed files with 316 additions and 7 deletions
|
|
@ -61,9 +61,10 @@ def _ancestry(path):
|
|||
"""Return a list consisting of path's parent directory, its grandparent,
|
||||
and so on. For instance, _ancestry('/a/b/c') == ['/', '/a', '/a/b']."""
|
||||
out = []
|
||||
while path != '/':
|
||||
while path and path != '/':
|
||||
path = os.path.dirname(path)
|
||||
out.insert(0, path)
|
||||
if path: # don't yield ''
|
||||
out.insert(0, path)
|
||||
return out
|
||||
|
||||
def _walk_files(path):
|
||||
|
|
@ -143,6 +144,7 @@ class Item(object):
|
|||
c = self.library.conn.execute(
|
||||
'select * from items where id=?', (load_id,) )
|
||||
self._fill_record(c.fetchone())
|
||||
self._clear_dirty()
|
||||
c.close()
|
||||
|
||||
def store(self, store_id=None, store_all=False):
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
import unittest
|
||||
|
||||
test_modules = ['test_mediafile', 'test_library']
|
||||
import os
|
||||
import re
|
||||
|
||||
def suite():
|
||||
s = unittest.TestSuite()
|
||||
for mod in map(__import__, test_modules):
|
||||
s.addTest(mod.suite())
|
||||
# get the suite() of every module in this directory begining with test_
|
||||
for fname in os.listdir('.'):
|
||||
match = re.match(r'(test_\S+)\.py', fname)
|
||||
if match:
|
||||
s.addTest(__import__(match.group(1)).suite())
|
||||
return s
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
Binary file not shown.
162
test/test_db.py
Executable file
162
test/test_db.py
Executable file
|
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Tests for non-query database functions of Item.
|
||||
"""
|
||||
|
||||
import unittest, sys, os
|
||||
sys.path.append('..')
|
||||
import beets.library
|
||||
|
||||
def lib(): return beets.library.Library('rsrc' + os.sep + 'test.blb')
|
||||
def boracay(l): return beets.library.Item(l.conn.execute('select * from items '
|
||||
'where id=3').fetchone(), l)
|
||||
def item(lib=None): return beets.library.Item({
|
||||
'title': u'the title',
|
||||
'artist': u'the artist',
|
||||
'album': u'the album',
|
||||
'genre': u'the genre',
|
||||
'composer': u'the composer',
|
||||
'grouping': u'the grouping',
|
||||
'year': 1,
|
||||
'track': 2,
|
||||
'tracktotal': 3,
|
||||
'disc': 4,
|
||||
'disctotal': 5,
|
||||
'lyrics': u'the lyrics',
|
||||
'comments': u'the comments',
|
||||
'bpm': 6,
|
||||
'comp': True,
|
||||
'path': 'somepath',
|
||||
}, lib)
|
||||
|
||||
class LoadTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lib = lib()
|
||||
self.i = boracay(self.lib)
|
||||
def tearDown(self):
|
||||
self.lib.conn.close()
|
||||
|
||||
def test_load_restores_data_from_db(self):
|
||||
original_title = self.i.title
|
||||
self.i.title = 'something'
|
||||
self.i.load()
|
||||
self.assertEqual(original_title, self.i.title)
|
||||
|
||||
def test_load_clears_dirty_flags(self):
|
||||
self.i.artist = 'something'
|
||||
self.i.load()
|
||||
self.assertTrue(not self.i.dirty['artist'])
|
||||
|
||||
class StoreTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lib = lib()
|
||||
self.i = boracay(self.lib)
|
||||
def tearDown(self):
|
||||
self.lib.conn.close()
|
||||
|
||||
def test_store_changes_database_value(self):
|
||||
self.i.year = 1987
|
||||
self.i.store()
|
||||
new_year = self.lib.conn.execute('select year from items where '
|
||||
'title="Boracay"').fetchone()['year']
|
||||
self.assertEqual(new_year, 1987)
|
||||
|
||||
def test_store_only_writes_dirty_fields(self):
|
||||
original_genre = self.i.genre
|
||||
self.i.record['genre'] = 'beatboxing' # change value w/o dirtying
|
||||
self.i.store()
|
||||
new_genre = self.lib.conn.execute('select genre from items where '
|
||||
'title="Boracay"').fetchone()['genre']
|
||||
self.assertEqual(new_genre, original_genre)
|
||||
|
||||
def test_store_clears_dirty_flags(self):
|
||||
self.i.composer = 'tvp'
|
||||
self.i.store()
|
||||
self.assertTrue(not self.i.dirty['composer'])
|
||||
|
||||
class AddTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lib = lib()
|
||||
self.i = item(self.lib)
|
||||
def tearDown(self):
|
||||
self.lib.conn.close()
|
||||
|
||||
def test_add_inserts_row(self):
|
||||
self.i.add()
|
||||
new_grouping = self.lib.conn.execute('select grouping from items '
|
||||
'where composer="the composer"').fetchone()['grouping']
|
||||
self.assertEqual(new_grouping, self.i.grouping)
|
||||
|
||||
class RemoveTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lib = lib()
|
||||
self.i = boracay(self.lib)
|
||||
def tearDown(self):
|
||||
self.lib.conn.close()
|
||||
|
||||
def test_remove_deletes_from_db(self):
|
||||
self.i.remove()
|
||||
c = self.lib.conn.execute('select * from items where id=3')
|
||||
self.assertEqual(c.fetchone(), None)
|
||||
|
||||
class GetSetTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.i = item()
|
||||
|
||||
def test_set_changes_value(self):
|
||||
self.i.bpm = 4915
|
||||
self.assertEqual(self.i.bpm, 4915)
|
||||
|
||||
def test_set_sets_dirty_flag(self):
|
||||
self.i.comp = True
|
||||
self.assertTrue(self.i.dirty['comp'])
|
||||
|
||||
class DestinationTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lib = beets.library.Library(':memory:')
|
||||
self.i = item(self.lib)
|
||||
def tearDown(self):
|
||||
self.lib.conn.close()
|
||||
|
||||
def test_directory_works_with_trailing_slash(self):
|
||||
self.lib.options['directory'] = 'one/'
|
||||
self.lib.options['path_format'] = 'two'
|
||||
self.assertEqual(self.i.destination(), 'one/two')
|
||||
|
||||
def test_directory_works_without_trailing_slash(self):
|
||||
self.lib.options['directory'] = 'one'
|
||||
self.lib.options['path_format'] = 'two'
|
||||
self.assertEqual(self.i.destination(), 'one/two')
|
||||
|
||||
def test_destination_substitues_metadata_values(self):
|
||||
self.lib.options['directory'] = 'base'
|
||||
self.lib.options['path_format'] = '$album/$artist $title'
|
||||
self.i.title = 'three'
|
||||
self.i.artist = 'two'
|
||||
self.i.album = 'one'
|
||||
self.assertEqual(self.i.destination(), 'base/one/two three')
|
||||
|
||||
def test_destination_substitutes_extension(self):
|
||||
self.lib.options['directory'] = 'base'
|
||||
self.lib.options['path_format'] = '$extension'
|
||||
self.i.path = 'hey.audioFormat'
|
||||
self.assertEqual(self.i.destination(), 'base/audioFormat')
|
||||
|
||||
def test_destination_pads_some_indices(self):
|
||||
self.lib.options['directory'] = 'base'
|
||||
self.lib.options['path_format'] = '$track $tracktotal ' \
|
||||
'$disc $disctotal $bpm $year'
|
||||
self.i.track = 1
|
||||
self.i.tracktotal = 2
|
||||
self.i.disc = 3
|
||||
self.i.disctotal = 4
|
||||
self.i.bpm = 5
|
||||
self.i.year = 6
|
||||
self.assertEqual(self.i.destination(), 'base/01 02 03 04 5 6')
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='suite')
|
||||
131
test/test_files.py
Executable file
131
test/test_files.py
Executable file
|
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Test file manipulation functionality of Item.
|
||||
"""
|
||||
|
||||
import unittest, shutil, sys, os
|
||||
sys.path.append('..')
|
||||
import beets.library
|
||||
from os.path import join
|
||||
|
||||
def mkfile(path):
|
||||
open(path, 'w').close()
|
||||
|
||||
class MoveTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# make a temporary file
|
||||
self.path = join('rsrc', 'temp.mp3')
|
||||
shutil.copy(join('rsrc', 'full.mp3'), self.path)
|
||||
|
||||
# add it to a temporary library
|
||||
self.lib = beets.library.Library(':memory:')
|
||||
self.i = beets.library.Item.from_path(self.path)
|
||||
self.i.add(self.lib)
|
||||
|
||||
# set up the destination
|
||||
self.libdir = join('rsrc', 'testlibdir')
|
||||
self.lib.options['directory'] = self.libdir
|
||||
self.lib.options['path_format'] = join('$artist',
|
||||
'$album', '$title')
|
||||
self.i.artist = 'one'
|
||||
self.i.album = 'two'
|
||||
self.i.title = 'three'
|
||||
self.dest = join(self.libdir, 'one', 'two', 'three')
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.path):
|
||||
os.remove(self.path)
|
||||
if os.path.exists(self.libdir):
|
||||
shutil.rmtree(self.libdir)
|
||||
|
||||
def test_move_arrives(self):
|
||||
self.i.move()
|
||||
self.assertTrue(os.path.exists(self.dest))
|
||||
|
||||
def test_move_departs(self):
|
||||
self.i.move()
|
||||
self.assertTrue(not os.path.exists(self.path))
|
||||
|
||||
def test_copy_arrives(self):
|
||||
self.i.move(copy=True)
|
||||
self.assertTrue(os.path.exists(self.dest))
|
||||
|
||||
def test_copy_does_not_depart(self):
|
||||
self.i.move(copy=True)
|
||||
self.assertTrue(os.path.exists(self.path))
|
||||
|
||||
def test_move_changes_path(self):
|
||||
self.i.move()
|
||||
self.assertEqual(self.i.path,self.dest)
|
||||
|
||||
class DeleteTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# make a temporary file
|
||||
self.path = join('rsrc', 'temp.mp3')
|
||||
shutil.copy(join('rsrc', 'full.mp3'), self.path)
|
||||
|
||||
# add it to a temporary library
|
||||
self.lib = beets.library.Library(':memory:')
|
||||
self.i = beets.library.Item.from_path(self.path)
|
||||
self.i.add(self.lib)
|
||||
def tearDown(self):
|
||||
# make sure the temp file is gone
|
||||
if os.path.exists(self.path):
|
||||
os.remove(self.path)
|
||||
|
||||
def test_delete_deletes_file(self):
|
||||
self.i.delete()
|
||||
self.assertTrue(not os.path.exists(self.path))
|
||||
|
||||
def test_delete_removes_from_db(self):
|
||||
self.i.delete()
|
||||
c = self.lib.conn.execute('select * from items where 1')
|
||||
self.assertEqual(c.fetchone(), None)
|
||||
|
||||
class WalkTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# create a directory structure for testing
|
||||
self.base = join('rsrc', 'temp_walk')
|
||||
os.mkdir(self.base)
|
||||
mkfile(join(self.base, 'file'))
|
||||
os.mkdir(join(self.base, 'dir1'))
|
||||
mkfile(join(self.base, 'dir1', 'dir1f1'))
|
||||
mkfile(join(self.base, 'dir1', 'dir1f2'))
|
||||
os.mkdir(join(self.base, 'dir2'))
|
||||
mkfile(join(self.base, 'dir2', 'dir2f'))
|
||||
os.mkdir(join(self.base, 'dir2', 'dir2dir'))
|
||||
mkfile(join(self.base, 'dir2', 'dir2dir', 'dir2dirf'))
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.base)
|
||||
|
||||
def test_walk_single_file(self):
|
||||
path = join(self.base, 'file')
|
||||
s = set(beets.library._walk_files(path))
|
||||
self.assertTrue(path in s)
|
||||
s.remove(path)
|
||||
self.assertTrue(not s) # s is empty (i.e., contains nothing else)
|
||||
|
||||
def test_walk_flat_directory(self):
|
||||
path = join(self.base, 'dir1')
|
||||
s = set(beets.library._walk_files(path))
|
||||
for f in (join(path, 'dir1f1'),
|
||||
join(path, 'dir1f2')):
|
||||
self.assertTrue(f in s)
|
||||
s.remove(f)
|
||||
self.assertTrue(not s)
|
||||
|
||||
def test_walk_hierarchy(self):
|
||||
path = join(self.base, 'dir2')
|
||||
s = set(beets.library._walk_files(path))
|
||||
for f in (join(path, 'dir2f'),
|
||||
join(path, 'dir2dir', 'dir2dirf')):
|
||||
self.assertTrue(f in s)
|
||||
s.remove(f)
|
||||
self.assertTrue(not s)
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='suite')
|
||||
|
|
@ -1,8 +1,14 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Test the MediaFile metadata layer.
|
||||
"""
|
||||
|
||||
import unittest, sys, os, shutil
|
||||
sys.path.append('..')
|
||||
import beets.mediafile
|
||||
|
||||
|
||||
def MakeReadingTest(path, correct_dict, field):
|
||||
class ReadingTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Various tests for querying the library database.
|
||||
"""
|
||||
|
||||
import unittest, sys, os
|
||||
sys.path.append('..')
|
||||
import beets.library
|
||||
|
|
@ -43,7 +48,7 @@ class QueryParseTest(unittest.TestCase):
|
|||
|
||||
class GetTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lib = beets.library.Library('rsrc' + os.sep + 'get.blb')
|
||||
self.lib = beets.library.Library('rsrc' + os.sep + 'test.blb')
|
||||
|
||||
def assert_matched(self, result_iterator, title):
|
||||
self.assertEqual(result_iterator.next().title, title)
|
||||
Loading…
Reference in a new issue