commit
message
[ParseEngineTest] directly testing parser
author
Ben Vogt <[email protected]>
date
2017-12-10 03:21:40
stats
2 file(s) changed,
199 insertions(+),
3 deletions(-)
files
src/Parser/ParserConstants.ts
tests/Parser/ParseEngineTest.ts
1diff --git a/src/Parser/ParserConstants.ts b/src/Parser/ParserConstants.ts
2index 40f512f..f049bf5 100644
3--- a/src/Parser/ParserConstants.ts
4+++ b/src/Parser/ParserConstants.ts
5@@ -334,6 +334,10 @@ symbolIndexToName[Symbol.EXCLAMATION_POINT] = "!";
6 const SYMBOL_INDEX_TO_NAME = symbolIndexToName;
7
8
9+const enum State {
10+ START = 0
11+}
12+
13
14 /**
15 * Array of to map rules to to LexActions and other rules. A single index in the object (e.g. `{2: 13}`) indicates the
16@@ -342,7 +346,7 @@ const SYMBOL_INDEX_TO_NAME = symbolIndexToName;
17 */
18 let table = [];
19 // All functions in the spreadsheet start with a 0-token.
20-table[0] = ObjectBuilder
21+table[State.START] = ObjectBuilder
22 .add(Symbol.ERROR, 13)
23 .add(Symbol.EXPRESSIONS, 1)
24 .add(Symbol.EXPRESSION, 2)
25diff --git a/tests/Parser/ParseEngineTest.ts b/tests/Parser/ParseEngineTest.ts
26index c837841..cc8cc92 100644
27--- a/tests/Parser/ParseEngineTest.ts
28+++ b/tests/Parser/ParseEngineTest.ts
29@@ -2,9 +2,12 @@ import {
30 Parser
31 } from "../../src/Parser/Parser";
32 import {TypeConverter} from "../../src/Utilities/TypeConverter";
33-import {DivZeroError, NameError} from "../../src/Errors";
34+import {
35+ DIV_ZERO_ERROR, DivZeroError, NA_ERROR, NameError, NULL_ERROR, NUM_ERROR, PARSE_ERROR,
36+ REF_ERROR, VALUE_ERROR
37+} from "../../src/Errors";
38 import {Formulas} from "../../src/Formulas";
39-import {assertEquals, test} from "../Utils/Asserts";
40+import {assertEquals, catchAndAssertEquals, test} from "../Utils/Asserts";
41
42
43 let FormulaParser = function(handler) {
44@@ -319,8 +322,195 @@ test("Declare number", function () {
45 assertEquals(parser.parse('5'), 5);
46 });
47
48-console.log("\n\n\n\n\n\n\n");
49-
50 test("Number multiplication", function () {
51 assertEquals(parser.parse('5*5'), 25);
52-});
53\ No newline at end of file
54+});
55+
56+
57+
58+test("Parse but throw parse error", function(){
59+ // assertEquals(parser.parse('=10e'), PARSE_ERROR);
60+ // assertEquals(parser.parse('= SUM('), PARSE_ERROR);
61+});
62+
63+test("Parse & operator", function(){
64+ assertEquals(parser.parse('"hey"&" "&"there"'), "hey there");
65+});
66+
67+test("Parse * operator", function(){
68+ assertEquals(parser.parse('10 * 10'), 100);
69+ assertEquals(parser.parse('10 * 0'), 0);
70+ assertEquals(parser.parse('1 * 1'), 1);
71+});
72+
73+test("Parse / operator", function(){
74+ assertEquals(parser.parse('10 / 2'), 5);
75+ assertEquals(parser.parse('10 / 1'), 10);
76+ assertEquals(parser.parse('1 / 1'), 1);
77+ assertEquals(parser.parse('0 / 1'), 0);
78+ assertEquals(parser.parse('"1" / 1'), 1);
79+ assertEquals(parser.parse('"500" / 1'), 500);
80+ catchAndAssertEquals(function () {
81+ parser.parse(' 10 / 0');
82+ }, DIV_ZERO_ERROR);
83+ catchAndAssertEquals(function () {
84+ parser.parse('0 / 0')
85+ }, DIV_ZERO_ERROR);
86+ // assertEquals(parser.parse('P9 / 1'), 0);
87+});
88+
89+test("Parse ^ operator", function(){
90+ assertEquals(parser.parse('10 ^ 10'), 10000000000);
91+ assertEquals(parser.parse('10 ^ 0'), 1);
92+ assertEquals(parser.parse('1 ^ 1'), 1);
93+ assertEquals(parser.parse('2 ^ 10'), 1024);
94+});
95+
96+test("Parse equality operators", function(){
97+ assertEquals(parser.parse('1 = 1'), true);
98+ assertEquals(parser.parse('1 = 0'), false);
99+ assertEquals(parser.parse('1 < 2'), true);
100+ assertEquals(parser.parse('1 < 0'), false);
101+ assertEquals(parser.parse('1 <= 1'), true);
102+ // assertEquals('= 1 <= 2', true); // TODO: Fails.
103+ assertEquals(parser.parse('1 >= 1'), true);
104+ assertEquals(parser.parse('2 >= 1'), true);
105+ assertEquals(parser.parse('1 >= 0'), true);
106+ assertEquals(parser.parse('1 >= 2'), false);
107+ assertEquals(parser.parse('1 <> 1'), false);
108+ assertEquals(parser.parse('1 <> 2'), true);
109+});
110+
111+test("Parse operators, order of operations", function(){
112+ assertEquals(parser.parse('10 + -10'), 0);
113+ assertEquals(parser.parse('10 + -10 = 0'), true);
114+ // assertEquals(parser.parse('10 + -10 = 0 & "str"'), false); // TODO should pass.
115+ assertEquals(parser.parse('-10%'), -0.1);
116+ assertEquals(parser.parse('10 + 10%'), 10.1);
117+ assertEquals(parser.parse('-10 + 10%'), -9.9);
118+ assertEquals(parser.parse('-10 - +10%'), -10.1);
119+ assertEquals(parser.parse('2^-10 + 10%'), 0.1009765625);
120+ assertEquals(parser.parse('4 * 5 / 2'), 10);
121+ assertEquals(parser.parse('4 / 5 * 4'), 3.2);
122+ assertEquals(parser.parse('2^2*5'), 20);
123+ assertEquals(parser.parse('2^(2*5)'), 1024);
124+});
125+
126+test("Parse and throw error literal", function () {
127+ // these pass, but strangely so.
128+ // assertEquals(parser.parse('#N/A'), NA_ERROR);
129+ // assertEquals(parser.parse('#NUM!'), NUM_ERROR);
130+ // assertEquals(parser.parse('#REF!'), REF_ERROR);
131+ // assertEquals(parser.parse('#NULL!'), NULL_ERROR);
132+ // assertEquals(parser.parse('#ERROR'), PARSE_ERROR);
133+ // assertEquals(parser.parse('#DIV/0!'), DIV_ZERO_ERROR);
134+ // assertEquals(parser.parse('#VALUE!'), VALUE_ERROR);
135+ // assertEquals(parser.parse('ISERROR(#N/A)'), true);
136+ // assertEquals(parser.parse('=ISERROR(#NUM!)'), true);
137+ // assertEquals(parser.parse('=ISERROR(#REF!)'), true);
138+ // assertEquals(parser.parse('=ISERROR(#NULL!)'), true);
139+ // assertEquals(parser.parse('=ISERROR(#ERROR)'), true);
140+ // assertEquals(parser.parse('=ISERROR(#DIV/0!)'), true);
141+ // assertEquals(parser.parse('=ISERROR(#VALUE!)'), true);
142+ // assertEquals(parser.parse('=IFERROR(#N/A, 10)'), 10);
143+ // assertEquals(parser.parse('=IFERROR(#NUM!, 10)'), 10);
144+ // assertEquals(parser.parse('=IFERROR(#REF!, 10)'), 10);
145+ // assertEquals(parser.parse('=IFERROR(#NULL!, 10)'), 10);
146+ // assertEquals(parser.parse('=IFERROR(#ERROR, 10)'), 10);
147+ // assertEquals(parser.parse('=IFERROR(#DIV/0!, 10)'), 10);
148+ // assertEquals(parser.parse('=IFERROR(#VALUE!, 10)'), 10);
149+});
150+
151+test("Parse plain numbers", function() {
152+ assertEquals(parser.parse('10'), 10);
153+ // assertEquals('=.1', 0.1); // TODO: Fails from parse error, but should pass
154+ // assertEquals(parser.parse('0.1'), 0.1); // TODO: Can't coerce to number?
155+ assertEquals(parser.parse('+1'), 1);
156+ assertEquals(parser.parse('-1'), -1);
157+ assertEquals(parser.parse('++1'), 1);
158+ assertEquals(parser.parse('--1'), 1);
159+ assertEquals(parser.parse('10e1'), 100);
160+ assertEquals(parser.parse('0e1'), 0);
161+ // assertEquals('=0.e1', 0); // TODO: Fails from parse error, but should pass
162+ assertEquals(parser.parse('-10e1'), -100);
163+ assertEquals(parser.parse('+10e1'), 100);
164+ assertEquals(parser.parse('++10e1'), 100);
165+ assertEquals(parser.parse('--10e1'), 100);
166+});
167+
168+test("Parse complex numbers and math", function(){
169+ assertEquals(parser.parse('"10" + 10'), 20);
170+ assertEquals(parser.parse('"10.111111" + 0'), 10.111111);
171+ assertEquals(parser.parse('10%'), 0.1);
172+ assertEquals(parser.parse('10% + 1'), 1.1);
173+ assertEquals(parser.parse('"10e1" + 0'), 100);
174+ assertEquals(parser.parse('10e1'), 100);
175+ assertEquals(parser.parse('10e-1'), 1);
176+ assertEquals(parser.parse('10e+1'), 100);
177+ assertEquals(parser.parse('10E1'), 100);
178+ assertEquals(parser.parse('10E-1'), 1);
179+ assertEquals(parser.parse('10E+1'), 100);
180+ assertEquals(parser.parse('"1,000,000" + 0'), 1000000);
181+ assertEquals(parser.parse('"+$10.00" + 0'), 10);
182+ assertEquals(parser.parse('"-$10.00" + 0'), -10);
183+ assertEquals(parser.parse('"$+10.00" + 0'), 10);
184+ assertEquals(parser.parse('"$-10.00" + 0'), -10);
185+ assertEquals(parser.parse('"10" + 10'), 20);
186+ assertEquals(parser.parse('"10.111111" + 0'), 10.111111);
187+ assertEquals(parser.parse('10%'), 0.1);
188+ assertEquals(parser.parse('10% + 1'), 1.1);
189+ assertEquals(parser.parse('"10e1" + 0'), 100);
190+ assertEquals(parser.parse('10e1'), 100);
191+ assertEquals(parser.parse('10e-1'), 1);
192+ assertEquals(parser.parse('10e+1'), 100);
193+ assertEquals(parser.parse('10E1'), 100);
194+ assertEquals(parser.parse('10E-1'), 1);
195+ assertEquals(parser.parse('10E+1'), 100);
196+ assertEquals(parser.parse('"1,000,000" + 0'), 1000000);
197+ catchAndAssertEquals(function () {
198+ parser.parse('"10e" + 10');
199+ }, VALUE_ERROR);
200+ assertEquals(parser.parse('"+$10.00" + 0'), 10);
201+ assertEquals(parser.parse('"-$10.00" + 0'), -10);
202+ assertEquals(parser.parse('"$+10.00" + 0'), 10);
203+ assertEquals(parser.parse('"$-10.00" + 0'), -10);
204+});
205+
206+test("Parse strings", function(){
207+ assertEquals(parser.parse('"str"'), "str");
208+ assertEquals(parser.parse('"str"&"str"'), "strstr");
209+ catchAndAssertEquals(function () {
210+ parser.parse('"str"+"str"');
211+ }, VALUE_ERROR);
212+ // assertEquals("='str'", PARSE_ERROR); // TODO: Parses, but it shouldn't.
213+});
214+
215+test("Parse boolean literals", function(){
216+ assertEquals(parser.parse('TRUE'), true);
217+ assertEquals(parser.parse('true'), true);
218+ assertEquals(parser.parse('FALSE'), false);
219+ assertEquals(parser.parse('false'), false);
220+});
221+
222+test("Parse boolean logic", function(){
223+ // assertEquals('=(1=1)', true); // TODO: Fails because we compute the value, rather than checking equality
224+ // assertEquals('=(1=2)', false); // TODO: Fails because we compute the value, rather than checking equality
225+ assertEquals(parser.parse('(1=1)+2'), 3);
226+
227+});
228+
229+
230+test("Parse range literal", function(){
231+ // assertEqualsArray('=[1, 2, 3]', [1, 2, 3]); // TODO: Fails because of low-level parser error
232+ // assertEqualsArray('=[]', []); // TODO: Fails because of low-level parser error
233+ // assertEqualsArray('=["str", "str"]', ["str", "str"]); // TODO: Fails because of low-level parser error
234+ // assertEqualsArray('=["str", [1, 2, 3], [1]]', ["str", [1, 2, 3], [1]]); // TODO: Fails because of low-level parser error
235+});
236+
237+
238+test("Parse range following comma", function(){
239+ // assertEquals('=SERIESSUM(1, 0, 1, [4, 5, 6])', 15);
240+ // assertEquals('=SERIESSUM([1], [0], [1], [4, 5, 6])', 15);
241+});
242+
243+