Skip to content

Commit

Permalink
Expose more parse type functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
timofurrer committed Oct 26, 2019
1 parent 22f4141 commit 80c85ee
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ The following packages can be imported from the radish package:

# Step Pattern Types
custom_type,
register_custom_type,
TypeBuilder,

# The radish parser
FeatureFileParser,
Expand Down
36 changes: 36 additions & 0 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,41 @@ The following table shows all built-in types:
| tt | Time e.g. 10:21:36 PM -5:30 | time |
+-----------------+-------------------------------------------------------------------------------+-------------+

All the above types can be combined with a cardinality:

.. code:: text
"{:type}" #< Cardinality: 1 (one; the normal case)
"{:type?}" #< Cardinality: 0..1 (zero or one = optional)
"{:type*}" #< Cardinality: 0..* (zero or more = many0)
"{:type+}" #< Cardinality: 1..* (one or more = many)
... whereas ``type`` stands for the actual type which should be used.

By default the ``,`` (comma) is used as a separator between multiple occurences
within the cardinality. However, one can specify their own separator.
Let's assume ``and`` should be used instead of ``,``:

.. code:: python
from radish import custom_type, register_custom_type, TypeBuilder
@custom_type("User", r"[A-Za-z0-9]+")
def user_type(text):
"""
Match a username and retrieve the ``User``
"""
# some database lookup
user = User(...)
return user
# register the NumberList type
register_custom_type(UserList=TypeBuilder.with_many(
user_type, listsep='and'))
Now you can use ``UserList`` as the type in the step pattern.
Follow the documentation to learn more about the ``custom_type()`` decorator.

Implementing custom Step Patterns
`````````````````````````````````

Expand Down Expand Up @@ -334,6 +369,7 @@ a Step Implementation function:
def when_load_user(step, user):
...
Regular Expression Syntax
.........................

Expand Down
2 changes: 1 addition & 1 deletion src/radish/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@
Tag
)
from radish.parser import FeatureFileParser # noqa
from radish.parsetyperegistry import custom_type # noqa
from radish.parsetyperegistry import custom_type, register_custom_type, TypeBuilder # noqa
from radish.stepregistry import given, step, then, when # noqa
from radish.terrain import world # noqa
21 changes: 18 additions & 3 deletions src/radish/parsetyperegistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
:license: MIT, see LICENSE for more details.
"""

from parse_type import TypeBuilder # noqa

from radish.errors import RadishError


Expand All @@ -17,7 +19,7 @@ class ParseTypeRegistry:
def __init__(self):
self.types = {}

def register(self, name, pattern, func):
def register(self, name, func, pattern=None):
"""Register a new parse type"""
if name in self.types:
raise RadishError(
Expand All @@ -26,7 +28,9 @@ def register(self, name, pattern, func):
)
)

func.pattern = pattern
if pattern is not None:
func.pattern = pattern

self.types[name] = func

def create_decorator(self, context=None):
Expand All @@ -41,7 +45,7 @@ def create_decorator(self, context=None):
def __create_decorator(decorator_name):
def __decorator(name, pattern):
def __wrapper(func):
self.register(name, pattern, func)
self.register(name, func, pattern)
return func

return __wrapper
Expand All @@ -56,4 +60,15 @@ def __wrapper(func):
#: Holds a global instance of the ParseTypeRegistry which shall be used
# by all modules implementing Custom Parse Types.
registry = ParseTypeRegistry()


def register_custom_type(**kwargs):
"""Register a custom type
The arguments are expected to be in the form of: type-name=func.
"""
for name, func in kwargs.items():
registry.register(name, func)


__all__ = registry.create_decorator()
8 changes: 4 additions & 4 deletions tests/unit/test_parsetyperegistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_parsetyperegistry_should_register_funcs_as_custom_parse_types():
custom_parse_type_func = lambda x: x # noqa

# when
registry.register("name", "pattern", custom_parse_type_func)
registry.register("name", custom_parse_type_func, "pattern")

# then
assert registry.types == {"name": custom_parse_type_func}
Expand All @@ -44,12 +44,12 @@ def test_parsetyperegistry_should_only_allow_unique_custom_parse_type_names():
# given
registry = ParseTypeRegistry()
custom_parse_type_func = lambda x: x # noqa
registry.register("name", "pattern", custom_parse_type_func)
registry.register("name", custom_parse_type_func, "pattern")

# then
with pytest.raises(RadishError):
# when
registry.register("name", "pattern", custom_parse_type_func)
registry.register("name", custom_parse_type_func, "pattern")


def test_parsetyperegistry_should_assign_pattern_to_func_during_register():
Expand All @@ -62,7 +62,7 @@ def test_parsetyperegistry_should_assign_pattern_to_func_during_register():
custom_parse_type_func = lambda x: x # noqa

# when
registry.register("name", "pattern", custom_parse_type_func)
registry.register("name", custom_parse_type_func, "pattern")

# then
assert custom_parse_type_func.pattern == "pattern"
Expand Down

0 comments on commit 80c85ee

Please sign in to comment.