def test_filter_chaining():
    template = '''{{ (xs|first|last).gsom|sort|length }}'''
    ast = parse(template).find(nodes.Filter)
    rtype, struct = visit_filter(ast, get_scalar_context(ast))

    expected_struct = Dictionary({
        'xs':
        List(List(Dictionary(
            {
                'gsom': List(Unknown(), label='gsom', linenos=[1]),
            },
            linenos=[1]),
                  linenos=[1]),
             label='xs',
             linenos=[1]),
    })
    assert struct == expected_struct

    template = '''{{ x|list|sort|first }}'''
    ast = parse(template).find(nodes.Filter)
    rtype, struct = visit_filter(ast, get_scalar_context(ast))

    expected_struct = Dictionary({
        'x': Scalar(label='x', linenos=[1]),
    })
    assert struct == expected_struct

    template = '''{{ x|first|list }}'''
    ast = parse(template).find(nodes.Filter)
    with pytest.raises(UnexpectedExpression):
        visit_filter(ast, get_scalar_context(ast))
Exemple #2
0
def test_getitem_1():
    template = '''{{ a['b']['c'][1]['d'][x] }}'''
    ast = parse(template).find(nodes.Getitem)
    config = Config()
    config.TYPE_OF_VARIABLE_INDEXED_WITH_VARIABLE_TYPE = 'list'
    rtype, struct = visit_getitem(ast, get_scalar_context(ast), {}, config)

    expected_struct = Dictionary({
        'a':
        Dictionary(
            {
                'b':
                Dictionary(
                    {
                        'c':
                        List(Dictionary(
                            {
                                'd':
                                List(Scalar(linenos=[1]),
                                     label='d',
                                     linenos=[1])
                            },
                            linenos=[1]),
                             label='c',
                             linenos=[1]),
                    },
                    label='b',
                    linenos=[1]),
            },
            label='a',
            linenos=[1]),
        'x':
        Scalar(label='x', linenos=[1]),
    })
    assert struct == expected_struct
Exemple #3
0
def test_basics_15():
    # 1. Accept no unknown filter (default behavior)
    config = Config()

    template = '''
    {% for item in items %}
        {{ item.attr1|lower }}
        {{ item.attr2|bar }}
    {% endfor %}
    '''

    with pytest.raises(InvalidExpression) as e:
        infer(template, config)
    assert 'line 4: unknown filter "bar"' == str(e.value)

    # 2. Accept all unknown filters
    config = Config()
    config.IGNORE_UNKNOWN_FILTERS = True

    template = '''
    {% for item in items %}
        {{ item.attr1|lower }}
        {{ item.attr2|bar }}
    {% endfor %}
    '''
    struct = infer(template, config)
    expected_struct = Dictionary({
        'items': List(Dictionary({
            'attr1': String(label='attr1', linenos=[3]),
            'attr2': Unknown(label='attr2', linenos=[4])
        }, label='item', linenos=[3, 4]), label='items', linenos=[2]),
    })
    assert struct == expected_struct
def test_length_filter():
    ast = parse('{{ xs|length }}').find(nodes.Filter)
    rtype, struct = visit_filter(ast, get_scalar_context(ast))
    assert rtype == Number(label='xs', linenos=[1])
    assert struct == Dictionary({
        'xs': List(Unknown(), label='xs', linenos=[1]),
    })
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
Exemple #6
0
def test_getattr_1():
    template = '{{ (x or y).field.subfield[2].a }}'
    ast = parse(template).find(nodes.Getattr)
    rtype, struct = visit_getattr(ast, get_scalar_context(ast))

    x_or_y_dict = {
        'field':
        Dictionary(
            {
                'subfield':
                List(Dictionary({'a': Scalar(label='a', linenos=[1])},
                                linenos=[1]),
                     label='subfield',
                     linenos=[1]),
            },
            label='field',
            linenos=[1]),
    }

    expected_struct = Dictionary({
        'x':
        Dictionary(x_or_y_dict, label='x', linenos=[1]),
        'y':
        Dictionary(x_or_y_dict, label='y', linenos=[1])
    })
    assert struct == expected_struct
