commit
message
[Text.VALUE] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-10-08 17:05:50
stats
8 file(s) changed,
73 insertions(+),
5 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Text.js
src/Formulas/AllFormulas.ts
src/Formulas/Text.ts
tests/Formulas/TextTest.ts
tests/SheetFormulaTest.ts
1diff --git a/DOCS.md b/DOCS.md
2index 0ca004d..613a1c8 100644
3--- a/DOCS.md
4+++ b/DOCS.md
5@@ -2470,3 +2470,12 @@
6 @param numberOfReps - The number of repetitions
7 @constructor
8 ```
9+
10+### VALUE
11+
12+```
13+ Converts a value into a number if possible.
14+@param value - The value to convert to a number.
15+@returns {number}
16+@constructor
17+```
18diff --git a/TODO.md b/TODO.md
19index 6496d7e..396e867 100644
20--- a/TODO.md
21+++ b/TODO.md
22@@ -20,6 +20,10 @@ Currently, this `=SERIESSUM([1], [0], [1], [4, 5, 6])` parses, but this `=SERIES
23 E.g. `01/09/2012 10:04:33.123`
24
25
26+### TypeConverter should be able to convert timestamps to numbers.
27+E.g. `12:00:00` should result in `0.5`.
28+
29+
30 ### Parser should be able to parse arrays without `eval`
31 Right now, arrays and reference literals in a formula are parsed using JS `eval`. This means, if we have references inside, or non-JS parsing values like TRUE or FALSE, they will cause ReferenceErrors. For example, `=SUM([M1, 10])` would throw `[ReferenceError: M1 is not defined]` because M1 is not a variable. Instead of using `eval`, we should parse the opening of an array, and the closeing of an array, and use recursion to see how deep we are, evaluating the tokens inside in the sam way we parse formulas and functions.
32
33@@ -47,7 +51,6 @@ Many of these formulas can be written by allowing the Sheet and Parser to return
34 * REGEXREPLACE - May be difficult considering language differences.
35 * REPLACE
36 * SUBSTITUTE
37-* VALUE
38
39 ### Other formulas to write
40 * CRITBINOM
41diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
42index cfcfdf1..6215687 100644
43--- a/dist/Formulas/AllFormulas.js
44+++ b/dist/Formulas/AllFormulas.js
45@@ -234,6 +234,7 @@ exports.LEFT = Text_1.LEFT;
46 exports.RIGHT = Text_1.RIGHT;
47 exports.SEARCH = Text_1.SEARCH;
48 exports.REPT = Text_1.REPT;
49+exports.VALUE = Text_1.VALUE;
50 var Date_1 = require("./Date");
51 exports.DATE = Date_1.DATE;
52 exports.DATEVALUE = Date_1.DATEVALUE;
53diff --git a/dist/Formulas/Text.js b/dist/Formulas/Text.js
54index abc96e2..ebd711b 100644
55--- a/dist/Formulas/Text.js
56+++ b/dist/Formulas/Text.js
57@@ -835,3 +835,18 @@ var REPT = function (text, numberOfReps) {
58 return new Array(numberOfReps + 1).join(text);
59 };
60 exports.REPT = REPT;
61+/**
62+ * Converts a value into a number if possible.
63+ * @param value - The value to convert to a number.
64+ * @returns {number}
65+ * @constructor
66+ */
67+var VALUE = function (value) {
68+ ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "VALUE");
69+ value = TypeConverter_1.TypeConverter.firstValue(value);
70+ if (typeof value === "boolean") {
71+ throw new Errors_1.ValueError("VALUE parameter '" + value + "' cannot be parsed to number.");
72+ }
73+ return TypeConverter_1.TypeConverter.firstValueAsNumber(value);
74+};
75+exports.VALUE = VALUE;
76diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
77index 1d8209f..6abe939 100644
78--- a/src/Formulas/AllFormulas.ts
79+++ b/src/Formulas/AllFormulas.ts
80@@ -241,7 +241,8 @@ import {
81 LEFT,
82 RIGHT,
83 SEARCH,
84- REPT
85+ REPT,
86+ VALUE
87 } from "./Text"
88 import {
89 DATE,
90@@ -543,5 +544,6 @@ export {
91 LEFT,
92 RIGHT,
93 SEARCH,
94- REPT
95+ REPT,
96+ VALUE
97 }
98\ No newline at end of file
99diff --git a/src/Formulas/Text.ts b/src/Formulas/Text.ts
100index 0cfef32..c80e535 100644
101--- a/src/Formulas/Text.ts
102+++ b/src/Formulas/Text.ts
103@@ -867,6 +867,21 @@ let REPT = function (text, numberOfReps) {
104 return new Array(numberOfReps + 1).join(text);
105 };
106
107+/**
108+ * Converts a value into a number if possible.
109+ * @param value - The value to convert to a number.
110+ * @returns {number}
111+ * @constructor
112+ */
113+let VALUE = function (value) {
114+ ArgsChecker.checkLength(arguments, 1, "VALUE");
115+ value = TypeConverter.firstValue(value);
116+ if (typeof value === "boolean") {
117+ throw new ValueError("VALUE parameter '" + value + "' cannot be parsed to number.");
118+ }
119+ return TypeConverter.firstValueAsNumber(value);
120+};
121+
122 export {
123 ARABIC,
124 CHAR,
125@@ -886,5 +901,6 @@ export {
126 LEFT,
127 RIGHT,
128 SEARCH,
129- REPT
130+ REPT,
131+ VALUE
132 }
133\ No newline at end of file
134diff --git a/tests/Formulas/TextTest.ts b/tests/Formulas/TextTest.ts
135index fc9a220..f2e1dbb 100644
136--- a/tests/Formulas/TextTest.ts
137+++ b/tests/Formulas/TextTest.ts
138@@ -17,7 +17,8 @@ import {
139 LEFT,
140 RIGHT,
141 SEARCH,
142- REPT
143+ REPT,
144+ VALUE
145 } from "../../src/Formulas/Text";
146 import * as ERRORS from "../../src/Errors";
147 import {
148@@ -483,3 +484,19 @@ test("REPT", function(){
149 REPT.apply(this, [1, 2, 3]);
150 }, ERRORS.NA_ERROR);
151 });
152+
153+test("VALUE", function(){
154+ assertEquals(VALUE("10"), 10);
155+ assertEquals(VALUE(10), 10);
156+ assertEquals(VALUE(10.1), 10.1);
157+ assertEquals(VALUE([10]), 10);
158+ assertEquals(VALUE("7/20/1966"), 24308);
159+ // TODO: Should pass once we're able to parse timestamp strings.
160+ // assertEquals(VALUE("12:00:00"), 0.5);
161+ catchAndAssertEquals(function() {
162+ VALUE(true);
163+ }, ERRORS.VALUE_ERROR);
164+ catchAndAssertEquals(function() {
165+ VALUE("str");
166+ }, ERRORS.VALUE_ERROR);
167+});
168diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
169index 844ba5d..37c89ae 100644
170--- a/tests/SheetFormulaTest.ts
171+++ b/tests/SheetFormulaTest.ts
172@@ -1073,6 +1073,10 @@ test("Sheet REPT", function(){
173 assertFormulaEquals('=REPT("a", 2)', "aa");
174 });
175
176+test("Sheet VALUE", function(){
177+ assertFormulaEquals('=VALUE("10")', 10);
178+});
179+
180 test("Sheet parsing error", function(){
181 assertFormulaEqualsError('= 10e', PARSE_ERROR);
182 assertFormulaEqualsError('= SUM(', PARSE_ERROR);