text: from friendly_name_mixin import FriendlyNameFromClassMixin
  from nose.tools import raises
  from nose_extra_tools import assert_equal, assert_is, assert_in, assert_not_in, issues_warnings #@UnresolvedImport
  from simple_plugins import AttrDict, PluginMount, CoercionError, PerformanceWarning
  
  
  class TestPluginMount(object):
      def setup_http_method_plugins(self):
          class HTTPMethod(FriendlyNameFromClassMixin):
              """Mount point should not be registered as a plugin"""
              __metaclass__ = PluginMount
              class Meta:
                  id_field = 'name'
                  id_field_coerce = str
          class BaseIdempotentHTTPMethod(HTTPMethod):
              """'Base*' classes should not be registered as plugins"""
              pass
          class GET(BaseIdempotentHTTPMethod):
              pass
          class POST(HTTPMethod):
              pass
          class FakePOST(POST):
              """Both parent and its child should be registered as plugins"""
              pass
          class PUT(BaseIdempotentHTTPMethod):
              pass
          class DELETE(BaseIdempotentHTTPMethod):
              pass
  
          self.HTTPMethod = HTTPMethod
          self.GET = GET
          self.POST = POST
          self.FakePOST = FakePOST
  
          self.actual_http_method_id = 'POST'
          self.desired_http_method_instance = HTTPMethod.plugins.id_to_instance[
              self.actual_http_method_id
          ]
  
          id_to_class = {
              'GET': GET, 'POST': POST, 'Fake POST': FakePOST, 'PUT': PUT,
              'DELETE': DELETE
          }
          self.desired_http_method_plugins = AttrDict(
              classes=set(id_to_class.values()),
              id_to_class=id_to_class,
              class_to_id=dict((v, k) for k, v in id_to_class.items()),
              classes_sorted_by_id=[v for _, v in sorted(id_to_class.items())],
              valid_ids=set(id_to_class.keys()),
          )
  
      def setup_http_response_plugins(self):
          class HttpResponse(object):
              """Mount point should not be registered as a plugin"""
              status_code = None
              __metaclass__ = PluginMount
              class Meta:
                  id_field = 'status_code'
              @classmethod
              def _contribute_to_plugins(cls, _plugins):
                  _plugins.contribute_to_plugins_works = True
          class OK(HttpResponse):
              status_code = 200
          class BaseRedirection(HttpResponse):
              """'Base*' classes should not be registered as plugins"""
              pass
          class MovedPermanently(BaseRedirection):
              status_code = 301
          class NotModified(BaseRedirection):
              status_code = 304
          class BadRequest(HttpResponse):
              status_code = 400
          class NotFound(HttpResponse):
              status_code = 404
  
          self.HttpResponse = HttpResponse
  
          self.actual_http_response_class = MovedPermanently
          self.desired_http_response_instance = HttpResponse.plugins.id_to_instance[
              self.actual_http_response_class.status_code
          ]
          self.desired_http_response_class = type(self.desired_http_response_instance)
  
      def setup(self):
          self.setup_http_method_plugins()
          self.setup_http_response_plugins()
  
      def test_plugin_registration(self):
          # Not comparing as sets to be able to confirm there are no duplicates
          # in the plugin registry
          assert_equal(
              sorted(self.HTTPMethod._plugin_registry),
              sorted(self.desired_http_method_plugins.classes)
          )
  
      def test_plugin_unregistration(self):
          cls = self.actual_http_response_class
          assert_in(cls, self.HttpResponse.plugins.classes)
  
          cls._unregister_plugin()
          assert_not_in(cls, self.HttpResponse.plugins.classes)
  
      def test_plugin_info(self):
          actual_plugins = self.HTTPMethod.plugins.copy()
  
          # Special case for any instances related information
          assert_equal(
              set(type(obj) for obj in actual_plugins.pop('instances')),
              self.desired_http_method_plugins.classes
          )
          assert_equal(
              dict((k, type(v)) for k, v in actual_plugins.pop('id_to_instance').items()),
              self.desired_http_method_plugins.id_to_class
          )
          assert_equal(
              [type(obj) for obj in actual_plugins.pop('instances_sorted_by_id')],
              self.desired_http_method_plugins.pop('classes_sorted_by_id')
          )
  
          # Compare the remaining plugin information directly
          assert_equal(actual_plugins, self.desired_http_method_plugins)
  
      def test_contribute_to_plugins(self):
          assert_is(self.HttpResponse.plugins.contribute_to_plugins_works, True)
  
      def test_distant_relatives_use_same_plugin_info_cache(self):
          self.GET._plugins = None
          self.POST._plugins = None
          assert_is(self.GET.plugins, self.POST.plugins)
  
      def test_child_uses_same_plugin_info_cache_as_parent(self):
          self.FakePOST._plugins = None
          self.POST._plugins = None
          assert_is(self.FakePOST.plugins, self.POST.plugins)
  
      def test_child_uses_same_plugin_info_cache_as_base_class(self):
          self.FakePOST._plugins = None
          self.HTTPMethod._plugins = None
          assert_is(self.FakePOST.plugins, self.HTTPMethod.plugins)
  
      def test_parent_uses_same_plugin_info_cache_as_base_class(self):
          self.POST._plugins = None
          self.HTTPMethod._plugins = None
          assert_is(self.POST.plugins, self.HTTPMethod.plugins)
  
      def test_plugins_not_shared_between_mount_points(self):
          assert self.HTTPMethod.plugins.classes.isdisjoint(
              self.HttpResponse.plugins.classes
          )
  
      @issues_warnings(PerformanceWarning)
      def test_coerce_valid_http_response_instance(self):
          assert_is(
              type(self.HttpResponse.coerce(self.actual_http_response_class())),
              self.desired_http_response_class
          )
  
      @issues_warnings(PerformanceWarning)
      def test_coerce_valid_http_response_class(self):
          assert_is(
              type(self.HttpResponse.coerce(self.actual_http_response_class)),
              self.desired_http_response_class
          )
  
      def test_coerce_works_with_empty_plugin_info_cache(self):
          self.HttpResponse._plugins = None
          self.HTTPMethod.coerce(self.actual_http_method_id)
  
      def test_coerce_nonnumeric_id(self):
          assert_is(
              self.HTTPMethod.coerce(self.actual_http_method_id),
              self.desired_http_method_instance
          )
  
      def test_coerce_valid_http_response_id(self):
          assert_is(
              self.HttpResponse.coerce(self.actual_http_response_class.status_code),
              self.desired_http_response_instance
          )
  
      @raises(CoercionError)
      def test_coerce_invalid_http_response_id(self):
          self.HttpResponse.coerce(-1)
  
      @raises(CoercionError)
      def test_coerce_unknown_type(self):
          self.HttpResponse.coerce(object())
  