def test_basics_13():
    config = Config()
    config.TYPE_OF_VARIABLE_INDEXED_WITH_INTEGER_TYPE = 'tuple'

    template = '''
    {% for x in xs %}
        {{ x[2] }}
        {{ x[3] }}
    {% endfor %}
    '''
    struct = infer(template, config)
    expected_struct = Dictionary({
        'xs':
        List(Tuple((
            Unknown(label=None, linenos=[]),
            Unknown(label=None, linenos=[]),
            Scalar(label=None, linenos=[3]),
            Scalar(label=None, linenos=[4]),
        ),
                   label='x',
                   linenos=[3, 4]),
             label='xs',
             linenos=[2])
    })
    assert struct == expected_struct
def test_list_becomes_dict():
    template = '''
{%   for r in PrjList %}
<tr><td><a class='btn btn-primary' href='/part/prj/{{ r[0] }}'>Select</a></td>
  <td> {{ r[1] }} [{{ r[0] }}] {{ ("<a href='mailto:"+r['email']+"'>") |safe if r['email'] }}</td>
  <td>{{ r['samplecount'] }}</td>
  </tr>
{%  endfor %}
    '''

    struct = infer(template)
    expected_struct = Dictionary({
        'PrjList':
        List(Dictionary(
            {
                0: Scalar(),
                1: Scalar(),
                'email': String(label="email", linenos=[4]),
                'samplecount': Scalar(label="samplecount", linenos=[5]),
            },
            label="r",
            linenos=[3, 4, 5]),
             label="PrjList",
             linenos=[2]),
    })
    assert struct == expected_struct
Exemple #9
0
def test_basics_8():
    template = '''
    {% for row in items|batch(3, '&nbsp;')|batch(1) %}
        {{ row[1].name }}
    {% endfor %}
    '''
    with pytest.raises(UnexpectedExpression) as excinfo:
        infer(template)
    e = excinfo.value

    assert isinstance(e.actual_ast, nodes.Filter)
    assert e.expected_struct == List(
        Dictionary({
            'name': Scalar(label='name', constant=False, linenos=[3])
        }, constant=False, linenos=[3]),
        label='row', constant=False, linenos=[2, 3]
    )
    assert e.actual_struct == List(List(Unknown()))
Exemple #10
0
def test_slice():
    template = '''{{ xs[a:2:b] }}'''
    ast = parse(template).find(nodes.Getitem)
    rtype, struct = visit_getitem(ast, get_scalar_context(ast))
    assert struct == Dictionary({
        'xs': List(Scalar(linenos=[1]), label='xs', linenos=[1]),
        'a': Number(label='a', linenos=[1]),
        'b': Number(label='b', linenos=[1]),
    })
def test_for_2():
    template = '''
    {% for x in xs %}
        {{ x }}
        {% for y in ys %}
            {{ loop.index0 }}
        {% endfor %}
        {{ loop.length }}
    {% endfor %}
    '''
    ast = parse(template)
    struct = infer_from_ast(ast)

    expected_struct = Dictionary({
        'xs': List(Scalar(label='x', linenos=[3]), label='xs', linenos=[2]),
        'ys': List(Unknown(linenos=[4]), label='ys', linenos=[4]),
    })
    assert struct == expected_struct
Exemple #12
0
def test_basics_6():
    template = '''
    {% for row in items|batch(3, '&nbsp;') %}
    {% endfor %}
    '''
    struct = infer(template)
    expected_struct = Dictionary({
        'items': List(Unknown(), label='items', linenos=[2]),
    })
    assert struct == expected_struct
Exemple #13
0
def test_basics_9():
    template = '''
    {% set xs = items|batch(3, '&nbsp;') %}
    {{ xs[0][0] }}
    '''
    struct = infer(template)
    expected_struct = Dictionary({
        'items': List(Unknown(), label='items', linenos=[2]),  # TODO it should be Scalar
    })
    assert struct == expected_struct
def test_join_filter():
    ast = parse('{{ xs|join(separator|default("|")) }}').find(nodes.Filter)
    rtype, struct = visit_filter(ast, get_scalar_context(ast))
    assert rtype == String(label='xs', linenos=[1])
    assert struct == Dictionary({
        'xs':
        List(String(), label='xs', linenos=[1]),
        'separator':
        String(label='separator', linenos=[1], used_with_default=True),
    })
