From d3a58a738b1a5a5cdee5081e3729aefa170262f7 Mon Sep 17 00:00:00 2001 From: Lynn Root Date: Sun, 31 Jan 2016 15:45:58 -0800 Subject: [PATCH] fixed order of uri/base uri params; create undeclared uri params --- ramlfications/parser/main.py | 6 ++++- ramlfications/parser/parameters.py | 16 +++++++++++-- ramlfications/utils/parameter.py | 23 +++++++++++++++++- ramlfications/utils/parser.py | 38 ++++++++++++++++++++++++++++++ tests/test_parser.py | 34 +++++++++++--------------- tests/v020tests/test_resources.py | 4 ++-- 6 files changed, 95 insertions(+), 26 deletions(-) diff --git a/ramlfications/parser/main.py b/ramlfications/parser/main.py index 720a4c0..568e4c6 100644 --- a/ramlfications/parser/main.py +++ b/ramlfications/parser/main.py @@ -20,7 +20,7 @@ # Private utility functions from ramlfications.utils.common import _get from ramlfications.utils.parser import ( - parse_assigned_dicts, resolve_inherited_scalar + parse_assigned_dicts, resolve_inherited_scalar, sort_uri_params ) from .parameters import create_param_objs @@ -446,6 +446,10 @@ def create_node_dict(): node["media_type"] = media_type() node["method"] = method node["raw"] = raw_data + node["uri_params"] = sort_uri_params(node["uri_params"], + node["absolute_uri"]) + node["base_uri_params"] = sort_uri_params(node["base_uri_params"], + node["absolute_uri"]) return node # Avoiding repeated function calls by calling them once here diff --git a/ramlfications/parser/parameters.py b/ramlfications/parser/parameters.py index e584cff..5f73602 100644 --- a/ramlfications/parser/parameters.py +++ b/ramlfications/parser/parameters.py @@ -9,7 +9,9 @@ from ramlfications.parameters import Response, Header, Body, URIParameter from ramlfications.utils import load_schema from ramlfications.utils.common import _get, substitute_parameters -from ramlfications.utils.parameter import map_object, resolve_scalar_data +from ramlfications.utils.parameter import ( + map_object, resolve_scalar_data, add_missing_uri_data +) ##### @@ -33,6 +35,12 @@ def create_param_objs(param_type, resolve=[], **kwargs): resolved = resolve_scalar_data(param_type, resolve, **kwargs) resolved = _substitute_params(resolved, **kwargs) + path = _get(kwargs, "resource_path") + if param_type == "uriParameters": + # only for resource node objects + if path: + resolved = add_missing_uri_data(path, resolved) + # create parameter objects based off of the resolved data object_name = map_object(param_type) if param_type == "body": @@ -44,9 +52,13 @@ def create_param_objs(param_type, resolve=[], **kwargs): params = __create_base_param_obj(resolved, object_name, conf, errs, method=method) - # TODO: if param type is URI/Base Uri, then preserve order according + # If param type is URI/Base Uri, then preserve order according # to how they are represented in absolute_uri, as well as create any # undeclared uri params that are in the path + # if param_type in ("uriParameters", "baseUriParameters"): + # if isinstance(params, list) and path: + # # this may not be true in all cases, but I'm not sure when + # params = params[::-1] return params or None diff --git a/ramlfications/utils/parameter.py b/ramlfications/utils/parameter.py index 1b3b856..8f1a6f6 100644 --- a/ramlfications/utils/parameter.py +++ b/ramlfications/utils/parameter.py @@ -3,8 +3,9 @@ from __future__ import absolute_import, division, print_function +import re -from six import iteritems +from six import iteritems, iterkeys from .common import ( _get, get_inherited_trait_data, merge_dicts, INH_FUNC_MAPPING @@ -83,3 +84,23 @@ def __trait(item, **kwargs): def __map_inheritance(obj_type): INH_FUNC_MAPPING["traits"] = __trait return INH_FUNC_MAPPING[obj_type] + + +def add_missing_uri_data(path, data): + # if this is hit, RAML shouldn't be valid anyways. + if isinstance(path, list): + path = path[0] + + pattern = re.compile(r'\{(.*?)\}') + params = re.findall(pattern, path) + + default_data = {"type": "string", "required": True} + defined_params = list(iterkeys(data)) + if params: + missing_params = set(params).difference(defined_params) + for p in missing_params: + # no need to create a URI param for version + if p == "version": + continue + data[p] = default_data + return data diff --git a/ramlfications/utils/parser.py b/ramlfications/utils/parser.py index f2068f8..56c1960 100644 --- a/ramlfications/utils/parser.py +++ b/ramlfications/utils/parser.py @@ -3,6 +3,8 @@ from __future__ import absolute_import, division, print_function +import re + from six import iterkeys, string_types from .common import ( @@ -57,6 +59,42 @@ def resolve_inherited_scalar(item, inherit_from=[], **kwargs): return None +def sort_uri_params(params, path): + if not params: + return params + # if this is hit, RAML shouldn't be valid anyways. + if isinstance(path, list): + path = path[0] + + pattern = re.compile(r'\{(.*?)\}') + param_order = re.findall(pattern, path) + + media_type = None + media_type_param = None + for p in params: + if p.name == "mediaTypeExtension": + media_type = params.index(p) + break + + if media_type is not None: + media_type_param = params.pop(media_type) + + to_sort = [] + + for p in params: + if p.name == "version": + continue + index = param_order.index(p.name) + to_sort.append((index, p)) + + params = [p[1] for p in sorted(to_sort, key=lambda item: item[0])] + + if media_type_param: + params.append(media_type_param) + + return params + + ##### # Private module-level helper functions ##### diff --git a/tests/test_parser.py b/tests/test_parser.py index 0205228..b022e03 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -564,9 +564,7 @@ def test_root_trait_params(trait_parameters): resp = paged.responses[0] assert resp.code == 200 - # TODO: FIXME - should be none, but getting copied when assigned to - # resources - # assert not resp.method + assert not resp.method assert resp.description.raw == "No more than <> pages returned" assert len(resp.headers) == 1 @@ -1127,11 +1125,10 @@ def test_resource_assigned_type(resources): exp_res_type_uri = ["mediaTypeExtension", "communityPath"] exp_res_uri = [ - "mediaTypeExtension", "communityPath", "user_id", "thingy_id" + "communityPath", "user_id", "thingy_id", "mediaTypeExtension", ] - # TODO: uri parameter order isn't preserved...I don't think... - assert sorted(res_type_uri) == sorted(exp_res_type_uri) - assert sorted(res_uri) == sorted(exp_res_uri) + assert res_type_uri == exp_res_type_uri + assert res_uri == exp_res_uri # TODO: add more attributes to test with parameter objects # e.g. h1.desc @@ -1647,17 +1644,16 @@ def uri_param_resources(): def test_uri_params_order(uri_param_resources): - # res = uri_param_resources.resources[1] - # expected_uri = ["lang", "user_id", "playlist_id"] - # expected_base = ["subHostName", "bucketName"] + res = uri_param_resources.resources[1] + expected_uri = ["lang", "user_id", "playlist_id"] + expected_base = ["subHostName", "bucketName"] - # uri = [u.name for u in res.uri_params] - # base = [b.name for b in res.base_uri_params] + uri = [u.name for u in res.uri_params] + base = [b.name for b in res.base_uri_params] # TODO: implement/fix uri param order - # assert uri == expected_uri - # assert base == expected_base - pass + assert uri == expected_uri + assert base == expected_base @pytest.fixture(scope="session") @@ -1670,12 +1666,10 @@ def undef_uri_params_resources(): def test_undefined_uri_params(undef_uri_params_resources): - # res = undef_uri_params_resources.resources[1] + res = undef_uri_params_resources.resources[1] - # TODO: Fix undeclared uri params - # assert len(res.uri_params) == 1 - # assert res.uri_params[0].name == "id" - pass + assert len(res.uri_params) == 1 + assert res.uri_params[0].name == "id" @pytest.fixture(scope="session") diff --git a/tests/v020tests/test_resources.py b/tests/v020tests/test_resources.py index 5e2e704..5bab9b9 100644 --- a/tests/v020tests/test_resources.py +++ b/tests/v020tests/test_resources.py @@ -351,7 +351,7 @@ def test_uri_params(api): # get /thingy-gizmos/{id} res = api.resources[4] - u = res.uri_params[1] + u = res.uri_params[0] assert u.name == "external_party" assert u.display_name == "external_party" assert u.description.raw == "code of third-party partner" @@ -364,7 +364,7 @@ def test_uri_params(api): ] assert_not_set(u, not_set) - u = res.uri_params[0] + u = res.uri_params[1] assert u.name == "id" assert u.display_name == "id" assert u.description.raw == "The thingy gizmo id"