diff options
-rw-r--r-- | jinja2/asyncfilters.py | 21 | ||||
-rw-r--r-- | tests/test_asyncfilters.py | 49 |
2 files changed, 69 insertions, 1 deletions
diff --git a/jinja2/asyncfilters.py b/jinja2/asyncfilters.py index 2a6eb520..26caccbc 100644 --- a/jinja2/asyncfilters.py +++ b/jinja2/asyncfilters.py @@ -77,6 +77,11 @@ async def do_join(eval_ctx, value, d=u'', attribute=None): return filters.do_join(eval_ctx, await auto_to_seq(value), d, attribute) +@asyncfiltervariant(filters.do_list) +async def do_list(value): + return await auto_to_seq(value) + + @asyncfiltervariant(filters.do_reject) async def do_reject(*args, **kwargs): return async_select_or_reject(args, kwargs, lambda x: not x, False) @@ -101,14 +106,27 @@ async def do_selectattr(*args, **kwargs): async def do_map(*args, **kwargs): seq, func = filters.prepare_map(args, kwargs) if seq: - async for item in seq: + async for item in auto_aiter(seq): yield func(item) +@asyncfiltervariant(filters.do_sum) +async def do_sum(environment, iterable, attribute=None, start=0): + rv = start + if attribute is not None: + func = filters.make_attrgetter(environment, attribute) + else: + func = lambda x: x + async for item in auto_aiter(iterable): + rv += func(item) + return rv + + ASYNC_FILTERS = { 'first': do_first, 'groupby': do_groupby, 'join': do_join, + 'list': do_list, # we intentionally do not support do_last because that would be # ridiculous 'reject': do_reject, @@ -116,4 +134,5 @@ ASYNC_FILTERS = { 'map': do_map, 'select': do_select, 'selectattr': do_selectattr, + 'sum': do_sum, } diff --git a/tests/test_asyncfilters.py b/tests/test_asyncfilters.py index 348a66b7..8732e780 100644 --- a/tests/test_asyncfilters.py +++ b/tests/test_asyncfilters.py @@ -165,3 +165,52 @@ def test_simple_select_attr(env_async, users): 'map(attribute="name")|join("|") }}' ) assert tmpl.render(users=users) == 'john|jane' + + +@mark_dualiter('items', lambda: list('123')) +def test_simple_map(env_async, items): + tmpl = env_async.from_string('{{ items()|map("int")|sum }}') + assert tmpl.render(items=items) == '6' + + +@mark_dualiter('users', make_users) +def test_attribute_map(env_async, users): + tmpl = env_async.from_string('{{ users()|map(attribute="name")|join("|") }}') + assert tmpl.render(users=users) == 'john|jane|mike' + + +def test_empty_map(env_async): + tmpl = env_async.from_string('{{ none|map("upper")|list }}') + assert tmpl.render() == '[]' + + +def test_sum(env_async): + tmpl = env_async.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''') + assert tmpl.render() == '21' + + +def test_sum_attributes(env_async): + tmpl = env_async.from_string('''{{ values|sum('value') }}''') + assert tmpl.render(values=[ + {'value': 23}, + {'value': 1}, + {'value': 18}, + ]) == '42' + + +def test_sum_attributes_nested(env_async): + tmpl = env_async.from_string('''{{ values|sum('real.value') }}''') + assert tmpl.render(values=[ + {'real': {'value': 23}}, + {'real': {'value': 1}}, + {'real': {'value': 18}}, + ]) == '42' + + +def test_sum_attributes_tuple(env_async): + tmpl = env_async.from_string('''{{ values.items()|sum('1') }}''') + assert tmpl.render(values={ + 'foo': 23, + 'bar': 1, + 'baz': 18, + }) == '42' |