def test_max_min_filter():
    for filter in ('max', 'min'):
        template = '{{ values|' + filter + ' }}'
        ast = parse(template).find(nodes.Filter)

        rtype, struct = visit_filter(ast, get_scalar_context(ast))
        assert rtype == Scalar(label='values', linenos=[1])
        assert struct == Dictionary({
            'values':
            List(Scalar(linenos=[1]), label='values', linenos=[1]),
        })
def test_length_filter():
    for filter in ('count', 'length'):
        template = '{{ xs|' + filter + ' }}'

        ast = parse(template).find(nodes.Filter)
        rtype, struct = visit_filter(ast, get_scalar_context(ast))
        assert rtype == Number(label='xs', linenos=[1])
        assert struct == Dictionary({
            'xs':
            List(Unknown(), label='xs', linenos=[1]),
        })
def test_sum_filter():
    template = '{{ x|sum }}'

    ast = parse(template).find(nodes.Filter)
    rtype, struct = visit_filter(ast, get_scalar_context(ast))

    assert rtype == Scalar(label='x', linenos=[1])
    expected_struct = Dictionary({
        'x': List(Scalar(), label='x', linenos=[1]),
    })
    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]),
    })
Exemple #19
0
def test_compare_2():
    template = '{{ a + b[1] - c == 4 == x }}'
    ast = parse(template).find(nodes.Compare)
    rtype, struct = visit_compare(ast, get_scalar_context(ast))
    # TODO make customizable
    expected_struct = Dictionary({
        'a': Unknown(label='a', linenos=[1]),
        'b': List(Unknown(linenos=[1]), label='b', linenos=[1]),
        'c': Unknown(label='c', linenos=[1]),
        'x': Unknown(label='x', linenos=[1]),
    })
    assert struct == expected_struct
Exemple #20
0
def test_getattr_3():
    template = '''{{ a[z][1:\nn][1].x }}'''
    ast = parse(template).find(nodes.Getattr)
    config = Config()
    config.TYPE_OF_VARIABLE_INDEXED_WITH_VARIABLE_TYPE = 'list'
    rtype, struct = visit_getattr(ast, get_scalar_context(ast), {}, config)

    expected_struct = Dictionary({
        'a':
        List(List(List(Dictionary({'x': Scalar(label='x', linenos=[2])},
                                  linenos=[2]),
                       linenos=[2]),
                  linenos=[1]),
             label='a',
             linenos=[1]),
        'z':
        Scalar(label='z', linenos=[1]),
        'n':
        Number(label='n', linenos=[2])
    })
    assert struct == expected_struct
Exemple #21
0
def test_basics_11():
    template = '''
    {{ a|xmlattr }}
    {{ a.attr1|join(',') }}
    {{ a.attr2|default([])|first }}
    {{ a.attr3|default('gsom') }}
    {% for x in xs|rejectattr('is_active') %}
        {{ x }}
    {% endfor %}
    '''
    struct = infer(template)
    expected_struct = Dictionary({
        'a':
        Dictionary(
            {
                'attr1':
                List(String(), label='attr1', linenos=[3]),
                'attr2':
                List(Scalar(linenos=[4]),
                     label='attr2',
                     linenos=[4],
                     used_with_default=True),
                'attr3':
                String(label='attr3',
                       linenos=[5],
                       used_with_default=True,
                       value='gsom')
            },
            label='a',
            linenos=[2, 3, 4, 5]),
        'xs':
        List(
            Scalar(label='x', linenos=[
                7
            ]),  # TODO it should be Dictionary({'is_active': Unknown()})
            label='xs',
            linenos=[6]),
    })
    assert struct == expected_struct
Exemple #22
0
def test_basics_7():
    template = '''
    {% for row in items|batch(3, '&nbsp;')|batch(1) %}
        {{ row[1][1].name }}
    {% endfor %}
    '''
    struct = infer(template)
    expected_struct = Dictionary({
        'items': List(Dictionary({
            'name': Scalar(label='name', linenos=[3]),
        }, linenos=[3]), label='items', linenos=[2, 3]),
    })
    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_for_1():
    template = '''
    {% for x in a.b %}
        {{ x }}
    {% endfor %}
    '''
    ast = parse(template).find(nodes.For)
    struct = visit_for(ast)
    expected_struct = Dictionary({
        'a': Dictionary({
            'b': List(Scalar(label='x', linenos=[3]), label='b', linenos=[2])
        }, label='a', linenos=[2]),
    })
    assert struct == expected_struct
