blob: 2d40231496df3452d4021aa92fb5149f93e890fc [file] [log] [blame]
swissChili7babd922021-12-02 22:46:48 -08001#include <QCoreApplication>
2#include <QDebug>
3
swissChili3e98c062021-12-04 22:07:38 -08004#include "Matcher.h"
5#include "Token.h"
swissChilic71acc62021-12-07 08:03:37 -08006#include "AstNode.h"
7#include "Parser.h"
swissChili07d325f2021-12-08 20:02:05 -08008#include "Evaluator.h"
9#include "VarContext.h"
swissChili3e98c062021-12-04 22:07:38 -080010
11int g_numFailed = 0;
12
swissChili07d325f2021-12-08 20:02:05 -080013void testEval(QString function, QString expression, QString expected)
14{
15 Evaluator eval;
16 Parser funcParser(function),
17 exprParser(expression),
18 resParser(expected);
19
20 Function func;
21
22 QList<AstNode> expr = exprParser.parseMany<AstNode>();
23 QList<Token> res = resParser.parseMany<Token>();
24
25 QList<Token> result;
26
27 exprParser.skip();
28 resParser.skip();
29 while (funcParser.parseFunctionDefinition(&func))
30 {
31 eval.addFunction(func);
32 }
33
34 funcParser.skip();
35
36 if (!exprParser.atEnd() || !resParser.atEnd() || !funcParser.atEnd())
37 {
38 g_numFailed++;
39 qDebug() << "\n\033[31mTEST FAILS:\033[0m";
40 qDebug() << "Failed to fully parse expression, function or result";
41 qDebug() << function << expression << expected;
42
43 goto end;
44 }
45
46 for (const AstNode &node : expr)
47 {
48 RuntimeResult rr = eval.evaluate(node, VarContext());
49
50 if (!rr.success())
51 {
52 g_numFailed++;
53 qDebug() << "\n\033[31mTEST FAILS:\033[0m";
54 qDebug() << "Runtime error while evaluating" << node;
55 qDebug() << rr;
56
57 goto end;
58 }
59
60 result.append(rr.result());
61 }
62
63 if (result != res)
64 {
65 g_numFailed++;
66 qDebug() << "\n\033[31mTEST FAILS:\033[0m";
67 qDebug() << "Expected result" << res;
68 qDebug() << "Got" << result;
69 }
70
71end:
72 qDebug() << "\033[36mEvaluate\033[0m" << function << expression << "->" << result;
73}
74
swissChilic71acc62021-12-07 08:03:37 -080075void testMatch(const QString &test, bool shouldBe, const MatchResult &result)
76{
77 if (result.success != shouldBe)
78 {
swissChili3e98c062021-12-04 22:07:38 -080079 g_numFailed++;
swissChilic71acc62021-12-07 08:03:37 -080080 qDebug() << "\n\033[31mTEST FAILS:\033[0m";
swissChilid17b5a12021-12-05 20:46:42 -080081 qDebug() << "with context" << result.context;
swissChili3e98c062021-12-04 22:07:38 -080082 }
83
swissChilic71acc62021-12-07 08:03:37 -080084 qDebug() << "\033[36mMatchResult\033[0m" << test << result.success;
swissChilid17b5a12021-12-05 20:46:42 -080085
swissChilic71acc62021-12-07 08:03:37 -080086 if (result.success != shouldBe)
87 {
swissChilid17b5a12021-12-05 20:46:42 -080088 qDebug() << "";
89 }
swissChili3e98c062021-12-04 22:07:38 -080090}
91
swissChili682e7bc2021-12-07 09:04:54 -080092void testMatch(QString data, QString pattern, bool shouldBe = true)
93{
94 Parser dataParser(data),
95 patternParser(pattern);
96
swissChili07d325f2021-12-08 20:02:05 -080097 testMatch(pattern + " = " + data, shouldBe,
98 match(dataParser.parseMany<Token>(), patternParser.parseMany<Token>(), VarContext()));
swissChili682e7bc2021-12-07 09:04:54 -080099}
100
101void testParseAst(QString string)
swissChilic71acc62021-12-07 08:03:37 -0800102{
103 Parser parser{string};
104
swissChili682e7bc2021-12-07 09:04:54 -0800105 QList<AstNode> result = parser.parseMany<AstNode>();
swissChilic71acc62021-12-07 08:03:37 -0800106
107 qDebug() << "\033[36mParse\033[0m" << string << result;
108}
109
swissChili8a581c62021-12-07 13:29:21 -0800110void testParseFunc(QString string)
111{
112 Parser parser{string};
113
114 Function func;
115
116 if (!parser.parseFunctionDefinition(&func))
117 {
118 g_numFailed++;
119 qDebug() << "\n\033[31mTEST FAILS:\033[0m";
120 qDebug() << string;
121 }
122 else
123 {
124 qDebug() << "\033[36mFunction\033[0m";
125 qDebug().noquote() << func;
126 }
127}
128
swissChilic71acc62021-12-07 08:03:37 -0800129int testResults()
130{
131 if (g_numFailed == 0)
132 {
133 qDebug() << "\033[32mALL TESTS SUCCEEDED\033[0m";
134 }
135 else
136 {
137 qDebug().nospace() << "\033[31m" << g_numFailed << " TESTS FAILED\033[0m";
swissChili3e98c062021-12-04 22:07:38 -0800138 }
139
140 return g_numFailed;
141}
142
swissChilic71acc62021-12-07 08:03:37 -0800143void testAllMatches()
144{
145 testMatch("a = a", true, match({Token('a')}, {Token('a')}, VarContext()));
swissChili3e98c062021-12-04 22:07:38 -0800146
swissChilic71acc62021-12-07 08:03:37 -0800147 testMatch("s.a = y", true, match({Token('y')}, {Token('s', "a")}, VarContext()));
swissChilid17b5a12021-12-05 20:46:42 -0800148
swissChili3e98c062021-12-04 22:07:38 -0800149 LTok sameTwo = {Token('s', "a"), Token('s', "a")};
swissChilic71acc62021-12-07 08:03:37 -0800150 testMatch("s.a s.a = aa", true, match({Token('a'), Token('a')}, sameTwo, VarContext()));
151 testMatch("s.a s.a = ab", false, match({Token('a'), Token('b')}, sameTwo, VarContext()));
swissChili3e98c062021-12-04 22:07:38 -0800152
153 LTok sameStartEnd = {
swissChilic71acc62021-12-07 08:03:37 -0800154 Token('s', "a"),
155 Token('e', "middle"),
156 Token('s', "a")};
157 testMatch("s.a e.middle s.a = aea", true,
158 match({Token('a'), Token('e'), Token('a')}, sameStartEnd, VarContext()));
swissChili3e98c062021-12-04 22:07:38 -0800159
swissChilic71acc62021-12-07 08:03:37 -0800160 testMatch("s.a e.middle s.a = aef Hi a", true,
161 match({Token('a'), Token('e'), Token('f'), Token("Hi"), Token('a')}, sameStartEnd, VarContext()));
swissChili3e98c062021-12-04 22:07:38 -0800162
swissChilic71acc62021-12-07 08:03:37 -0800163 testMatch("s.a e.middle s.a = aef Hi c", false,
164 match({Token('a'), Token('e'), Token('f'), Token("Hi"), Token('c')}, sameStartEnd, VarContext()));
swissChilid17b5a12021-12-05 20:46:42 -0800165
166 LTok parenthesized = {
swissChilic71acc62021-12-07 08:03:37 -0800167 Token(LTok({Token('s', "a")})),
168 Token('e', "Middle"),
169 Token('s', "a"),
swissChilid17b5a12021-12-05 20:46:42 -0800170 };
171 LTok parenTest1 = {
swissChilic71acc62021-12-07 08:03:37 -0800172 Token(LTok({Token('y')})),
173 Token('f'),
174 Token("MiddleStuff"),
175 Token('y')};
swissChilid17b5a12021-12-05 20:46:42 -0800176
swissChilic71acc62021-12-07 08:03:37 -0800177 testMatch("(s.a) e.Middle s.a = (y)f MiddleStuff y", true,
swissChilid17b5a12021-12-05 20:46:42 -0800178 match(parenTest1, parenthesized, VarContext()));
swissChili682e7bc2021-12-07 09:04:54 -0800179 // testMatch("(y)f Middle-stuff y", "(s.a) e.Middle s.a");
swissChilid17b5a12021-12-05 20:46:42 -0800180
swissChili682e7bc2021-12-07 09:04:54 -0800181 testMatch("(a)", "(a)");
swissChili07d325f2021-12-08 20:02:05 -0800182 testMatch("hello", "s.A e.Rest");
swissChili3e98c062021-12-04 22:07:38 -0800183}
184
swissChilic71acc62021-12-07 08:03:37 -0800185void testAllParses()
186{
swissChili682e7bc2021-12-07 09:04:54 -0800187 testParseAst("all symbols");
188 testParseAst("Identifier symbols Identifier");
189 testParseAst("s.A");
190 testParseAst("(s.A) Variable-quoted");
191 testParseAst("<Func-name a b (c)>");
192 testParseAst("<Prout hi>");
193 testParseAst("(Prout hi)");
194 testParseAst("(<Prout hi>)");
195 testParseAst("<If T Then (<Prout hi>) Else (<Prout sorry>)>");
196 testParseAst("(s.a) e.Middle s.a");
swissChili8a581c62021-12-07 13:29:21 -0800197 testParseAst("Hello; Goodbye");
198 testParseAst("Key = Value");
199}
200
201void testAllFunctionDefs()
202{
203 testParseFunc("Test { = HI; }");
swissChili07d325f2021-12-08 20:02:05 -0800204 testParseFunc("Palindrome { = T; s.A = T; s.A s.A = T; s.A e.Middle s.A = <Palindrome e.Middle>; e.Ignored = F; } ");
205}
206
207void testAllEvals()
208{
209 testEval("First {s.A e.Rest = s.A;}", "<First hello>", "h");
swissChilic71acc62021-12-07 08:03:37 -0800210}
211
212int main(int argc, char *argv[])
213{
swissChili7babd922021-12-02 22:46:48 -0800214 QCoreApplication a(argc, argv);
swissChili3e98c062021-12-04 22:07:38 -0800215
swissChilic71acc62021-12-07 08:03:37 -0800216 testAllMatches();
217 qDebug() << "";
218 testAllParses();
swissChili8a581c62021-12-07 13:29:21 -0800219 qDebug() << "";
220 testAllFunctionDefs();
swissChili07d325f2021-12-08 20:02:05 -0800221 qDebug() << "";
222 testAllEvals();
swissChili3e98c062021-12-04 22:07:38 -0800223
swissChilic71acc62021-12-07 08:03:37 -0800224 qDebug() << "";
swissChili3e98c062021-12-04 22:07:38 -0800225 return testResults();
swissChili7babd922021-12-02 22:46:48 -0800226}