mirror of
https://github.com/beetbox/beets.git
synced 2026-02-16 12:24:53 +01:00
Add captureStdout helper and mocks to some tests
This commit is contained in:
parent
65fcb8a28c
commit
e5104784c6
3 changed files with 105 additions and 99 deletions
|
|
@ -48,6 +48,25 @@ def controlStdin(input=None):
|
|||
sys.stdin = org
|
||||
|
||||
|
||||
@contextmanager
|
||||
def captureStdout():
|
||||
"""Save stdout in a StringIO.
|
||||
|
||||
>>> with captureStdout() as output:
|
||||
... print('spam')
|
||||
...
|
||||
>>> output.getvalue()
|
||||
'spam'
|
||||
"""
|
||||
org = sys.stdout
|
||||
sys.stdout = StringIO()
|
||||
sys.stdout.encoding = 'utf8'
|
||||
try:
|
||||
yield sys.stdout
|
||||
finally:
|
||||
sys.stdout = org
|
||||
|
||||
|
||||
class TestHelper(object):
|
||||
"""Helper mixin for high-level cli and plugin tests.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
import os
|
||||
import yaml
|
||||
from mock import patch
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
|
||||
from beets import ui
|
||||
from beets import config
|
||||
from beets.library import Library
|
||||
|
||||
import _common
|
||||
from _common import unittest
|
||||
from helper import TestHelper
|
||||
from helper import TestHelper, captureStdout
|
||||
|
||||
|
||||
class ConfigCommandTest(_common.TestCase, TestHelper):
|
||||
class ConfigCommandTest(unittest.TestCase, TestHelper):
|
||||
|
||||
def setUp(self):
|
||||
super(ConfigCommandTest, self).setUp()
|
||||
self.io.install()
|
||||
|
||||
self.temp_dir = mkdtemp()
|
||||
if 'EDITOR' in os.environ:
|
||||
del os.environ['EDITOR']
|
||||
|
||||
|
|
@ -33,89 +33,78 @@ class ConfigCommandTest(_common.TestCase, TestHelper):
|
|||
config._materialized = False
|
||||
|
||||
def tearDown(self):
|
||||
super(ConfigCommandTest, self).tearDown()
|
||||
self.execlp_restore()
|
||||
rmtree(self.temp_dir)
|
||||
|
||||
def test_show_user_config(self):
|
||||
self.run_command('config')
|
||||
output = yaml.load(self.io.getoutput())
|
||||
with captureStdout() as output:
|
||||
self.run_command('config')
|
||||
output = yaml.load(output.getvalue())
|
||||
self.assertEqual(output['option'], 'value')
|
||||
|
||||
def test_show_user_config_with_defaults(self):
|
||||
self.run_command('config', '-d')
|
||||
output = yaml.load(self.io.getoutput())
|
||||
with captureStdout() as output:
|
||||
self.run_command('config', '-d')
|
||||
output = yaml.load(output.getvalue())
|
||||
self.assertEqual(output['option'], 'value')
|
||||
self.assertEqual(output['library'], 'lib')
|
||||
self.assertEqual(output['import']['timid'], False)
|
||||
|
||||
def test_show_user_config_with_cli(self):
|
||||
self.run_command('--config', self.cli_config_path, 'config')
|
||||
output = yaml.load(self.io.getoutput())
|
||||
with captureStdout() as output:
|
||||
self.run_command('--config', self.cli_config_path, 'config')
|
||||
output = yaml.load(output.getvalue())
|
||||
self.assertEqual(output['library'], 'lib')
|
||||
self.assertEqual(output['option'], 'cli overwrite')
|
||||
|
||||
def test_config_paths(self):
|
||||
self.run_command('config', '-p')
|
||||
paths = self.io.getoutput().split('\n')
|
||||
with captureStdout() as output:
|
||||
self.run_command('config', '-p')
|
||||
paths = output.getvalue().split('\n')
|
||||
self.assertEqual(len(paths), 2)
|
||||
self.assertEqual(paths[0], self.config_path)
|
||||
|
||||
def test_config_paths_with_cli(self):
|
||||
self.run_command('--config', self.cli_config_path, 'config', '-p')
|
||||
paths = self.io.getoutput().split('\n')
|
||||
with captureStdout() as output:
|
||||
self.run_command('--config', self.cli_config_path, 'config', '-p')
|
||||
paths = output.getvalue().split('\n')
|
||||
self.assertEqual(len(paths), 3)
|
||||
self.assertEqual(paths[0], self.cli_config_path)
|
||||
|
||||
def test_edit_config_with_editor_env(self):
|
||||
self.execlp_stub()
|
||||
os.environ['EDITOR'] = 'myeditor'
|
||||
|
||||
self.run_command('config', '-e')
|
||||
self.assertEqual(self._execlp_call, ['myeditor', self.config_path])
|
||||
with patch('os.execlp') as execlp:
|
||||
self.run_command('config', '-e')
|
||||
execlp.assert_called_once_with(
|
||||
'myeditor', 'myeditor', self.config_path)
|
||||
|
||||
def test_edit_config_with_open(self):
|
||||
self.execlp_stub()
|
||||
|
||||
with _common.system_mock('Darwin'):
|
||||
self.run_command('config', '-e')
|
||||
self.assertEqual(self._execlp_call, ['open', '-n', self.config_path])
|
||||
|
||||
with patch('os.execlp') as execlp:
|
||||
self.run_command('config', '-e')
|
||||
execlp.assert_called_once_with(
|
||||
'open', 'open', '-n', self.config_path)
|
||||
|
||||
def test_edit_config_with_xdg_open(self):
|
||||
self.execlp_stub()
|
||||
|
||||
with _common.system_mock('Linux'):
|
||||
self.run_command('config', '-e')
|
||||
self.assertEqual(self._execlp_call, ['xdg-open', self.config_path])
|
||||
with patch('os.execlp') as execlp:
|
||||
self.run_command('config', '-e')
|
||||
execlp.assert_called_once_with(
|
||||
'xdg-open', 'xdg-open', self.config_path)
|
||||
|
||||
def test_edit_config_with_windows_exec(self):
|
||||
self.execlp_stub()
|
||||
|
||||
with _common.system_mock('Windows'):
|
||||
self.run_command('config', '-e')
|
||||
self.assertEqual(self._execlp_call, [self.config_path])
|
||||
with patch('os.execlp') as execlp:
|
||||
self.run_command('config', '-e')
|
||||
execlp.assert_called_once_with(self.config_path, self.config_path)
|
||||
|
||||
def test_config_editor_not_found(self):
|
||||
def raise_os_error(*args):
|
||||
raise OSError
|
||||
os.execlp = raise_os_error
|
||||
with self.assertRaises(ui.UserError) as user_error:
|
||||
self.run_command('config', '-e')
|
||||
with patch('os.execlp') as execlp:
|
||||
execlp.side_effect = OSError()
|
||||
self.run_command('config', '-e')
|
||||
self.assertIn('Could not edit configuration',
|
||||
str(user_error.exception.args[0]))
|
||||
|
||||
def execlp_stub(self):
|
||||
self._execlp_call = None
|
||||
def _execlp_stub(file, *args):
|
||||
self._execlp_call = [file] + list(args[1:])
|
||||
|
||||
self._orig_execlp = os.execlp
|
||||
os.execlp = _execlp_stub
|
||||
|
||||
def execlp_restore(self):
|
||||
if hasattr(self, '_orig_execlp'):
|
||||
os.execlp = self._orig_execlp
|
||||
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import subprocess
|
|||
|
||||
import _common
|
||||
from _common import unittest
|
||||
from helper import captureStdout
|
||||
|
||||
from beets import library
|
||||
from beets import ui
|
||||
from beets.ui import commands
|
||||
|
|
@ -33,85 +35,81 @@ from beets import plugins
|
|||
from beets.util.confit import ConfigError
|
||||
|
||||
|
||||
class ListTest(_common.TestCase):
|
||||
class ListTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
super(ListTest, self).setUp()
|
||||
self.io.install()
|
||||
|
||||
self.lib = library.Library(':memory:')
|
||||
i = _common.item()
|
||||
i.path = 'xxx/yyy'
|
||||
self.lib.add(i)
|
||||
self.lib.add_album([i])
|
||||
self.item = i
|
||||
self.item = _common.item()
|
||||
self.item.path = 'xxx/yyy'
|
||||
self.lib.add(self.item)
|
||||
self.lib.add_album([self.item])
|
||||
|
||||
def _run_list(self, query='', album=False, path=False, fmt=None):
|
||||
commands.list_items(self.lib, query, album, fmt)
|
||||
|
||||
def test_list_outputs_item(self):
|
||||
self._run_list()
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'the title' in out)
|
||||
with captureStdout() as stdout:
|
||||
self._run_list()
|
||||
self.assertIn(u'the title', stdout.getvalue())
|
||||
|
||||
def test_list_unicode_query(self):
|
||||
self.item.title = u'na\xefve'
|
||||
self.item.store()
|
||||
self.lib._connection().commit()
|
||||
|
||||
self._run_list([u'na\xefve'])
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'na\xefve' in out.decode(self.io.stdout.encoding))
|
||||
with captureStdout() as stdout:
|
||||
self._run_list([u'na\xefve'])
|
||||
out = stdout.getvalue()
|
||||
self.assertTrue(u'na\xefve' in out.decode(stdout.encoding))
|
||||
|
||||
def test_list_item_path(self):
|
||||
self._run_list(fmt='$path')
|
||||
out = self.io.getoutput()
|
||||
self.assertEqual(out.strip(), u'xxx/yyy')
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(fmt='$path')
|
||||
self.assertEqual(stdout.getvalue().strip(), u'xxx/yyy')
|
||||
|
||||
def test_list_album_outputs_something(self):
|
||||
self._run_list(album=True)
|
||||
out = self.io.getoutput()
|
||||
self.assertGreater(len(out), 0)
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(album=True)
|
||||
self.assertGreater(len(stdout.getvalue()), 0)
|
||||
|
||||
def test_list_album_path(self):
|
||||
self._run_list(album=True, fmt='$path')
|
||||
out = self.io.getoutput()
|
||||
self.assertEqual(out.strip(), u'xxx')
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(album=True, fmt='$path')
|
||||
self.assertEqual(stdout.getvalue().strip(), u'xxx')
|
||||
|
||||
def test_list_album_omits_title(self):
|
||||
self._run_list(album=True)
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'the title' not in out)
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(album=True)
|
||||
self.assertNotIn(u'the title', stdout.getvalue())
|
||||
|
||||
def test_list_uses_track_artist(self):
|
||||
self._run_list()
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'the artist' in out)
|
||||
self.assertTrue(u'the album artist' not in out)
|
||||
with captureStdout() as stdout:
|
||||
self._run_list()
|
||||
self.assertIn(u'the artist', stdout.getvalue())
|
||||
self.assertNotIn(u'the album artist', stdout.getvalue())
|
||||
|
||||
def test_list_album_uses_album_artist(self):
|
||||
self._run_list(album=True)
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'the artist' not in out)
|
||||
self.assertTrue(u'the album artist' in out)
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(album=True)
|
||||
self.assertNotIn(u'the artist', stdout.getvalue())
|
||||
self.assertIn(u'the album artist', stdout.getvalue())
|
||||
|
||||
def test_list_item_format_artist(self):
|
||||
self._run_list(fmt='$artist')
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'the artist' in out)
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(fmt='$artist')
|
||||
self.assertIn(u'the artist', stdout.getvalue())
|
||||
|
||||
def test_list_item_format_multiple(self):
|
||||
self._run_list(fmt='$artist - $album - $year')
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'1' in out)
|
||||
self.assertTrue(u'the album' in out)
|
||||
self.assertTrue(u'the artist' in out)
|
||||
self.assertEqual(u'the artist - the album - 0001', out.strip())
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(fmt='$artist - $album - $year')
|
||||
self.assertEqual(u'the artist - the album - 0001',
|
||||
stdout.getvalue().strip())
|
||||
|
||||
def test_list_album_format(self):
|
||||
self._run_list(album=True, fmt='$genre')
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'the genre' in out)
|
||||
self.assertTrue(u'the album' not in out)
|
||||
with captureStdout() as stdout:
|
||||
self._run_list(album=True, fmt='$genre')
|
||||
self.assertIn(u'the genre', stdout.getvalue())
|
||||
self.assertNotIn(u'the album', stdout.getvalue())
|
||||
|
||||
|
||||
class RemoveTest(_common.TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue