aboutsummaryrefslogtreecommitdiff
path: root/lib/testing.nom
blob: 83d0108aac0f0d689b1d2cacd63c43955a526cad (plain)
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
require "lib/metaprogramming.nom"

# For unit testing
macro block [test %code yields %expected] =:


    _yield_tree: (tree, indent_level=0)=>
        ind = (s) -> INDENT\rep(indent_level)..s
        switch tree.type
            when "File"
                coroutine.yield(ind"File:")
                @_yield_tree(tree.value.body, indent_level+1)
            when "Errors" then coroutine.yield(ind"Error:\n#{tree.value}")
            when "Block"
                for chunk in *tree.value
                    @_yield_tree(chunk, indent_level)
            when "Thunk"
                coroutine.yield(ind"Thunk:")
                @_yield_tree(tree.value, indent_level+1)
            when "Statement" then @_yield_tree(tree.value, indent_level)
            when "FunctionCall"
                alias = @get_alias tree
                args = [a for a in *tree.value when a.type != "Word"]
                if #args == 0
                    coroutine.yield(ind"Call [#{alias}]!")
                else
                    coroutine.yield(ind"Call [#{alias}]:")
                    for a in *args
                        @_yield_tree(a, indent_level+1)
            when "String" then coroutine.yield(ind(repr(tree.value)))
            when "Longstring" then coroutine.yield(ind(repr(tree.value)))
            when "Number" then coroutine.yield(ind(tree.value))
            when "Var" then coroutine.yield ind"Var[#{repr(tree.value)}]"
            when "List"
                if #tree.value == 0
                    coroutine.yield(ind("<Empty List>"))
                else
                    coroutine.yield(ind"List:")
                    for item in *tree.value
                        @_yield_tree(item, indent_level+1)
            else error("Unknown/unimplemented thingy: #{tree.type}")

    print_tree:(tree)=>
        for line in coroutine.wrap(-> @_yield_tree(tree))
            @writeln(line)

    stringify_tree:(tree)=>
        result = {}
        for line in coroutine.wrap(-> @_yield_tree(tree))
            insert(result, line)
        return concat result, "\n"

    test: (src, filename, expected)=>
        i = 1
        while i != nil
            start,stop = src\find("\n\n", i)

            test = src\sub(i,start)
            i = stop
            start,stop = test\find"==="
            if not start or not stop then
                @error("WHERE'S THE ===? in:\n#{test}")
            test_src, expected = test\sub(1,start-1), test\sub(stop+1,-1)
            expected = expected\match'[\n]*(.*[^\n])'
            tree = @parse(test_src, filename)
            got = @stringify_tree(tree.value.body)
            if got != expected
                @error"TEST FAILED!\nSource:\n#{test_src}\nExpected:\n#{expected}\n\nGot:\n#{got}"





    %generated =: repr (nomsu "stringify_tree" [%code's "value"])
    %expected =: %expected as lua
    if (%generated != %expected):
        say "Test failed!"
        say "Expected:"
        say %expected
        say "But got:"
        say %generated
        error!
    return ""