diff --git a/tests/pecantest/test/controllers/ws.py b/tests/pecantest/test/controllers/ws.py index 42b6b1f..23ee0da 100644 --- a/tests/pecantest/test/controllers/ws.py +++ b/tests/pecantest/test/controllers/ws.py @@ -37,12 +37,28 @@ class BooksController(RestController): return book +class Criterion(Base): + op = text + attrname = text + value = text + + class AuthorsController(RestController): books = BooksController() - @wsme.pecan.wsexpose([Author]) - def get_all(self): + @wsme.pecan.wsexpose([Author], [unicode], [Criterion]) + def get_all(self, q=None, r=None): + if q: + return [ + Author(id=i, firstname=value) + for i, value in enumerate(q) + ] + if r: + return [ + Author(id=i, firstname=c.value) + for i, c in enumerate(r) + ] return [ Author(id=1, firstname=u'FirstName') ] diff --git a/tests/pecantest/test/tests/test_ws.py b/tests/pecantest/test/tests/test_ws.py index d53c002..d971eba 100644 --- a/tests/pecantest/test/tests/test_ws.py +++ b/tests/pecantest/test/tests/test_ws.py @@ -7,6 +7,38 @@ class TestWS(FunctionalTest): def test_get_all(self): self.app.get('/authors') + def test_optional_array_param(self): + r = self.app.get('/authors?q=a&q=b') + l = json.loads(r.body) + print l + assert len(l) == 2 + assert l[0]['firstname'] == 'a' + assert l[1]['firstname'] == 'b' + + def test_optional_indexed_array_param(self): + r = self.app.get('/authors?q[0]=a&q[1]=b') + l = json.loads(r.body) + print l + assert len(l) == 2 + assert l[0]['firstname'] == 'a' + assert l[1]['firstname'] == 'b' + + def test_options_object_array_param(self): + r = self.app.get('/authors?r.value=a&r.value=b') + l = json.loads(r.body) + print l + assert len(l) == 2 + assert l[0]['firstname'] == 'a' + assert l[1]['firstname'] == 'b' + + def test_options_indexed_object_array_param(self): + r = self.app.get('/authors?r[0].value=a&r[1].value=b') + l = json.loads(r.body) + print l + assert len(l) == 2 + assert l[0]['firstname'] == 'a' + assert l[1]['firstname'] == 'b' + def test_get_author(self): a = self.app.get( '/authors/1.json', diff --git a/wsme/pecan.py b/wsme/pecan.py index e9ba454..6bee7f4 100644 --- a/wsme/pecan.py +++ b/wsme/pecan.py @@ -62,7 +62,7 @@ def wsexpose(*args, **kwargs): def callfunction(self, *args, **kwargs): try: args, kwargs = wsme.rest.args.get_args( - funcdef, args, kwargs, + funcdef, args, kwargs, pecan.request.params, pecan.request.body, pecan.request.content_type ) result = f(self, *args, **kwargs) diff --git a/wsme/rest/args.py b/wsme/rest/args.py index 9c31f35..1b918da 100644 --- a/wsme/rest/args.py +++ b/wsme/rest/args.py @@ -46,6 +46,16 @@ def usertype_from_param(datatype, value): from_param(datatype.basetype, value)) +@from_param.when_type(ArrayType) +def array_from_param(datatype, value): + if value is None: + return value + return [ + from_param(datatype.item_type, item) + for item in value + ] + + @generic def from_params(datatype, params, path, hit_paths): if iscomplex(datatype) and datatype is not File: @@ -72,6 +82,7 @@ def from_params(datatype, params, path, hit_paths): @from_params.when_type(ArrayType) def array_from_params(datatype, params, path, hit_paths): if path in params: + hit_paths.add(path) return [ from_param(datatype.item_type, value) for value in params.getall(path)] @@ -175,9 +186,10 @@ def combine_args(funcdef, *akw): return newargs, newkwargs -def get_args(funcdef, args, kwargs, body, mimetype): +def get_args(funcdef, args, kwargs, params, body, mimetype): return combine_args( funcdef, args_from_args(funcdef, args, kwargs), - args_from_body(funcdef, body, mimetype) + args_from_params(funcdef, params), + args_from_body(funcdef, body, mimetype), )