Add captureStdout helper and mocks to some tests

This commit is contained in:
Thomas Scholtes 2014-04-12 16:49:54 +02:00
parent 65fcb8a28c
commit e5104784c6
3 changed files with 105 additions and 99 deletions

View file

@ -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.

View file

@ -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__)

View file

@ -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):