From f89f4151b0f7a037786bdb5d63092dc74dbffac3 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 1 Apr 2013 11:02:02 +0200 Subject: [PATCH 1/4] ext: Add Extension base class --- mopidy/ext.py | 27 +++++++++++++++++++++++++++ tests/ext_test.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 mopidy/ext.py create mode 100644 tests/ext_test.py diff --git a/mopidy/ext.py b/mopidy/ext.py new file mode 100644 index 00000000..dc756a3a --- /dev/null +++ b/mopidy/ext.py @@ -0,0 +1,27 @@ +from __future__ import unicode_literals + + +class Extension(object): + + name = None + version = None + + def get_default_config(self): + raise NotImplementedError( + 'Add at least a config section with "enabled = true"') + + def validate_config(self, config): + raise NotImplementedError( + 'You must explicitly pass config validation if not needed') + + def validate_environment(self): + pass + + def get_frontend_class(self): + pass + + def get_backend_class(self): + pass + + def register_gstreamer_elements(self): + pass diff --git a/tests/ext_test.py b/tests/ext_test.py new file mode 100644 index 00000000..98849e21 --- /dev/null +++ b/tests/ext_test.py @@ -0,0 +1,34 @@ +from __future__ import unicode_literals + +from mopidy.ext import Extension + +from tests import unittest + + +class ExtensionTest(unittest.TestCase): + def setUp(self): + self.ext = Extension() + + def test_name_is_none(self): + self.assertIsNone(self.ext.name) + + def test_version_is_none(self): + self.assertIsNone(self.ext.version) + + def test_get_default_config_raises_not_implemented(self): + self.assertRaises(NotImplementedError, self.ext.get_default_config) + + def test_validate_config_raises_not_implemented(self): + self.assertRaises(NotImplementedError, self.ext.validate_config, None) + + def test_validate_environment_does_nothing_by_default(self): + self.assertIsNone(self.ext.validate_environment()) + + def test_get_frontend_class_returns_none_by_default(self): + self.assertIsNone(self.ext.get_frontend_class()) + + def test_get_backend_class_returns_none_by_default(self): + self.assertIsNone(self.ext.get_backend_class()) + + def test_register_gstreamer_elements_does_nothing_by_default(self): + self.assertIsNone(self.ext.register_gstreamer_elements()) From 059147723bb5aa15615be076928d38d0d75a502e Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 1 Apr 2013 11:08:05 +0200 Subject: [PATCH 2/4] tests: Test existing exception classes --- tests/exceptions_test.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/exceptions_test.py diff --git a/tests/exceptions_test.py b/tests/exceptions_test.py new file mode 100644 index 00000000..5148ebaf --- /dev/null +++ b/tests/exceptions_test.py @@ -0,0 +1,21 @@ +from __future__ import unicode_literals + +from mopidy import exceptions + +from tests import unittest + + +class ExceptionsTest(unittest.TestCase): + def test_exception_can_include_message_string(self): + exc = exceptions.MopidyException('foo') + + self.assertEqual(exc.message, 'foo') + self.assertEqual(str(exc), 'foo') + + def test_settings_error_is_a_mopidy_exception(self): + self.assert_(issubclass( + exceptions.SettingsError, exceptions.MopidyException)) + + def test_optional_dependency_error_is_a_mopidy_exception(self): + self.assert_(issubclass( + exceptions.OptionalDependencyError, exceptions.MopidyException)) From 0ec989d2cb9bb18c0529f1f7a6767f815488ee17 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 1 Apr 2013 11:09:16 +0200 Subject: [PATCH 3/4] ext: Add ExtensionError exception class --- mopidy/exceptions.py | 4 ++++ tests/exceptions_test.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/mopidy/exceptions.py b/mopidy/exceptions.py index b8d183fb..00c19e9e 100644 --- a/mopidy/exceptions.py +++ b/mopidy/exceptions.py @@ -22,3 +22,7 @@ class SettingsError(MopidyException): class OptionalDependencyError(MopidyException): pass + + +class ExtensionError(MopidyException): + pass diff --git a/tests/exceptions_test.py b/tests/exceptions_test.py index 5148ebaf..2bc838d7 100644 --- a/tests/exceptions_test.py +++ b/tests/exceptions_test.py @@ -19,3 +19,7 @@ class ExceptionsTest(unittest.TestCase): def test_optional_dependency_error_is_a_mopidy_exception(self): self.assert_(issubclass( exceptions.OptionalDependencyError, exceptions.MopidyException)) + + def test_extension_error_is_a_mopidy_exception(self): + self.assert_(issubclass( + exceptions.ExtensionError, exceptions.MopidyException)) From 64b0cc7b98963cbcdd5d704ad075e50547d2715a Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 1 Apr 2013 11:30:07 +0200 Subject: [PATCH 4/4] ext: Support multiple frontends/backends in an extension --- docs/extensiondev.rst | 8 ++++---- mopidy/ext.py | 8 ++++---- tests/ext_test.py | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/extensiondev.rst b/docs/extensiondev.rst index b1928798..f2c54847 100644 --- a/docs/extensiondev.rst +++ b/docs/extensiondev.rst @@ -265,13 +265,13 @@ meaningful defaults blank, like ``username`` and ``password``. # You will typically only implement one of the next three methods # in a single extension. - def get_frontend_class(self): + def get_frontend_classes(self): from .frontend import SoundspotFrontend - return SoundspotFrontend + return [SoundspotFrontend] - def get_backend_class(self): + def get_backend_classes(self): from .backend import SoundspotBackend - return SoundspotBackend + return [SoundspotBackend] def register_gstreamer_elements(self): from .mixer import SoundspotMixer diff --git a/mopidy/ext.py b/mopidy/ext.py index dc756a3a..6cc35139 100644 --- a/mopidy/ext.py +++ b/mopidy/ext.py @@ -17,11 +17,11 @@ class Extension(object): def validate_environment(self): pass - def get_frontend_class(self): - pass + def get_frontend_classes(self): + return [] - def get_backend_class(self): - pass + def get_backend_classes(self): + return [] def register_gstreamer_elements(self): pass diff --git a/tests/ext_test.py b/tests/ext_test.py index 98849e21..ac238ca5 100644 --- a/tests/ext_test.py +++ b/tests/ext_test.py @@ -24,11 +24,11 @@ class ExtensionTest(unittest.TestCase): def test_validate_environment_does_nothing_by_default(self): self.assertIsNone(self.ext.validate_environment()) - def test_get_frontend_class_returns_none_by_default(self): - self.assertIsNone(self.ext.get_frontend_class()) + def test_get_frontend_classes_returns_an_empty_list(self): + self.assertListEqual(self.ext.get_frontend_classes(), []) - def test_get_backend_class_returns_none_by_default(self): - self.assertIsNone(self.ext.get_backend_class()) + def test_get_backend_classes_returns_an_empty_list(self): + self.assertListEqual(self.ext.get_backend_classes(), []) def test_register_gstreamer_elements_does_nothing_by_default(self): self.assertIsNone(self.ext.register_gstreamer_elements())