def test_filter_chaining():
    template = '''{{ (xs|first|last).gsom|sort|length }}'''
    ast = parse(template).find(nodes.Filter)
    rtype, struct = visit_filter(ast, get_scalar_context(ast))

    expected_struct = Dictionary({
        'xs':
        List(List(Dictionary(
            {
                'gsom': List(Unknown(), label='gsom', linenos=[1]),
            },
            linenos=[1]),
                  linenos=[1]),
             label='xs',
             linenos=[1]),
    })
    assert struct == expected_struct

    template = '''{{ x|list|sort|first }}'''
    ast = parse(template).find(nodes.Filter)
    rtype, struct = visit_filter(ast, get_scalar_context(ast))

    expected_struct = Dictionary({
        'x': Scalar(label='x', linenos=[1]),
    })
    assert struct == expected_struct

    template = '''{{ x|first|list }}'''
    ast = parse(template).find(nodes.Filter)
    with pytest.raises(UnexpectedExpression) as e:
        visit_filter(ast, get_scalar_context(ast))
    expected = "conflict on the line 1\n\
got: AST node jinja2.nodes.Filter of structure [<scalar>]\n\
expected structure: <scalar>"

    assert expected == str(e.value)
def test_batch_and_slice_filters():
    for filter in ('batch', 'slice'):
        template = '{{ items|' + filter + '(3, "&nbsp;") }}'
        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>')
Exemple #27
0
def test_basics_5():
    template = '''
    {% for row in items|batch(3, '&nbsp;') %}
        {% for column in row %}
            {{ column.x }}
        {% endfor %}
    {% endfor %}
    '''
    struct = infer(template)
    expected_struct = Dictionary({
        'items': List(Dictionary({
            'x': Scalar(label='x', linenos=[4])
        }, label='column', linenos=[4]), label='items', linenos=[2, 3]),
    })
    assert struct == expected_struct
def test_assign_5():
    template = '''
    {%- set weights = [
        ('A', {'data': 0.3}),
        ('B', {'data': 0.9}),
    ] %}
    '''
    ast = parse(template).find(nodes.Assign)
    struct = visit_assign(ast)
    expected_struct = Dictionary({
        'weights': List(Tuple([
            String(linenos=[3, 4], constant=True),
            Dictionary({
                'data': Number(linenos=[3, 4], constant=True)
            }, linenos=[3, 4], constant=True),
        ], linenos=[3, 4], constant=True), label='weights', linenos=[2], constant=True)
    })
    assert struct == expected_struct
def test_for_3():
    template = '''
    {% for a, b in list %}
        {{ a.field }}
        {{ b }}
    {% endfor %}
    '''
    ast = parse(template).find(nodes.For)
    struct = visit_for(ast)

    expected_struct = Dictionary({
        'list': List(Tuple((
            Dictionary({
                'field': Scalar(label='field', linenos=[3])
            }, label='a', linenos=[3]),
            Scalar(label='b', linenos=[4])
        ), linenos=[2]), label='list', linenos=[2])
    })
    assert struct == expected_struct
Exemple #30
0
def test_for():
    template = '''
    {% for number in range(10 - users|length) %}
        {{ number }}
    {% endfor %}
    '''
    struct = infer(template)
    expected_struct = Dictionary({
        'users':
        List(Unknown(), label='users', linenos=[2]),
    })
    assert struct == expected_struct

    template = '''
    {% for number in range(10 - users|length) %}
        {{ number.field }}
    {% endfor %}
    '''
    with pytest.raises(MergeException):
        infer(template)

    template = '{{ range(10 - users|length) }}'
    with pytest.raises(UnexpectedExpression):
        infer(template)

    template = '''
    {% for number in lipsum(n=10) %}
    {% endfor %}
    '''
    with pytest.raises(UnexpectedExpression):
        infer(template)

    template = '''
    {% for k, v in data|dictsort %}
        {{ k.x }}
        {{ v }}
    {% endfor %}
    '''
    with pytest.raises(UnexpectedExpression):
        infer(template)