Merge branch 'develop' into feature/switch-to-gst-mixers
Conflicts: mopidy/gstreamer.py
This commit is contained in:
commit
114bc10ae8
@ -18,11 +18,19 @@ v0.8 (in development)
|
||||
Track position and CPID was intermixed, so it would cause a crash if a CPID
|
||||
matching the track position didn't exist. (Fixes: :issue:`162`)
|
||||
|
||||
- Removed most traces of multiple outputs support. Having this feature
|
||||
currently seems to be more trouble than what it is worth.
|
||||
:attr:`mopidy.settings.OUTPUTS` setting is no longer supported, and has been
|
||||
replaced with :attr:`mopidy.settings.OUTPUT` which is a GStreamer
|
||||
bin described in the same format as ``gst-launch`` expects. Default value is
|
||||
- Added :option:`--list-deps` option to :cmd:`mopidy` command that lists
|
||||
required and optional dependencies, their current versions, and some other
|
||||
information useful for debugging. (Fixes: :issue:`74`)
|
||||
|
||||
- When unknown settings are encountered, we now check if it's similar to a
|
||||
known setting, and suggests to the user what we think the setting should have
|
||||
been.
|
||||
|
||||
- Removed multiple outputs support. Having this feature currently seems to be
|
||||
more trouble than what it is worth. The :attr:`mopidy.settings.OUTPUTS`
|
||||
setting is no longer supported, and has been replaced with
|
||||
:attr:`mopidy.settings.OUTPUT` which is a GStreamer bin description string in
|
||||
the same format as ``gst-launch`` expects. Default value is
|
||||
``autoaudiosink``.
|
||||
|
||||
|
||||
|
||||
@ -157,13 +157,13 @@ server simultaneously. To use the SHOUTcast output, do the following:
|
||||
#. Install, configure and start the Icecast server. It can be found in the
|
||||
``icecast2`` package in Debian/Ubuntu.
|
||||
|
||||
#. Set :attr:`mopidy.settings.OUTPUT` to ``lame ! shout2send`` (an Ogg Vorbis
|
||||
encoder could be used instead of lame).
|
||||
#. Set :attr:`mopidy.settings.OUTPUT` to ``lame ! shout2send``. An Ogg Vorbis
|
||||
encoder could be used instead of the lame MP3 encoder.
|
||||
|
||||
#. You might also need to change the ``shout2send`` default settings, run
|
||||
``gst-inspect-0.10 shout2send`` to see the available settings. Most likely
|
||||
you want to change ``ip``, ``username``, ``password`` and ``mount``. For
|
||||
example, to set the password use:
|
||||
you want to change ``ip``, ``username``, ``password``, and ``mount``. For
|
||||
example, to set the username and password, use:
|
||||
``lame ! shout2send username="foobar" password="s3cret"``.
|
||||
|
||||
Other advanced setups are also possible for outputs. Basically anything you can
|
||||
|
||||
@ -22,6 +22,7 @@ from mopidy import (get_version, settings, OptionalDependencyError,
|
||||
SettingsError, DATA_PATH, SETTINGS_PATH, SETTINGS_FILE)
|
||||
from mopidy.gstreamer import GStreamer
|
||||
from mopidy.utils import get_class
|
||||
from mopidy.utils.deps import list_deps_optparse_callback
|
||||
from mopidy.utils.log import setup_logging
|
||||
from mopidy.utils.path import get_or_create_folder, get_or_create_file
|
||||
from mopidy.utils.process import (exit_handler, stop_remaining_actors,
|
||||
@ -77,6 +78,9 @@ def parse_options():
|
||||
parser.add_option('--list-settings',
|
||||
action='callback', callback=list_settings_optparse_callback,
|
||||
help='list current settings')
|
||||
parser.add_option('--list-deps',
|
||||
action='callback', callback=list_deps_optparse_callback,
|
||||
help='list dependencies and their versions')
|
||||
return parser.parse_args(args=mopidy_args)[0]
|
||||
|
||||
def check_old_folders():
|
||||
|
||||
@ -196,7 +196,7 @@ def _list_build_query(field, mpd_query):
|
||||
if error.message == 'No closing quotation':
|
||||
raise MpdArgError(u'Invalid unquoted character', command=u'list')
|
||||
else:
|
||||
raise error
|
||||
raise
|
||||
tokens = [t.decode('utf-8') for t in tokens]
|
||||
if len(tokens) == 1:
|
||||
if field == u'album':
|
||||
|
||||
@ -151,7 +151,6 @@ class FakeMixer(gst.Element, gst.ImplementsInterface, gst.interfaces.Mixer):
|
||||
def set_record(self, track, record):
|
||||
pass
|
||||
|
||||
|
||||
gobject.type_register(FakeMixer)
|
||||
gst.element_register (FakeMixer, 'fakemixer', gst.RANK_MARGINAL)
|
||||
|
||||
|
||||
193
mopidy/utils/deps.py
Normal file
193
mopidy/utils/deps.py
Normal file
@ -0,0 +1,193 @@
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
|
||||
import pygst
|
||||
pygst.require('0.10')
|
||||
import gst
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy.utils.log import indent
|
||||
|
||||
|
||||
def list_deps_optparse_callback(*args):
|
||||
"""
|
||||
Prints a list of all dependencies.
|
||||
|
||||
Called by optparse when Mopidy is run with the :option:`--list-deps`
|
||||
option.
|
||||
"""
|
||||
print format_dependency_list()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def format_dependency_list(adapters=None):
|
||||
if adapters is None:
|
||||
adapters = [
|
||||
platform_info,
|
||||
python_info,
|
||||
gstreamer_info,
|
||||
pykka_info,
|
||||
pyspotify_info,
|
||||
pylast_info,
|
||||
dbus_info,
|
||||
serial_info,
|
||||
]
|
||||
|
||||
lines = []
|
||||
for adapter in adapters:
|
||||
dep_info = adapter()
|
||||
lines.append('%(name)s: %(version)s' % {
|
||||
'name': dep_info['name'],
|
||||
'version': dep_info.get('version', 'not found'),
|
||||
})
|
||||
if 'path' in dep_info:
|
||||
lines.append(' Imported from: %s' % (
|
||||
os.path.dirname(dep_info['path'])))
|
||||
if 'other' in dep_info:
|
||||
lines.append(' Other: %s' % (
|
||||
indent(dep_info['other'])),)
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
def platform_info():
|
||||
return {
|
||||
'name': 'Platform',
|
||||
'version': platform.platform(),
|
||||
}
|
||||
|
||||
|
||||
def python_info():
|
||||
return {
|
||||
'name': 'Python',
|
||||
'version': '%s %s' % (platform.python_implementation(),
|
||||
platform.python_version()),
|
||||
'path': platform.__file__,
|
||||
}
|
||||
|
||||
|
||||
def gstreamer_info():
|
||||
other = []
|
||||
other.append('Python wrapper: gst-python %s' % (
|
||||
'.'.join(map(str, gst.get_pygst_version()))))
|
||||
other.append('Relevant elements:')
|
||||
for name, status in _gstreamer_check_elements():
|
||||
other.append(' %s: %s' % (name, 'OK' if status else 'not found'))
|
||||
return {
|
||||
'name': 'GStreamer',
|
||||
'version': '.'.join(map(str, gst.get_gst_version())),
|
||||
'path': gst.__file__,
|
||||
'other': '\n'.join(other),
|
||||
}
|
||||
|
||||
|
||||
def _gstreamer_check_elements():
|
||||
elements_to_check = [
|
||||
# Core playback
|
||||
'uridecodebin',
|
||||
|
||||
# External HTTP streams
|
||||
'souphttpsrc',
|
||||
|
||||
# Spotify
|
||||
'appsrc',
|
||||
|
||||
# Mixers and sinks
|
||||
'alsamixer',
|
||||
'alsasink',
|
||||
'ossmixer',
|
||||
'osssink',
|
||||
'oss4mixer',
|
||||
'oss4sink',
|
||||
'pulsemixer',
|
||||
'pulsesink',
|
||||
|
||||
# MP3 encoding and decoding
|
||||
'mp3parse',
|
||||
'mad',
|
||||
'id3demux',
|
||||
'id3v2mux',
|
||||
'lame',
|
||||
|
||||
# Ogg Vorbis encoding and decoding
|
||||
'vorbisdec',
|
||||
'vorbisenc',
|
||||
'vorbisparse',
|
||||
'oggdemux',
|
||||
'oggmux',
|
||||
'oggparse',
|
||||
|
||||
# Flac decoding
|
||||
'flacdec',
|
||||
'flacparse',
|
||||
|
||||
# Shoutcast output
|
||||
'shout2send',
|
||||
]
|
||||
known_elements = [factory.get_name() for factory in
|
||||
gst.registry_get_default().get_feature_list(gst.TYPE_ELEMENT_FACTORY)]
|
||||
return [(element, element in known_elements) for element in elements_to_check]
|
||||
|
||||
|
||||
def pykka_info():
|
||||
if hasattr(pykka, '__version__'):
|
||||
# Pykka >= 0.14
|
||||
version = pykka.__version__
|
||||
else:
|
||||
# Pykka < 0.14
|
||||
version = pykka.get_version()
|
||||
return {
|
||||
'name': 'Pykka',
|
||||
'version': version,
|
||||
'path': pykka.__file__,
|
||||
}
|
||||
|
||||
|
||||
def pyspotify_info():
|
||||
dep_info = {'name': 'pyspotify'}
|
||||
try:
|
||||
import spotify
|
||||
if hasattr(spotify, '__version__'):
|
||||
dep_info['version'] = spotify.__version__
|
||||
else:
|
||||
dep_info['version'] = '< 1.3'
|
||||
dep_info['path'] = spotify.__file__
|
||||
dep_info['other'] = 'Built for libspotify API version %d' % (
|
||||
spotify.api_version,)
|
||||
except ImportError:
|
||||
pass
|
||||
return dep_info
|
||||
|
||||
|
||||
def pylast_info():
|
||||
dep_info = {'name': 'pylast'}
|
||||
try:
|
||||
import pylast
|
||||
dep_info['version'] = pylast.__version__
|
||||
dep_info['path'] = pylast.__file__
|
||||
except ImportError:
|
||||
pass
|
||||
return dep_info
|
||||
|
||||
|
||||
def dbus_info():
|
||||
dep_info = {'name': 'dbus-python'}
|
||||
try:
|
||||
import dbus
|
||||
dep_info['version'] = dbus.__version__
|
||||
dep_info['path'] = dbus.__file__
|
||||
except ImportError:
|
||||
pass
|
||||
return dep_info
|
||||
|
||||
|
||||
def serial_info():
|
||||
dep_info = {'name': 'pyserial'}
|
||||
try:
|
||||
import serial
|
||||
dep_info['version'] = serial.VERSION
|
||||
dep_info['path'] = serial.__file__
|
||||
except ImportError:
|
||||
pass
|
||||
return dep_info
|
||||
@ -12,6 +12,7 @@ from mopidy.utils.log import indent
|
||||
|
||||
logger = logging.getLogger('mopidy.utils.settings')
|
||||
|
||||
|
||||
class SettingsProxy(object):
|
||||
def __init__(self, default_settings_module):
|
||||
self.default = self._get_settings_dict_from_module(
|
||||
@ -101,7 +102,7 @@ def validate_settings(defaults, settings):
|
||||
Checks the settings for both errors like misspellings and against a set of
|
||||
rules for renamed settings, etc.
|
||||
|
||||
Returns of setting names with associated errors.
|
||||
Returns mapping from setting names to associated errors.
|
||||
|
||||
:param defaults: Mopidy's default settings
|
||||
:type defaults: dict
|
||||
@ -116,9 +117,9 @@ def validate_settings(defaults, settings):
|
||||
'DUMP_LOG_FILENAME': 'DEBUG_LOG_FILENAME',
|
||||
'DUMP_LOG_FORMAT': 'DEBUG_LOG_FORMAT',
|
||||
'FRONTEND': 'FRONTENDS',
|
||||
'GSTREAMER_AUDIO_SINK': 'CUSTOM_OUTPUT',
|
||||
'GSTREAMER_AUDIO_SINK': 'OUTPUT',
|
||||
'LOCAL_MUSIC_FOLDER': 'LOCAL_MUSIC_PATH',
|
||||
'LOCAL_OUTPUT_OVERRIDE': 'CUSTOM_OUTPUT',
|
||||
'LOCAL_OUTPUT_OVERRIDE': 'OUTPUT',
|
||||
'LOCAL_PLAYLIST_FOLDER': 'LOCAL_PLAYLIST_PATH',
|
||||
'LOCAL_TAG_CACHE': 'LOCAL_TAG_CACHE_FILE',
|
||||
'MIXER_ALSA_CONTROL': None,
|
||||
@ -152,7 +153,7 @@ def validate_settings(defaults, settings):
|
||||
elif setting == 'OUTPUTS':
|
||||
errors[setting] = (
|
||||
u'Deprecated setting, please change to OUTPUT. OUTPUT expectes '
|
||||
u'a GStreamer bin describing your desired output.')
|
||||
u'a GStreamer bin description string for your desired output.')
|
||||
|
||||
elif setting == 'SPOTIFY_BITRATE':
|
||||
if value not in (96, 160, 320):
|
||||
@ -166,11 +167,15 @@ def validate_settings(defaults, settings):
|
||||
u'bin in OUTPUT.')
|
||||
|
||||
elif setting not in defaults:
|
||||
errors[setting] = u'Unknown setting. Is it misspelled?'
|
||||
continue
|
||||
errors[setting] = u'Unknown setting.'
|
||||
suggestion = did_you_mean(setting, defaults)
|
||||
|
||||
if suggestion:
|
||||
errors[setting] += u' Did you mean %s?' % suggestion
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def list_settings_optparse_callback(*args):
|
||||
"""
|
||||
Prints a list of all settings.
|
||||
@ -182,6 +187,7 @@ def list_settings_optparse_callback(*args):
|
||||
print format_settings_list(settings)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def format_settings_list(settings):
|
||||
errors = settings.get_errors()
|
||||
lines = []
|
||||
@ -196,8 +202,41 @@ def format_settings_list(settings):
|
||||
lines.append(u' Error: %s' % errors[key])
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
def mask_value_if_secret(key, value):
|
||||
if key.endswith('PASSWORD') and value:
|
||||
return u'********'
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def did_you_mean(setting, defaults):
|
||||
"""Suggest most likely setting based on levenshtein."""
|
||||
if not defaults:
|
||||
return None
|
||||
|
||||
setting = setting.upper()
|
||||
candidates = [(levenshtein(setting, d), d) for d in defaults]
|
||||
candidates.sort()
|
||||
|
||||
if candidates[0][0] <= 3:
|
||||
return candidates[0][1]
|
||||
return None
|
||||
|
||||
|
||||
def levenshtein(a, b, max=3):
|
||||
"""Calculates the Levenshtein distance between a and b."""
|
||||
n, m = len(a), len(b)
|
||||
if n > m:
|
||||
return levenshtein(b, a)
|
||||
|
||||
current = xrange(n+1)
|
||||
for i in xrange(1, m+1):
|
||||
previous, current = current, [i] + [0] * n
|
||||
for j in xrange(1, n+1):
|
||||
add, delete = previous[j] + 1, current[j-1] + 1
|
||||
change = previous[j-1]
|
||||
if a[j-1] != b[i-1]:
|
||||
change += 1
|
||||
current[j] = min(add, delete, change)
|
||||
return current[n]
|
||||
|
||||
113
tests/utils/deps_test.py
Normal file
113
tests/utils/deps_test.py
Normal file
@ -0,0 +1,113 @@
|
||||
import platform
|
||||
|
||||
import pygst
|
||||
pygst.require('0.10')
|
||||
import gst
|
||||
import pykka
|
||||
|
||||
try:
|
||||
import dbus
|
||||
except ImportError:
|
||||
dbus = False
|
||||
|
||||
try:
|
||||
import pylast
|
||||
except ImportError:
|
||||
pylast = False
|
||||
|
||||
try:
|
||||
import serial
|
||||
except ImportError:
|
||||
serial = False
|
||||
|
||||
try:
|
||||
import spotify
|
||||
except ImportError:
|
||||
spotify = False
|
||||
|
||||
from mopidy.utils import deps
|
||||
|
||||
from tests import unittest
|
||||
|
||||
|
||||
class DepsTest(unittest.TestCase):
|
||||
def test_format_dependency_list(self):
|
||||
adapters = [
|
||||
lambda: dict(name='Python', version='FooPython 2.7.3'),
|
||||
lambda: dict(name='Platform', version='Loonix 4.0.1'),
|
||||
lambda: dict(name='Pykka', path='/foo/bar/baz.py', other='Quux')
|
||||
]
|
||||
|
||||
result = deps.format_dependency_list(adapters)
|
||||
|
||||
self.assertIn('Python: FooPython 2.7.3', result)
|
||||
self.assertIn('Platform: Loonix 4.0.1', result)
|
||||
self.assertIn('Pykka: not found', result)
|
||||
self.assertIn('Imported from: /foo/bar', result)
|
||||
self.assertNotIn('/baz.py', result)
|
||||
self.assertIn('Quux', result)
|
||||
|
||||
def test_platform_info(self):
|
||||
result = deps.platform_info()
|
||||
|
||||
self.assertEquals('Platform', result['name'])
|
||||
self.assertIn(platform.platform(), result['version'])
|
||||
|
||||
def test_python_info(self):
|
||||
result = deps.python_info()
|
||||
|
||||
self.assertEquals('Python', result['name'])
|
||||
self.assertIn(platform.python_implementation(), result['version'])
|
||||
self.assertIn(platform.python_version(), result['version'])
|
||||
self.assertIn('python', result['path'])
|
||||
|
||||
def test_gstreamer_info(self):
|
||||
result = deps.gstreamer_info()
|
||||
|
||||
self.assertEquals('GStreamer', result['name'])
|
||||
self.assertEquals('.'.join(map(str, gst.get_gst_version())), result['version'])
|
||||
self.assertIn('gst', result['path'])
|
||||
self.assertIn('Python wrapper: gst-python', result['other'])
|
||||
self.assertIn('.'.join(map(str, gst.get_pygst_version())), result['other'])
|
||||
self.assertIn('Relevant elements:', result['other'])
|
||||
|
||||
def test_pykka_info(self):
|
||||
result = deps.pykka_info()
|
||||
|
||||
self.assertEquals('Pykka', result['name'])
|
||||
self.assertEquals(pykka.__version__, result['version'])
|
||||
self.assertIn('pykka', result['path'])
|
||||
|
||||
@unittest.skipUnless(spotify, 'pyspotify not found')
|
||||
def test_pyspotify_info(self):
|
||||
result = deps.pyspotify_info()
|
||||
|
||||
self.assertEquals('pyspotify', result['name'])
|
||||
self.assertEquals(spotify.__version__, result['version'])
|
||||
self.assertIn('spotify', result['path'])
|
||||
self.assertIn('Built for libspotify API version', result['other'])
|
||||
self.assertIn(str(spotify.api_version), result['other'])
|
||||
|
||||
@unittest.skipUnless(pylast, 'pylast not found')
|
||||
def test_pylast_info(self):
|
||||
result = deps.pylast_info()
|
||||
|
||||
self.assertEquals('pylast', result['name'])
|
||||
self.assertEquals(pylast.__version__, result['version'])
|
||||
self.assertIn('pylast', result['path'])
|
||||
|
||||
@unittest.skipUnless(dbus, 'dbus not found')
|
||||
def test_dbus_info(self):
|
||||
result = deps.dbus_info()
|
||||
|
||||
self.assertEquals('dbus-python', result['name'])
|
||||
self.assertEquals(dbus.__version__, result['version'])
|
||||
self.assertIn('dbus', result['path'])
|
||||
|
||||
@unittest.skipUnless(serial, 'serial not found')
|
||||
def test_serial_info(self):
|
||||
result = deps.serial_info()
|
||||
|
||||
self.assertEquals('pyserial', result['name'])
|
||||
self.assertEquals(serial.VERSION, result['version'])
|
||||
self.assertIn('serial', result['path'])
|
||||
@ -1,8 +1,7 @@
|
||||
import os
|
||||
|
||||
from mopidy import settings as default_settings_module, SettingsError
|
||||
from mopidy.utils.settings import (format_settings_list, mask_value_if_secret,
|
||||
SettingsProxy, validate_settings)
|
||||
import mopidy
|
||||
from mopidy.utils import settings as setting_utils
|
||||
|
||||
from tests import unittest
|
||||
|
||||
@ -16,29 +15,29 @@ class ValidateSettingsTest(unittest.TestCase):
|
||||
}
|
||||
|
||||
def test_no_errors_yields_empty_dict(self):
|
||||
result = validate_settings(self.defaults, {})
|
||||
result = setting_utils.validate_settings(self.defaults, {})
|
||||
self.assertEqual(result, {})
|
||||
|
||||
def test_unknown_setting_returns_error(self):
|
||||
result = validate_settings(self.defaults,
|
||||
result = setting_utils.validate_settings(self.defaults,
|
||||
{'MPD_SERVER_HOSTNMAE': '127.0.0.1'})
|
||||
self.assertEqual(result['MPD_SERVER_HOSTNMAE'],
|
||||
u'Unknown setting. Is it misspelled?')
|
||||
u'Unknown setting. Did you mean MPD_SERVER_HOSTNAME?')
|
||||
|
||||
def test_not_renamed_setting_returns_error(self):
|
||||
result = validate_settings(self.defaults,
|
||||
result = setting_utils.validate_settings(self.defaults,
|
||||
{'SERVER_HOSTNAME': '127.0.0.1'})
|
||||
self.assertEqual(result['SERVER_HOSTNAME'],
|
||||
u'Deprecated setting. Use MPD_SERVER_HOSTNAME.')
|
||||
|
||||
def test_unneeded_settings_returns_error(self):
|
||||
result = validate_settings(self.defaults,
|
||||
result = setting_utils.validate_settings(self.defaults,
|
||||
{'SPOTIFY_LIB_APPKEY': '/tmp/foo'})
|
||||
self.assertEqual(result['SPOTIFY_LIB_APPKEY'],
|
||||
u'Deprecated setting. It may be removed.')
|
||||
|
||||
def test_deprecated_setting_value_returns_error(self):
|
||||
result = validate_settings(self.defaults,
|
||||
result = setting_utils.validate_settings(self.defaults,
|
||||
{'BACKENDS': ('mopidy.backends.despotify.DespotifyBackend',)})
|
||||
self.assertEqual(result['BACKENDS'],
|
||||
u'Deprecated setting value. ' +
|
||||
@ -46,33 +45,33 @@ class ValidateSettingsTest(unittest.TestCase):
|
||||
'available.')
|
||||
|
||||
def test_unavailable_bitrate_setting_returns_error(self):
|
||||
result = validate_settings(self.defaults,
|
||||
result = setting_utils.validate_settings(self.defaults,
|
||||
{'SPOTIFY_BITRATE': 50})
|
||||
self.assertEqual(result['SPOTIFY_BITRATE'],
|
||||
u'Unavailable Spotify bitrate. ' +
|
||||
u'Available bitrates are 96, 160, and 320.')
|
||||
|
||||
def test_two_errors_are_both_reported(self):
|
||||
result = validate_settings(self.defaults,
|
||||
result = setting_utils.validate_settings(self.defaults,
|
||||
{'FOO': '', 'BAR': ''})
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
def test_masks_value_if_secret(self):
|
||||
secret = mask_value_if_secret('SPOTIFY_PASSWORD', 'bar')
|
||||
secret = setting_utils.mask_value_if_secret('SPOTIFY_PASSWORD', 'bar')
|
||||
self.assertEqual(u'********', secret)
|
||||
|
||||
def test_does_not_mask_value_if_not_secret(self):
|
||||
not_secret = mask_value_if_secret('SPOTIFY_USERNAME', 'foo')
|
||||
not_secret = setting_utils.mask_value_if_secret('SPOTIFY_USERNAME', 'foo')
|
||||
self.assertEqual('foo', not_secret)
|
||||
|
||||
def test_does_not_mask_value_if_none(self):
|
||||
not_secret = mask_value_if_secret('SPOTIFY_USERNAME', None)
|
||||
not_secret = setting_utils.mask_value_if_secret('SPOTIFY_USERNAME', None)
|
||||
self.assertEqual(None, not_secret)
|
||||
|
||||
|
||||
class SettingsProxyTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.settings = SettingsProxy(default_settings_module)
|
||||
self.settings = setting_utils.SettingsProxy(mopidy.settings)
|
||||
self.settings.local.clear()
|
||||
|
||||
def test_set_and_get_attr(self):
|
||||
@ -83,7 +82,7 @@ class SettingsProxyTest(unittest.TestCase):
|
||||
try:
|
||||
_ = self.settings.TEST
|
||||
self.fail(u'Should raise exception')
|
||||
except SettingsError as e:
|
||||
except mopidy.SettingsError as e:
|
||||
self.assertEqual(u'Setting "TEST" is not set.', e.message)
|
||||
|
||||
def test_getattr_raises_error_on_empty_setting(self):
|
||||
@ -91,7 +90,7 @@ class SettingsProxyTest(unittest.TestCase):
|
||||
try:
|
||||
_ = self.settings.TEST
|
||||
self.fail(u'Should raise exception')
|
||||
except SettingsError as e:
|
||||
except mopidy.SettingsError as e:
|
||||
self.assertEqual(u'Setting "TEST" is empty.', e.message)
|
||||
|
||||
def test_getattr_does_not_raise_error_if_setting_is_false(self):
|
||||
@ -177,44 +176,68 @@ class SettingsProxyTest(unittest.TestCase):
|
||||
|
||||
class FormatSettingListTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.settings = SettingsProxy(default_settings_module)
|
||||
self.settings = setting_utils.SettingsProxy(mopidy.settings)
|
||||
|
||||
def test_contains_the_setting_name(self):
|
||||
self.settings.TEST = u'test'
|
||||
result = format_settings_list(self.settings)
|
||||
result = setting_utils.format_settings_list(self.settings)
|
||||
self.assert_('TEST:' in result, result)
|
||||
|
||||
def test_repr_of_a_string_value(self):
|
||||
self.settings.TEST = u'test'
|
||||
result = format_settings_list(self.settings)
|
||||
result = setting_utils.format_settings_list(self.settings)
|
||||
self.assert_("TEST: u'test'" in result, result)
|
||||
|
||||
def test_repr_of_an_int_value(self):
|
||||
self.settings.TEST = 123
|
||||
result = format_settings_list(self.settings)
|
||||
result = setting_utils.format_settings_list(self.settings)
|
||||
self.assert_("TEST: 123" in result, result)
|
||||
|
||||
def test_repr_of_a_tuple_value(self):
|
||||
self.settings.TEST = (123, u'abc')
|
||||
result = format_settings_list(self.settings)
|
||||
result = setting_utils.format_settings_list(self.settings)
|
||||
self.assert_("TEST: (123, u'abc')" in result, result)
|
||||
|
||||
def test_passwords_are_masked(self):
|
||||
self.settings.TEST_PASSWORD = u'secret'
|
||||
result = format_settings_list(self.settings)
|
||||
result = setting_utils.format_settings_list(self.settings)
|
||||
self.assert_("TEST_PASSWORD: u'secret'" not in result, result)
|
||||
self.assert_("TEST_PASSWORD: u'********'" in result, result)
|
||||
|
||||
def test_short_values_are_not_pretty_printed(self):
|
||||
self.settings.FRONTEND = (u'mopidy.frontends.mpd.MpdFrontend',)
|
||||
result = format_settings_list(self.settings)
|
||||
result = setting_utils.format_settings_list(self.settings)
|
||||
self.assert_("FRONTEND: (u'mopidy.frontends.mpd.MpdFrontend',)" in result,
|
||||
result)
|
||||
|
||||
def test_long_values_are_pretty_printed(self):
|
||||
self.settings.FRONTEND = (u'mopidy.frontends.mpd.MpdFrontend',
|
||||
u'mopidy.frontends.lastfm.LastfmFrontend')
|
||||
result = format_settings_list(self.settings)
|
||||
result = setting_utils.format_settings_list(self.settings)
|
||||
self.assert_("""FRONTEND:
|
||||
(u'mopidy.frontends.mpd.MpdFrontend',
|
||||
u'mopidy.frontends.lastfm.LastfmFrontend')""" in result, result)
|
||||
|
||||
|
||||
class DidYouMeanTest(unittest.TestCase):
|
||||
def testSuggestoins(self):
|
||||
defaults = {
|
||||
'MPD_SERVER_HOSTNAME': '::',
|
||||
'MPD_SERVER_PORT': 6600,
|
||||
'SPOTIFY_BITRATE': 160,
|
||||
}
|
||||
|
||||
suggestion = setting_utils.did_you_mean('spotify_bitrate', defaults)
|
||||
self.assertEqual(suggestion, 'SPOTIFY_BITRATE')
|
||||
|
||||
suggestion = setting_utils.did_you_mean('SPOTIFY_BITROTE', defaults)
|
||||
self.assertEqual(suggestion, 'SPOTIFY_BITRATE')
|
||||
|
||||
suggestion = setting_utils.did_you_mean('SPITIFY_BITROT', defaults)
|
||||
self.assertEqual(suggestion, 'SPOTIFY_BITRATE')
|
||||
|
||||
suggestion = setting_utils.did_you_mean('SPTIFY_BITROT', defaults)
|
||||
self.assertEqual(suggestion, 'SPOTIFY_BITRATE')
|
||||
|
||||
suggestion = setting_utils.did_you_mean('SPTIFY_BITRO', defaults)
|
||||
self.assertEqual(suggestion, None)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user