spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[ParsingTest] work-in-progress, filling out parser tests for upcoming parser changes
author
Ben Vogt <[email protected]>
date
2017-12-04 03:28:08
stats
3 file(s) changed, 196 insertions(+), 119 deletions(-)
files
tests.sh
tests/ParsingTest.ts
tests/SheetParsingTest.ts
  1diff --git a/tests.sh b/tests.sh
  2index b0017f7..d8b7e40 100755
  3--- a/tests.sh
  4+++ b/tests.sh
  5@@ -4,11 +4,5 @@ echo "$(date) Compiling Tests"
  6 tsc --outDir test_output tests/*.ts
  7 tsc --outDir test_output tests/*/*.ts
  8 
  9-echo "$(date) Running All Tests"
 10-for test_file in test_output/tests/*.js test_output/tests/*/*.js
 11-do
 12-  echo "$(date) Running ${test_file}"
 13-  node ${test_file}
 14-done
 15-node test_output/tests/SheetParsingTest.js
 16+node test_output/tests/ParsingTest.js
 17 echo "$(date) Tests Done"
 18\ No newline at end of file
 19diff --git a/tests/ParsingTest.ts b/tests/ParsingTest.ts
 20new file mode 100644
 21index 0000000..f5c680b
 22--- /dev/null
 23+++ b/tests/ParsingTest.ts
 24@@ -0,0 +1,195 @@
 25+import {
 26+  assertFormulaEquals, assertFormulaEqualsArray, assertFormulaEqualsDependsOnReference,
 27+  assertFormulaEqualsError,
 28+  test
 29+} from "./Utils/Asserts";
 30+import {
 31+  DIV_ZERO_ERROR,
 32+  VALUE_ERROR,
 33+  PARSE_ERROR, NA_ERROR, NUM_ERROR, NULL_ERROR, REF_ERROR
 34+} from "../src/Errors";
 35+import {Cell} from "../src/Cell";
 36+
 37+test("Parse but throw parse error", function(){
 38+  assertFormulaEqualsError('= 10e', PARSE_ERROR);
 39+  assertFormulaEqualsError('= SUM(', PARSE_ERROR);
 40+});
 41+
 42+test("Parse & operator", function(){
 43+  assertFormulaEquals('="hey"&" "&"there"', "hey there");
 44+  assertFormulaEquals('=TEXT(12.3, "###.##")&"mm"', "12.3mm");
 45+});
 46+
 47+test("Parse * operator", function(){
 48+  assertFormulaEquals('= 10 * 10', 100);
 49+  assertFormulaEquals('= 10 * 0', 0);
 50+  assertFormulaEquals('= 1 * 1', 1);
 51+});
 52+
 53+test("Parse / operator", function(){
 54+  assertFormulaEquals('= 10 / 2', 5);
 55+  assertFormulaEquals('= 10 / 1', 10);
 56+  assertFormulaEquals('= 1 / 1', 1);
 57+  assertFormulaEquals('= 0 / 1', 0);
 58+  assertFormulaEquals('="1" / 1', 1);
 59+  assertFormulaEquals('="500" / 1', 500);
 60+  assertFormulaEqualsError('= 10 / 0', DIV_ZERO_ERROR);
 61+  assertFormulaEqualsError('= 0 / 0', DIV_ZERO_ERROR);
 62+  assertFormulaEquals('= P9 / 1', 0);
 63+});
 64+
 65+test("Parse ^ operator", function(){
 66+  assertFormulaEquals('= 10 ^ 10', 10000000000);
 67+  assertFormulaEquals('= 10 ^ 0', 1);
 68+  assertFormulaEquals('= 1 ^ 1', 1);
 69+  assertFormulaEquals('= 2 ^ 10', 1024);
 70+});
 71+
 72+test("Parse equality operators", function(){
 73+  assertFormulaEquals('= 1 = 1', true);
 74+  assertFormulaEquals('= 1 = 0', false);
 75+  assertFormulaEquals('= 1 < 2', true);
 76+  assertFormulaEquals('= 1 < 0', false);
 77+  assertFormulaEquals('= 1 <= 1', true);
 78+  // assertFormulaEquals('= 1 <= 2', true); // TODO: Fails.
 79+  assertFormulaEquals('= 1 >= 1', true);
 80+  assertFormulaEquals('= 2 >= 1', true);
 81+  assertFormulaEquals('= 1 >= 0', true);
 82+  assertFormulaEquals('= 1 >= 2', false);
 83+  assertFormulaEquals('= 1 <> 1', false);
 84+  assertFormulaEquals('= 1 <> 2', true);
 85+});
 86+
 87+test("Parse operators, order of operations", function(){
 88+  assertFormulaEquals('= 10 + -10', 0);
 89+  assertFormulaEquals('= 10 + -10 = 0', true);
 90+  assertFormulaEquals('= 10 + -10 = 0 & "str"', false);
 91+  assertFormulaEquals('= -10%', -0.1);
 92+  assertFormulaEquals('= 10 + 10%', 10.1);
 93+  assertFormulaEquals('= -10 + 10%', -9.9);
 94+  assertFormulaEquals('= -10 - +10%', -10.1);
 95+  assertFormulaEquals('= 2^-10 + 10%', 0.1009765625);
 96+  assertFormulaEquals('= 4 * 5 / 2', 10);
 97+  assertFormulaEquals('= 4 / 5 * 4', 3.2);
 98+  assertFormulaEquals('= 2^2*5', 20);
 99+  assertFormulaEquals('= 2^(2*5)', 1024);
100+});
101+
102+test("Parse and throw error literal", function () {
103+  assertFormulaEqualsError('=#N/A', NA_ERROR);
104+  assertFormulaEqualsError('=#NUM!', NUM_ERROR);
105+  assertFormulaEqualsError('=#REF!', REF_ERROR);
106+  assertFormulaEqualsError('=#NULL!', NULL_ERROR);
107+  assertFormulaEqualsError('=#ERROR', PARSE_ERROR);
108+  assertFormulaEqualsError('=#DIV/0!', DIV_ZERO_ERROR);
109+  assertFormulaEqualsError('=#VALUE!', VALUE_ERROR);
110+  assertFormulaEquals('=ISERROR(#N/A)', true);
111+  assertFormulaEquals('=ISERROR(#NUM!)', true);
112+  assertFormulaEquals('=ISERROR(#REF!)', true);
113+  assertFormulaEquals('=ISERROR(#NULL!)', true);
114+  assertFormulaEquals('=ISERROR(#ERROR)', true);
115+  assertFormulaEquals('=ISERROR(#DIV/0!)', true);
116+  assertFormulaEquals('=ISERROR(#VALUE!)', true);
117+  assertFormulaEquals('=IFERROR(#N/A, 10)', 10);
118+  assertFormulaEquals('=IFERROR(#NUM!, 10)', 10);
119+  assertFormulaEquals('=IFERROR(#REF!, 10)', 10);
120+  assertFormulaEquals('=IFERROR(#NULL!, 10)', 10);
121+  assertFormulaEquals('=IFERROR(#ERROR, 10)', 10);
122+  assertFormulaEquals('=IFERROR(#DIV/0!, 10)', 10);
123+  assertFormulaEquals('=IFERROR(#VALUE!, 10)', 10);
124+});
125+
126+test("Parse plain numbers", function() {
127+  assertFormulaEquals('=10', 10);
128+  // assertFormulaEquals('=.1', 0.1); // TODO: Fails from parse error, but should pass
129+  assertFormulaEquals('=0.1', 0.1);
130+  assertFormulaEquals('=+1', 1);
131+  assertFormulaEquals('=-1', -1);
132+  assertFormulaEquals('=++1', 1);
133+  assertFormulaEquals('=--1', 1);
134+  assertFormulaEquals('=10e1', 100);
135+  assertFormulaEquals('=0e1', 0);
136+  // assertFormulaEquals('=0.e1', 0); // TODO: Fails from parse error, but should pass
137+  assertFormulaEquals('=-10e1', -100);
138+  assertFormulaEquals('=+10e1', 100);
139+  assertFormulaEquals('=++10e1', 100);
140+  assertFormulaEquals('=--10e1', 100);
141+});
142+
143+test("Parse complex numbers and math", function(){
144+  assertFormulaEquals('= "10" + 10', 20);
145+  assertFormulaEquals('= "10.111111" + 0', 10.111111);
146+  assertFormulaEquals('= 10%', 0.1);
147+  assertFormulaEquals('= 10% + 1', 1.1);
148+  assertFormulaEquals('= "10e1" + 0', 100);
149+  assertFormulaEquals('= 10e1', 100);
150+  assertFormulaEquals('= 10e-1', 1);
151+  assertFormulaEquals('= 10e+1', 100);
152+  assertFormulaEquals('= 10E1', 100);
153+  assertFormulaEquals('= 10E-1', 1);
154+  assertFormulaEquals('= 10E+1', 100);
155+  assertFormulaEquals('= "1,000,000"  + 0', 1000000);
156+  assertFormulaEqualsError('= "10e" + 10', VALUE_ERROR);
157+  assertFormulaEquals('= "+$10.00" + 0', 10);
158+  assertFormulaEquals('= "-$10.00" + 0', -10);
159+  assertFormulaEquals('= "$+10.00" + 0', 10);
160+  assertFormulaEquals('= "$-10.00" + 0', -10);
161+  assertFormulaEquals('= "10" + 10', 20);
162+  assertFormulaEquals('= "10.111111" + 0', 10.111111);
163+  assertFormulaEquals('= 10%', 0.1);
164+  assertFormulaEquals('= 10% + 1', 1.1);
165+  assertFormulaEquals('= "10e1" + 0', 100);
166+  assertFormulaEquals('= 10e1', 100);
167+  assertFormulaEquals('= 10e-1', 1);
168+  assertFormulaEquals('= 10e+1', 100);
169+  assertFormulaEquals('= 10E1', 100);
170+  assertFormulaEquals('= 10E-1', 1);
171+  assertFormulaEquals('= 10E+1', 100);
172+  assertFormulaEquals('= "1,000,000"  + 0', 1000000);
173+  assertFormulaEqualsError('= "10e" + 10', VALUE_ERROR);
174+  assertFormulaEquals('= "+$10.00" + 0', 10);
175+  assertFormulaEquals('= "-$10.00" + 0', -10);
176+  assertFormulaEquals('= "$+10.00" + 0', 10);
177+  assertFormulaEquals('= "$-10.00" + 0', -10);
178+});
179+
180+test("Parse strings", function(){
181+  assertFormulaEquals('="str"', "str");
182+  assertFormulaEquals('="str"&"str"', "strstr");
183+  assertFormulaEqualsError('="str"+"str"', VALUE_ERROR);
184+  // assertFormulaEqualsError("='str'", PARSE_ERROR); // TODO: Parses, but it shouldn't.
185+});
186+
187+test("Parse boolean literals", function(){
188+  assertFormulaEquals('=TRUE', true);
189+  assertFormulaEquals('=true', true);
190+  assertFormulaEquals('=FALSE', false);
191+  assertFormulaEquals('=false', false);
192+});
193+
194+test("Parse boolean logic", function(){
195+  // assertFormulaEquals('=(1=1)', true); // TODO: Fails because we compute the value, rather than checking equality
196+  // assertFormulaEquals('=(1=2)', false); // TODO: Fails because we compute the value, rather than checking equality
197+  assertFormulaEquals('=(1=1)+2', 3);
198+
199+});
200+
201+
202+test("Parse range literal", function(){
203+  // assertFormulaEqualsArray('=[1, 2, 3]', [1, 2, 3]); // TODO: Fails because of low-level parser error
204+  // assertFormulaEqualsArray('=[]', []); // TODO: Fails because of low-level parser error
205+  // assertFormulaEqualsArray('=["str", "str"]', ["str", "str"]); // TODO: Fails because of low-level parser error
206+  // assertFormulaEqualsArray('=["str", [1, 2, 3], [1]]', ["str", [1, 2, 3], [1]]); // TODO: Fails because of low-level parser error
207+});
208+
209+test("Parse cell references", function(){
210+  assertFormulaEqualsDependsOnReference("E1", "str", '=E1', Cell.BuildFrom("E1", "str"));
211+  // assertFormulaEqualsArray('=E1:E2', [new Cell("E1"), new Cell("E2")]); // TODO: Fails because the returned result is nested. Shouldn't be.
212+});
213+
214+test("Parse range following comma", function(){
215+  // assertFormulaEquals('=SERIESSUM(1, 0, 1, [4, 5, 6])', 15);
216+  // assertFormulaEquals('=SERIESSUM([1], [0], [1], [4, 5, 6])', 15);
217+});
218+
219+
220diff --git a/tests/SheetParsingTest.ts b/tests/SheetParsingTest.ts
221deleted file mode 100644
222index 41e9e76..0000000
223--- a/tests/SheetParsingTest.ts
224+++ /dev/null
225@@ -1,113 +0,0 @@
226-import {
227-  assertFormulaEquals,
228-  assertFormulaEqualsError,
229-  test
230-} from "./Utils/Asserts";
231-import {
232-  DIV_ZERO_ERROR,
233-  VALUE_ERROR,
234-  PARSE_ERROR, NA_ERROR, NUM_ERROR, NULL_ERROR, REF_ERROR
235-} from "../src/Errors";
236-
237-test("Sheet parsing error", function(){
238-  assertFormulaEqualsError('= 10e', PARSE_ERROR);
239-  assertFormulaEqualsError('= SUM(', PARSE_ERROR);
240-});
241-
242-test("Sheet &", function(){
243-  assertFormulaEquals('="hey"&" "&"there"', "hey there");
244-  assertFormulaEquals('=TEXT(12.3, "###.##")&"mm"', "12.3mm");
245-});
246-
247-test("Sheet *", function(){
248-  assertFormulaEquals('= 10 * 10', 100);
249-  assertFormulaEquals('= 10 * 0', 0);
250-  assertFormulaEquals('= 1 * 1', 1);
251-});
252-
253-test("Sheet /", function(){
254-  assertFormulaEquals('= 10 / 2', 5);
255-  assertFormulaEquals('= 10 / 1', 10);
256-  assertFormulaEquals('= 1 / 1', 1);
257-  assertFormulaEquals('= 0 / 1', 0);
258-  assertFormulaEquals('="1" / 1', 1);
259-  assertFormulaEquals('="500" / 1', 500);
260-  assertFormulaEqualsError('= 10 / 0', DIV_ZERO_ERROR);
261-  assertFormulaEqualsError('= 0 / 0', DIV_ZERO_ERROR);
262-  assertFormulaEquals('= P9 / 1', 0);
263-});
264-
265-test("Sheet ^", function(){
266-  assertFormulaEquals('= 10 ^ 10', 10000000000);
267-  assertFormulaEquals('= 10 ^ 0', 1);
268-  assertFormulaEquals('= 1 ^ 1', 1);
269-  assertFormulaEquals('= 2 ^ 10', 1024);
270-});
271-
272-test("Sheet throw error literal", function () {
273-  assertFormulaEqualsError('=#N/A', NA_ERROR);
274-  assertFormulaEqualsError('=#NUM!', NUM_ERROR);
275-  assertFormulaEqualsError('=#REF!', REF_ERROR);
276-  assertFormulaEqualsError('=#NULL!', NULL_ERROR);
277-  assertFormulaEqualsError('=#ERROR', PARSE_ERROR);
278-  assertFormulaEqualsError('=#DIV/0!', DIV_ZERO_ERROR);
279-  assertFormulaEqualsError('=#VALUE!', VALUE_ERROR);
280-  assertFormulaEquals('=ISERROR(#N/A)', true);
281-  assertFormulaEquals('=ISERROR(#NUM!)', true);
282-  assertFormulaEquals('=ISERROR(#REF!)', true);
283-  assertFormulaEquals('=ISERROR(#NULL!)', true);
284-  assertFormulaEquals('=ISERROR(#ERROR)', true);
285-  assertFormulaEquals('=ISERROR(#DIV/0!)', true);
286-  assertFormulaEquals('=ISERROR(#VALUE!)', true);
287-  assertFormulaEquals('=IFERROR(#N/A, 10)', 10);
288-  assertFormulaEquals('=IFERROR(#NUM!, 10)', 10);
289-  assertFormulaEquals('=IFERROR(#REF!, 10)', 10);
290-  assertFormulaEquals('=IFERROR(#NULL!, 10)', 10);
291-  assertFormulaEquals('=IFERROR(#ERROR, 10)', 10);
292-  assertFormulaEquals('=IFERROR(#DIV/0!, 10)', 10);
293-  assertFormulaEquals('=IFERROR(#VALUE!, 10)', 10);
294-});
295-
296-test("Sheet numbers/math", function(){
297-  assertFormulaEquals('= "10" + 10', 20);
298-  assertFormulaEquals('= "10.111111" + 0', 10.111111);
299-  assertFormulaEquals('= 10%', 0.1);
300-  assertFormulaEquals('= 10% + 1', 1.1);
301-  assertFormulaEquals('= "10e1" + 0', 100);
302-  assertFormulaEquals('= 10e1', 100);
303-  assertFormulaEquals('= 10e-1', 1);
304-  assertFormulaEquals('= 10e+1', 100);
305-  assertFormulaEquals('= 10E1', 100);
306-  assertFormulaEquals('= 10E-1', 1);
307-  assertFormulaEquals('= 10E+1', 100);
308-  assertFormulaEquals('= "1,000,000"  + 0', 1000000);
309-  assertFormulaEqualsError('= "10e" + 10', VALUE_ERROR);
310-  assertFormulaEquals('= "+$10.00" + 0', 10);
311-  assertFormulaEquals('= "-$10.00" + 0', -10);
312-  assertFormulaEquals('= "$+10.00" + 0', 10);
313-  assertFormulaEquals('= "$-10.00" + 0', -10);
314-  assertFormulaEquals('= "10" + 10', 20);
315-  assertFormulaEquals('= "10.111111" + 0', 10.111111);
316-  assertFormulaEquals('= 10%', 0.1);
317-  assertFormulaEquals('= 10% + 1', 1.1);
318-  assertFormulaEquals('= "10e1" + 0', 100);
319-  assertFormulaEquals('= 10e1', 100);
320-  assertFormulaEquals('= 10e-1', 1);
321-  assertFormulaEquals('= 10e+1', 100);
322-  assertFormulaEquals('= 10E1', 100);
323-  assertFormulaEquals('= 10E-1', 1);
324-  assertFormulaEquals('= 10E+1', 100);
325-  assertFormulaEquals('= "1,000,000"  + 0', 1000000);
326-  assertFormulaEqualsError('= "10e" + 10', VALUE_ERROR);
327-  assertFormulaEquals('= "+$10.00" + 0', 10);
328-  assertFormulaEquals('= "-$10.00" + 0', -10);
329-  assertFormulaEquals('= "$+10.00" + 0', 10);
330-  assertFormulaEquals('= "$-10.00" + 0', -10);
331-});
332-
333-test("Sheet parse range following comma", function(){
334-  // assertFormulaEquals('=SERIESSUM(1, 0, 1, [4, 5, 6])', 15);
335-  // assertFormulaEquals('=SERIESSUM([1], [0], [1], [4, 5, 6])', 15);
336-});
337-
338-