commit
message
[Cell,Sheet,etc] work-in-progress on having all functions handle Cell objects
author
Ben Vogt <[email protected]>
date
2017-07-09 15:24:40
stats
6 file(s) changed,
97 insertions(+),
22 deletions(-)
files
src/Cell.ts
src/Sheet.ts
src/Utilities/TypeConverter.ts
tests/CellTest.ts
tests/SheetTest.ts
tests/Utils/Asserts.ts
1diff --git a/src/Cell.ts b/src/Cell.ts
2index cecd7e7..a5358a9 100644
3--- a/src/Cell.ts
4+++ b/src/Cell.ts
5@@ -141,6 +141,22 @@ class Cell {
6 return this.error;
7 }
8
9+ /**
10+ * Easier way to check if this cell has an error.
11+ * @returns {boolean}
12+ */
13+ hasError() : boolean {
14+ return this.error !== null;
15+ }
16+
17+ /**
18+ * A cell is deemed blank if it contains no value, no error, and no typed value.
19+ * @returns {boolean}
20+ */
21+ isBlank(): boolean {
22+ return this.error === null && this.rawFormulaText === null && this.typedValue === null;
23+ }
24+
25 /**
26 * Returns the human-readable string representation of this cell, omitting some obvious fields.
27 * @returns {string}
28diff --git a/src/Sheet.ts b/src/Sheet.ts
29index a299bd7..73768a3 100644
30--- a/src/Sheet.ts
31+++ b/src/Sheet.ts
32@@ -77,12 +77,15 @@ var Sheet = (function () {
33 public data: Object = {};
34
35 /**
36- * Gets the cell corresponding to the key. If the value is not defined, will return undefined.
37+ * Gets the cell corresponding to the key. If the value is undefined, will return blank cell..
38 * @param key to look up cell
39- * @returns {Cell} to return, if it exists. Returns undefined if key not in matrix.
40+ * @returns {Cell} to return, if it exists. Returns blank cell if key not in matrix.
41 */
42 getCell(key: string) : Cell {
43- return this.data[key];
44+ if (key in this.data) {
45+ return this.data[key];
46+ }
47+ return new Cell(key);
48 }
49
50 /**
51@@ -463,7 +466,7 @@ var Sheet = (function () {
52 cell = instance.matrix.getCell(cellId);
53
54 // get value, defaulting to undefined
55- value = cell ? cell.getValue() : undefined;
56+ value = cell.isBlank() ? undefined : cell.getValue();
57 //update dependencies
58 instance.matrix.getCell(origin).updateDependencies([cellId]);
59 // check references error
60@@ -474,19 +477,19 @@ var Sheet = (function () {
61 }
62
63 // check if any error occurs
64- if (cell && cell.getError()) {
65+ if (!cell.isBlank() && cell.getError()) {
66 throw cell.getError()
67 }
68
69+ if (cell.isBlank()) {
70+ return cell;
71+ }
72+
73 // return value if is set
74 if (utils.isSet(value)) {
75 var result = instance.helper.number(value);
76-
77 return !isNaN(result) ? result : value;
78 }
79-
80- // cell is not available
81- return undefined;
82 },
83
84 cellRangeValue: function (start: string, end: string) {
85diff --git a/src/Utilities/TypeConverter.ts b/src/Utilities/TypeConverter.ts
86index c0f0c69..ea479ef 100644
87--- a/src/Utilities/TypeConverter.ts
88+++ b/src/Utilities/TypeConverter.ts
89@@ -7,6 +7,7 @@ import {
90 import {
91 DateRegExBuilder
92 } from "./DateRegExBuilder";
93+import {Cell} from "../Cell";
94
95 const YEAR_MONTHDIG_DAY = DateRegExBuilder.DateRegExBuilder()
96 .start()
97@@ -426,7 +427,16 @@ class TypeConverter {
98 * @returns {number} to return. Will always return a number or throw an error. Never returns undefined.
99 */
100 public static valueToNumber(value : any) {
101- if (typeof value === "number") {
102+ if (value instanceof Cell) {
103+ if (value.isBlank()) {
104+ return 0;
105+ } else {
106+ if (value.hasError()) {
107+ throw value.getError();
108+ }
109+ return value.getValue();
110+ }
111+ } else if (typeof value === "number") {
112 return value;
113 } else if (typeof value === "string") {
114 if (value === "") {
115diff --git a/tests/CellTest.ts b/tests/CellTest.ts
116index 911b1a8..5f0a2a5 100644
117--- a/tests/CellTest.ts
118+++ b/tests/CellTest.ts
119@@ -4,7 +4,7 @@ import {
120 import {
121 assertEquals,
122 assertArrayEquals,
123- test
124+ test, assertIsNull
125 } from "./Utils/Asserts";
126
127 test("Cell.constructor", function(){
128@@ -13,7 +13,7 @@ test("Cell.constructor", function(){
129 assertEquals(cell.getRow(), 0);
130 assertArrayEquals(cell.getDependencies(), []);
131 assertEquals(cell.getId(), "A1");
132- assertEquals(cell.getFormula(), null);
133+ assertIsNull(cell.getFormula());
134 assertEquals(cell.hasFormula(), false);
135 });
136
137@@ -30,3 +30,10 @@ test("Cell.setValue", function(){
138 v.setValue("100");
139 assertEquals("100", v.getValue());
140 });
141+
142+test("Cell.isBlank", function(){
143+ var v = new Cell("A1");
144+ assertIsNull(v.getValue());
145+ assertIsNull(v.getError());
146+ assertEquals(v.isBlank(), true);
147+});
148diff --git a/tests/SheetTest.ts b/tests/SheetTest.ts
149index fb4f419..baf08a1 100644
150--- a/tests/SheetTest.ts
151+++ b/tests/SheetTest.ts
152@@ -3,6 +3,7 @@ import {
153 } from "../src/Sheet";
154 import {
155 assertEquals,
156+ assertIsNull,
157 assertArrayEquals,
158 test
159 } from "./Utils/Asserts";
160@@ -21,12 +22,14 @@ test("Sheet.setCell, Sheet.getCell", function(){
161 assertEquals("A2", cell.getId());
162 assertEquals(1, cell.getRow());
163 assertEquals(0, cell.getColumn());
164- assertEquals(null, cell.getError());
165+ assertIsNull(cell.getError());
166 assertArrayEquals([], cell.getDependencies());
167
168- // Test getCell, null value
169- var nullCell = sheet.getCell("N1");
170- assertEquals(null, nullCell);
171+ // Test getCell, blank cell value
172+ var blankCell = sheet.getCell("N1");
173+ assertEquals(true, blankCell.isBlank());
174+ assertIsNull(blankCell.getError());
175+ assertEquals(false, blankCell.hasFormula());
176
177 // Test setCell, with formula
178 var sheet = new Sheet();
179@@ -39,7 +42,7 @@ test("Sheet.setCell, Sheet.getCell", function(){
180 var A5 = sheet.getCell("A5");
181 assertEquals(69.4, A5.getValue());
182 assertEquals(SUM_FORM.substr(1), A5.getFormula());
183- assertEquals(null, cell.getError());
184+ assertIsNull(cell.getError());
185 assertArrayEquals(['A1', 'A2', 'A3', 'A4'], A5.getDependencies());
186 });
187
188@@ -60,32 +63,32 @@ test("Sheet.load", function(){
189 var K1 = sheet.getCell("K1");
190 assertEquals(18, K1.getValue());
191 assertEquals(SUM_FORMULA.substr(1), K1.getFormula());
192- assertEquals(null, K1.getError());
193+ assertIsNull(K1.getError());
194 assertArrayEquals(['A1', 'B1', 'C1', 'D1', 'H1'], K1.getDependencies());
195 var K2 = sheet.getCell("K2");
196 assertEquals(200, K2.getValue());
197 assertEquals(MAX_FORMULA.substr(1), K2.getFormula());
198- assertEquals(null, K2.getError());
199+ assertIsNull(K2.getError());
200 assertArrayEquals(['A2', 'B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2', 'J2'], K2.getDependencies());
201 var K3 = sheet.getCell("K3");
202 assertEquals(-53, K3.getValue());
203 assertEquals(MIN_FORMULA.substr(1), K3.getFormula());
204- assertEquals(null, K3.getError());
205+ assertIsNull(K3.getError());
206 assertArrayEquals(['A3', 'B3', 'C3', 'D3', 'E3', 'F3', 'G3', 'H3', 'I3', 'J3'], K3.getDependencies());
207 var K4 = sheet.getCell("K4");
208 assertEquals(30.4, K4.getValue());
209 assertEquals(AVERAGE_FORMULA.substr(1), K4.getFormula());
210- assertEquals(null, K4.getError());
211+ assertIsNull(K4.getError());
212 assertArrayEquals(['A4', 'B4', 'C4', 'D4', 'E4', 'F4', 'G4', 'H4', 'I4', 'J4'], K4.getDependencies());
213 var K5 = sheet.getCell("K5");
214 assertEquals(0, K5.getValue());
215 assertEquals(SUM_IF_FORMULA.substr(1), K5.getFormula());
216- assertEquals(null, K5.getError());
217+ assertIsNull(K5.getError());
218 assertArrayEquals(['A5', 'B5', 'C5', 'D5', 'E5', 'F5', 'G5', 'H5', 'I5', 'J5'], K5.getDependencies());
219 var K6 = sheet.getCell("K6");
220 assertEquals(195.4, K6.getValue());
221 assertEquals(SUM_REF_FORMULA.substr(1), K6.getFormula());
222- assertEquals(null, K6.getError());
223+ assertIsNull(K6.getError());
224 assertArrayEquals(['K1', 'K2', 'K3', 'K4'], K6.getDependencies());
225 });
226
227@@ -97,11 +100,11 @@ test("Sheet REF error", function(){
228 sheet.setCell("B1", "=SUM(A3, B2)");
229 sheet.setCell("B2", "=SUM(A1, B1)");
230 var B1 = sheet.getCell("B1");
231- assertEquals(null, B1.getValue());
232+ assertIsNull(B1.getValue());
233 assertEquals(REF_ERROR, B1.getError().name);
234 assertArrayEquals(['A3', 'B2'], B1.getDependencies());
235 var B2 = sheet.getCell("B2");
236- assertEquals(null, B2.getValue());
237+ assertIsNull(B2.getValue());
238 assertEquals(REF_ERROR, B2.getError().name);
239 assertArrayEquals(['A1', 'B1'], B2.getDependencies());
240 });
241@@ -111,7 +114,7 @@ test("Sheet cell NAME error", function(){
242 sheet.setCell("A1", "1");
243 sheet.setCell("A2", "=SUM(A1, NN)");
244 var A2 = sheet.getCell("A2");
245- assertEquals(null, A2.getValue());
246+ assertIsNull(A2.getValue());
247 assertEquals(NAME_ERROR, A2.getError().name);
248 assertArrayEquals(['A1'], A2.getDependencies());
249 });
250@@ -121,7 +124,7 @@ test("Sheet unsupported formula NAME error", function(){
251 sheet.setCell("A1", "1");
252 sheet.setCell("A2", "=BEN(A1)");
253 var A2 = sheet.getCell("A2");
254- assertEquals(null, A2.getValue());
255+ assertIsNull(A2.getValue());
256 assertEquals(NAME_ERROR, A2.getError().name);
257 assertArrayEquals(['A1'], A2.getDependencies());
258 });
259@@ -136,10 +139,22 @@ test("Sheet nested formulas", function(){
260 var A4 = sheet.getCell("A4");
261 assertEquals(99.8, A4.getValue());
262 assertEquals("SUM(A1:A3, MAX(A1, A3))", A4.getFormula());
263- assertEquals(null, A4.getError());
264+ assertIsNull(A4.getError());
265 assertArrayEquals(['A1', 'A2', 'A3'], A4.getDependencies());
266 });
267
268+test("Sheet cell range query", function(){
269+ var sheet = new Sheet();
270+ sheet.setCell("A1", "1");
271+ sheet.setCell("A2", "1");
272+ sheet.setCell("A3", "1");
273+ sheet.setCell("A4", "1");
274+ sheet.setCell("A5", "1");
275+ sheet.setCell("N1", "=SUM(A1:A7)");
276+ var N1 = sheet.getCell("N1");
277+ assertArrayEquals(['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7'], N1.getDependencies());
278+});
279+
280 test("Sheet dependency calculation propagation", function(){
281 var sheet = new Sheet();
282 sheet.setCell("A1", "1");
283diff --git a/tests/Utils/Asserts.ts b/tests/Utils/Asserts.ts
284index 3709262..46163c9 100644
285--- a/tests/Utils/Asserts.ts
286+++ b/tests/Utils/Asserts.ts
287@@ -10,6 +10,18 @@ function assertEquals(actual, expected) {
288 }
289 }
290
291+/**
292+ * Asserts value is equal to null.
293+ * @param actual - value to test.
294+ */
295+function assertIsNull(actual) {
296+ if (null !== actual) {
297+ console.log("expected:", null, " actual:", actual);
298+ console.trace();
299+ }
300+}
301+
302+
303 /**
304 * Assert two arrays are equal using strict equality testing on individual items.
305 * @param actual value
306@@ -58,6 +70,7 @@ function test(description: string, toRun: Function) {
307
308
309 export {
310+ assertIsNull,
311 assertEquals,
312 assertArrayEquals,
313 catchAndAssertEquals,