diff --git a/beetsplug/convert.py b/beetsplug/convert.py index 7dd1b0aa6..0e0cadafd 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -180,7 +180,6 @@ def convert_item(dest_dir, keep_new, path_formats): if keep_new: # If we're keeping the transcoded file, read it again (after # writing) to get new bitrate, duration, etc. - item.path = dest item.read() item.store() # Store new path and audio data. diff --git a/setup.py b/setup.py index 589a1076c..af8c55466 100755 --- a/setup.py +++ b/setup.py @@ -82,6 +82,7 @@ setup(name='beets', tests_require=[ 'responses', + 'pathlib', ], # Plugin (optional) dependencies: diff --git a/test/helper.py b/test/helper.py index cd60a6aa0..e00705b50 100644 --- a/test/helper.py +++ b/test/helper.py @@ -12,22 +12,42 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. +import sys import os import os.path import shutil import tempfile +from pathlib import Path from glob import glob +from contextlib import contextmanager +from StringIO import StringIO import beets from beets import config import beets.plugins -from beets.library import Library +from beets.library import Library, Item # TODO Move this here, along with AutotagMock from test_importer import TestImportSession import _common +@contextmanager +def controlStdin(input=None): + """Sends ``input`` to stdin. + + >>> with controlStdin('yes'): + ... in = input() + 'yes' + """ + org = sys.stdin + sys.stdin = StringIO(input) + sys.stdin.encoding = 'utf8' + try: + yield sys.stdin + finally: + sys.stdin = org + class TestHelper(object): """Helper mixin for high-level cli and plugin tests. @@ -97,6 +117,8 @@ class TestHelper(object): """Unload all plugins and remove the from the configuration. """ beets.config['plugins'] = [] + for plugin in beets.plugins._classes: + plugin.listeners = None beets.plugins._classes = set() beets.plugins._instances = {} @@ -119,3 +141,17 @@ class TestHelper(object): return TestImportSession(self.lib, logfile=None, query=None, paths=[import_dir]) + + def add_item_fixtures(self, ext='mp3', count=1): + items = [] + paths = list(Path(_common.RSRC).glob('*.' + ext)) + for path in paths[0:count]: + item = Item.from_path(str(path)) + item.add(self.lib) + item.move(copy=True) + item.store() + items.append(item) + return items + + def run_command(self, *args): + beets.ui._raw_main(list(args)) diff --git a/test/test_convert.py b/test/test_convert.py index fcd109d94..093b37784 100644 --- a/test/test_convert.py +++ b/test/test_convert.py @@ -13,8 +13,9 @@ # included in all copies or substantial portions of the Software. import os.path +from pathlib import Path from _common import unittest -from helper import TestHelper +from helper import TestHelper, controlStdin class ImportConvertTest(unittest.TestCase, TestHelper): @@ -40,6 +41,36 @@ class ImportConvertTest(unittest.TestCase, TestHelper): self.assertIsNotNone(item) self.assertTrue(os.path.isfile(item.path)) +class ImportCliTest(unittest.TestCase, TestHelper): + + def setUp(self): + self.setup_beets() + self.item, = self.add_item_fixtures(ext='ogg') + self.load_plugins('convert') + + self.convert_dest = Path(self.temp_dir) / 'convert_dest' + self.config['convert']['dest'] = str(self.convert_dest) + self.config['convert']['command'] = u'cp $source $dest' + self.config['convert']['paths']['default'] = u'converted' + + def tearDown(self): + self.teardown_beets() + self.unload_plugins() + + def test_convert(self): + with controlStdin('y'): + self.run_command('convert', self.item.path) + converted = Path(self.convert_dest) / 'converted.mp3' + self.assertTrue(converted.is_file()) + + def test_convert_keep_new(self): + self.assertEqual(Path(self.item.path).suffix, '.ogg') + + with controlStdin('y'): + self.run_command('convert', '--keep-new', self.item.path) + + self.item.load() + self.assertEqual(Path(self.item.path).suffix, '.mp3') def suite(): return unittest.TestLoader().loadTestsFromName(__name__) diff --git a/tox.ini b/tox.ini index efa90aaf0..ee9593cee 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,7 @@ deps = pylast flask responses + pathlib commands = nosetests {posargs} sitepackages = True