Skip to content

Commit

Permalink
fixed order of uri/base uri params; create undeclared uri params
Browse files Browse the repository at this point in the history
  • Loading branch information
econchick committed Feb 1, 2016
1 parent e319dec commit d3a58a7
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 26 deletions.
6 changes: 5 additions & 1 deletion ramlfications/parser/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions ramlfications/parser/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)


#####
Expand All @@ -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":
Expand All @@ -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


Expand Down
23 changes: 22 additions & 1 deletion ramlfications/utils/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
38 changes: 38 additions & 0 deletions ramlfications/utils/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from __future__ import absolute_import, division, print_function

import re

from six import iterkeys, string_types

from .common import (
Expand Down Expand Up @@ -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
#####
Expand Down
34 changes: 14 additions & 20 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<maxPages>> pages returned"
assert len(resp.headers) == 1

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand All @@ -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")
Expand Down
4 changes: 2 additions & 2 deletions tests/v020tests/test_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down

0 comments on commit d3a58a7

Please sign in to comment.