def test_str_method_calls(): template = '''{{ x.endswith(suffix) }}''' call_ast = parse(template).find(nodes.Call) rtype, struct = visit_call(call_ast, get_scalar_context(call_ast)) expected_rtype = Boolean() assert rtype == expected_rtype expected_struct = Dictionary({ 'x': String(label='x', linenos=[1]), # TODO suffix must be in struct too }) assert struct == expected_struct template = '''{{ x.split(separator) }}''' call_ast = parse(template).find(nodes.Call) ctx = Context(return_struct_cls=Unknown, predicted_struct=Unknown.from_ast(call_ast)) rtype, struct = visit_call(call_ast, ctx) expected_rtype = List(String()) assert rtype == expected_rtype expected_struct = Dictionary({ 'x': String(label='x', linenos=[1]), 'separator': String(label='separator', linenos=[1]), }) assert struct == expected_struct
def test_dict_call(): template = '''{{ dict(x=\ndict(\na=1, b=2), y=a) }}''' call_ast = parse(template).find(nodes.Call) rtype, struct = visit_call( call_ast, Context(predicted_struct=Unknown.from_ast(call_ast))) expected_rtype = Dictionary( { 'x': Dictionary( { 'a': Number(linenos=[3], constant=True, value=1), 'b': Number(linenos=[3], constant=True, value=2) }, linenos=[2], constant=True), 'y': Unknown(label='a', linenos=[3]), }, linenos=[1], constant=True) assert rtype == expected_rtype expected_struct = Dictionary({ 'a': Unknown(label='a', linenos=[3]), }) assert struct == expected_struct
def test_unique_filter(): template = '{{ values|unique }}' ast = parse(template).find(nodes.Filter) unknown_ctx = Context(predicted_struct=Unknown.from_ast(ast)) rtype, struct = visit_filter(ast, unknown_ctx) assert rtype == Unknown(label='values', linenos=[1]) assert struct == Dictionary({ 'values': List(Unknown(), label='values', linenos=[1]), })
def test_lipsum_call(): template = '{{ lipsum(n) }}' ast = parse(template).find(nodes.Call) rtype, struct = visit_call(ast, Context(predicted_struct=Unknown())) expected_rtype = String() assert rtype == expected_rtype expected_struct = Dictionary({ 'n': Scalar(label='n', linenos=[1]), # TODO must be Number }) assert struct == expected_struct
def test_range_call(): template = '{{ range(n) }}' ast = parse(template).find(nodes.Call) rtype, struct = visit_call(ast, Context(predicted_struct=Unknown())) expected_rtype = List(Number()) assert rtype == expected_rtype expected_struct = Dictionary({ 'n': Number(label='n', linenos=[1]), }) assert struct == expected_struct
def test_batch_and_slice_filters(): for filter in ('batch', 'slice'): template = '{{ items|' + filter + '(3, " ") }}' ast = parse(template).find(nodes.Filter) unknown_ctx = Context(predicted_struct=Unknown.from_ast(ast)) rtype, struct = visit_filter(ast, unknown_ctx) expected_rtype = List(List(Unknown(), linenos=[1]), linenos=[1]) assert rtype == expected_rtype expected_struct = Dictionary({ 'items': List(Unknown(), label='items', linenos=[1]), }) assert struct == expected_struct scalar_ctx = Context(predicted_struct=Scalar.from_ast(ast)) with pytest.raises(UnexpectedExpression) as e: visit_filter(ast, scalar_ctx) assert str(e.value) == ( 'conflict on the line 1\n' 'got: AST node jinja2.nodes.Filter of structure [[<unknown>]]\n' 'expected structure: <scalar>')
def test_string_filters(): for filter in ('striptags', 'capitalize', 'title', 'upper', 'urlize'): template = '{{ x|' + filter + ' }}' ast = parse(template).find(nodes.Filter) ctx = Context(return_struct_cls=Scalar, predicted_struct=Scalar.from_ast(ast)) rtype, struct = visit_filter(ast, ctx) expected_rtype = String(label='x', linenos=[1]) expected_struct = Dictionary({ 'x': String(label='x', linenos=[1]), }) assert rtype == expected_rtype assert struct == expected_struct
def get_scalar_context(ast): return Context(return_struct_cls=Scalar, predicted_struct=Scalar.from_ast(ast))