Commits

Hong Minhee committed d4ae681

Implemented the short type mapping interface for the method decorator.

Comments (0)

Files changed (2)

 
     """
 
+    def setUp(self):
+        self.method = MethodDecorator("GET")
+
+    def assert_same(self, expected, actual):
+        self.assertEquals(id(expected), id(actual))
+
+    def assert_handler(self, expected, resource, type):
+        from vlastic.rom.resource import METHOD_HANDLER_ATTRIBUTE_NAME as name
+        view = getattr(resource, name)["GET"]
+        self.assertTrue(isinstance(view, NegotiativeView))
+        self.assert_same(expected, view[type])
+
     def test_negotiation(self):
-        method = MethodDecorator("GET")
-        decorator = method({
+        decorator = self.method({
             "text/plain": test_view,
             "text/html": NegotiativeViewTest._html_view
         })
         resource = lambda: None
         decorator(resource)
-        from vlastic.rom.resource import METHOD_HANDLER_ATTRIBUTE_NAME as name
-        view = getattr(resource, name)["GET"]
-        self.assertTrue(isinstance(view, NegotiativeView))
-        self.assertEquals(id(test_view), id(view["text/plain"]))
-        self.assertEquals(
-            id(NegotiativeViewTest._html_view),
-            id(view["text/html"])
+        self.assert_handler(test_view, resource, "text/plain")
+        self.assert_handler(
+            NegotiativeViewTest._html_view,
+            resource, "text/html"
+        )
+
+    def test_kwargs(self):
+        decorator = self.method(html=NegotiativeViewTest._html_view)
+        resource = lambda: None
+        decorator(resource)
+        self.assert_handler(
+            NegotiativeViewTest._html_view,
+            resource, "text/html"
+        )
+        self.assert_handler(
+            NegotiativeViewTest._html_view,
+            resource, "application/xhtml+xml"
         )
 
 

vlastic/rom/decorator.py

 __all__ = ["NegotiativeView", "MethodDecorator", "method", "get", "post",
            "put", "delete"]
 
+KEYWORDS_MIME_MAP = {
+    "html": ("text/html", "application/xhtml+xml"),
+    "json": ("application/json",),
+    "xml": ("text/xml",),
+    "text": ("text/plain",)
+}
+
 
 class NegotiativeView(dict):
     """Accept-aware higher-order view functor. Its constructor takes a
         chosen when the request doesn't contain Accept header.
 
         """
-        try:
-            view = self["text/html"]
-        except KeyError:
-            view = self["application/xhtml+xml"]
-        return view(*args)
+        for mime in KEYWORDS_MIME_MAP["html"]:
+            if mime in self:
+                return self[mime](*args)
+        raise KeyError
 
     def __call__(self, context, request):
         accept = request.accept
     def __init__(self, method):
         self.method = method.upper()
 
-    def __call__(self, view):
+    def __call__(self, _=None, **kwtypes):
         """Accepts a view function and returns decorator which make given
         function to handle specific HTTP method through view function.
 
         """
+        view = _
         if isinstance(view, dict):
             view = NegotiativeView(view)
+        elif _ is None:
+            view = NegotiativeView()
+            for type, view4type in kwtypes.items():
+                for mime in KEYWORDS_MIME_MAP[type]:
+                    view[mime] = view4type
         def decorator(function):
             handler_attr = resource.METHOD_HANDLER_ATTRIBUTE_NAME
             if hasattr(function, handler_attr):