aboutsummaryrefslogtreecommitdiffstats
path: root/testing/tests/gen_ws_tests.py
blob: d8c809ccf89b03a35b2eead513395c44eb81ee47 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from itertools import product, chain, zip_longest, tee


IF, ELSE_IF, ELSE, END_IF = 0, 1, 2, 3

NL = "\\n"
dash = lambda ws: [" ", "-"][ws]


def cond_kind(i, n):
    i += 1
    if i == 1:
        return IF # if
    elif (i == n) and (i > 1):
        return ELSE # else
    elif i > n:
        return END_IF # endif
    else:
        return ELSE_IF # else if


# From: https://docs.python.org/3/library/itertools.html#itertools-recipes
def pairwise(iterable):
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)


def write_cond(conds, active_branch):
    n = len(conds) - 1

    lits = []
    for i in range(1, n + 2 + 1):
        ws1 = "\\n" * i
        ws2 = "\\r\\n" * i
        lits.append((ws1, str(i), ws2))

    conds = list(conds)
    for i, (pws, nws) in enumerate(conds):
        kind = cond_kind(i, n)
        b = str(i == active_branch).lower()
        cond = [f"if {b}", f"else if {b}", "else", "endif"][kind]
        cond = f"{{%{dash(pws)} {cond} {dash(nws)}%}}"
        conds[i] = cond

    it = map("".join, lits)
    it = filter(None, chain.from_iterable(zip_longest(it, conds)))
    code = "".join(it)

    expected = f"{lits[0][0]}{lits[0][1]}"
    for i, (cond, (before, after)) in enumerate(zip(conds, pairwise(lits))):
        kind = cond_kind(i, n)
        pws = cond.startswith("{%-")
        nws = cond.endswith("-%}")

        cond = i == active_branch
        prev_cond = i == (active_branch + 1)

        if prev_cond or (kind == IF):
            expected += before[2] * (not pws)
        if cond or (kind == END_IF):
            expected += after[0] * (not nws)
            expected += after[1]

    # FIXME: Askama does not include whitespace before eof
    # expected += lits[-1][2]

    return code, expected


if __name__ == "__main__":
    # The amount of branches to generate
    n = 2 # branches


    with open("ws.rs", "w") as f:
        f.write("""\
// This file is auto generated by gen_ws_tests.py

use askama::Template;

macro_rules! test_template {
    ($source:literal, $rendered:expr) => {{
        #[derive(Template)]
        #[template(source = $source, ext = "txt")]
        struct CondWS;

        assert_eq!(CondWS.render().unwrap(), $rendered);
    }};
}

#[rustfmt::skip]
#[test]
fn test_cond_ws() {
""")

        for branches in range(1, n + 1):
            for x in product([False, True], repeat=(branches+1)*2):
                # it = iter(x)
                # conds = list(zip(it, it))
                conds = list(zip(x[::2], x[1::2]))

                for i in range(branches):
                    code, expected = write_cond(conds, i)
                    f.write(f'    test_template!("{code}", "{expected}");\n')

            if branches != n:
                f.write("\n")
        f.write("}\n")