Skip to content

Commit

Permalink
Added an if/then/else step to Fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
epsy committed Apr 7, 2016
1 parent dfe9f10 commit c723bbd
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
30 changes: 25 additions & 5 deletions napper/restspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ class Conversion(enum.Enum):
MATCHER = 5

@classmethod
def convert_arg(cls, func, arg):
conv = getattr(func, 'convert_arg', cls.WHOLE)
def convert(cls, conv, arg):
if conv == cls.RAW:
try:
return arg._value
Expand All @@ -155,6 +154,10 @@ def convert_arg(cls, func, arg):
return Matcher.from_restspec(arg)
raise AssertionError("Bad conversion type", conv)

@classmethod
def convert_for_func(cls, func, arg):
return cls.convert(getattr(func, 'convert_arg', cls.WHOLE), arg)


def attr_setter(attr, base_type):
def func(value):
Expand All @@ -167,6 +170,7 @@ def deco(func):


convert_arg = attr_setter('convert_arg', Conversion)
takes_keywords = attr_setter('takes_keywords', dict)


def boolean_result(func):
Expand Down Expand Up @@ -198,14 +202,22 @@ def from_restspec(cls, obj):
with step:
conds = []
has_noncond = False
errors = []
for key in step:
try:
func = getattr(ret, 'step_' + key)
except AttributeError:
raise ValueError("Unknown step: " + key)
errors.append(key)
else:
par = partial(func,
Conversion.convert_arg(func, step[key]))
kwds = getattr(func, 'takes_keywords', {})
kwargs = {}
for kname, conv in kwds.items():
kwargs[kname] = Conversion.convert(
conv, step[kname.rstrip('_')])
par = partial(
func,
Conversion.convert_for_func(func, step[key]),
**kwargs)
if getattr(func, 'boolean_result', False):
conds.append(par)
else:
Expand Down Expand Up @@ -310,6 +322,14 @@ def step_all(self, args, value, context):
def step_any(self, args, value, context):
return any(arg(value, context) for arg in args)

@convert_arg(Conversion.WHOLE_CONDITIONAL)
@takes_keywords({'then_': Conversion.WHOLE, 'else_': Conversion.WHOLE})
def step_if(self, cond, value, context, *, then_, else_):
if cond(value, context):
return then_(value, context)
else:
return else_(value, context)


class Conditional(Fetcher):
@classmethod
Expand Down
5 changes: 5 additions & 0 deletions napper/tests/test_restspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ def test_root(self):
f = self.f(['Hello {}!', {'format': [[{'context': 'root'}, {'attr': 'name'}]]}])
self.assertEqual('Hello John!', f({'name': 'John'}))

def test_ifelse(self):
f = self.f({'if': {'is_eq': 23}, 'then': 'abc', 'else': 'def'})
self.assertEqual(f(23), 'abc')
self.assertEqual(f(24), 'def')


class ConditionalTests(Tests):
def c(self, obj):
Expand Down

0 comments on commit c723bbd

Please sign in to comment.