commit
message
Added Formulas.DOLLAR
author
Ben Vogt <[email protected]>
date
2017-02-20 19:40:20
stats
5 file(s) changed,
55 insertions(+),
6 deletions(-)
files
README.md
src/RawFormulas/RawFormulas.ts
src/RawFormulas/Utils.ts
tests/FormulasTest.ts
tests/SheetFormulaTest.ts
1diff --git a/README.md b/README.md
2index 3b16fe2..d47b149 100644
3--- a/README.md
4+++ b/README.md
5@@ -45,3 +45,8 @@ don't check for this, and they should.
6
7 ### jStat functions should know their caller
8 Either through `arguments`, or directly passed in like `mean("FORMULA", [10, 20, 30])`
9+
10+### Dollar functions have special types
11+Although dollar functions look like they just format `number`s, it seems like they have a special type under the hood.
12+This means that we should do dollar->number casting in all casting functions. For now, just using number primitive.
13+See `DOLLAR` function for more info.
14\ No newline at end of file
15diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
16index c995254..7c6f00b 100644
17--- a/src/RawFormulas/RawFormulas.ts
18+++ b/src/RawFormulas/RawFormulas.ts
19@@ -103,7 +103,7 @@ import {
20 TypeCaster,
21 Serializer
22 } from "./Utils";
23-import {CellError, NUM_ERROR} from "../Errors"
24+import {CellError} from "../Errors"
25 import * as ERRORS from "../Errors"
26
27 var ACCRINT = Formula["ACCRINT"];
28@@ -117,7 +117,6 @@ var DATEVALUE = function (dateString: string) : Date {
29 var DAY = Formula["DAY"];
30 var DAYS = Formula["DAYS"];
31 var DAYS360 = Formula["DAYS360"];
32-var DOLLAR = Formula["DOLLAR"];
33 var DOLLARDE = Formula["DOLLARDE"];
34 var DOLLARFR = Formula["DOLLARFR"];
35 var EDATE = function (start_date: Date, months) {
36@@ -133,6 +132,30 @@ var __COMPLEX = {
37 var YEARFRAC = Formula["YEARFRAC"];
38
39
40+/**
41+ * Formats a number into the locale-specific currency format. WARNING: Currently the equivalent of TRUNC, since this
42+ * returns numbers
43+ * @param values[0] number - The value to be formatted.
44+ * @param values[1] places - [ OPTIONAL - 2 by default ] - The number of decimal places to display.
45+ * @returns {number} dollars
46+ * @constructor
47+ * TODO: In GS and Excel, Dollar values are primitive types at a certain level, meaning you can do =DOLLAR(10) + 10
48+ * TODO(cont.) and the result will be 20. Right now, JS allows you to inherit from primitives so you can use operators
49+ * TODO(cont.) on them (eg: new Number(10) + 10 == 20) but TS does not. So for now, Dollar values will be represented
50+ * TODO(cont.) with the primitive number type. At some point TS might allow me to suppress the warnings with
51+ * TODO(cont.) https://github.com/Microsoft/TypeScript/issues/9448 or
52+ * TODO(cont.) https://github.com/Microsoft/TypeScript/issues/11051
53+ */
54+var DOLLAR = function (...values) : number {
55+ ArgsChecker.checkLengthWithin(values, 1, 2);
56+ var v = TypeCaster.firstValueAsNumber(values[0]);
57+ var places = values.length === 2 ? TypeCaster.firstValueAsNumber(values[1]) : 2;
58+ var sign = (v > 0) ? 1 : -1;
59+ return sign * (Math.floor(Math.abs(v) * Math.pow(10, places))) / Math.pow(10, places);
60+};
61+
62+
63+
64 /**
65 * Returns the number of ways to choose some number of objects from a pool of a given size of objects.
66 * @param values[0] n - The size of the pool of objects to choose from.
67diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
68index 92bde34..be342ec 100644
69--- a/src/RawFormulas/Utils.ts
70+++ b/src/RawFormulas/Utils.ts
71@@ -100,13 +100,13 @@ class TypeCaster {
72 return 0;
73 }
74 if (value.indexOf(".") > -1) {
75- var fl = parseFloat(value);
76+ var fl = parseFloat(value.replace("$", ""));
77 if (isNaN(fl)) {
78 throw new CellError(ERRORS.VALUE_ERROR, "Function ____ expects number values, but is text and cannot be coerced to a number.");
79 }
80 return fl;
81 }
82- var fl = parseInt(value);
83+ var fl = parseInt(value.replace("$", ""));
84 if (isNaN(fl)) {
85 throw new CellError(ERRORS.VALUE_ERROR, "Function ____ expects number values, but is text and cannot be coerced to a number.");
86 }
87diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
88index 8eab87a..d71dc7c 100644
89--- a/tests/FormulasTest.ts
90+++ b/tests/FormulasTest.ts
91@@ -920,7 +920,27 @@ catchAndAssertEquals(function() {
92 }, ERRORS.REF_ERROR);
93
94
95-assertEquals(DOLLAR(1.2351, 4), "$1.2351");
96+// Test DOLLAR
97+assertEquals(DOLLAR(1.2351, 4), 1.2351);
98+assertEquals(DOLLAR(1.2351, 2), 1.23);
99+assertEquals(DOLLAR("$3.141592653589793", "2"), 3.14);
100+assertEquals(DOLLAR("-$3.141592653589793", "2"), -3.14);
101+assertEquals(DOLLAR("$-3.141592653589793", "2"), -3.14);
102+assertEquals(DOLLAR(PI(), 1), 3.1);
103+assertEquals(DOLLAR(PI(), 0), 3);
104+assertEquals(DOLLAR(PI(), false), 3);
105+assertEquals(DOLLAR(PI(), -1), 0);
106+assertEquals(DOLLAR(31.41592653589793, -1), 30);
107+assertEquals(DOLLAR([31.41592653589793], [-1]), 30);
108+assertEquals(DOLLAR(31111.41592653589793, -4), 30000);
109+assertEquals(DOLLAR(31111.41592653589793, -2), 31100);
110+catchAndAssertEquals(function() {
111+ DOLLAR();
112+}, ERRORS.NA_ERROR);
113+catchAndAssertEquals(function() {
114+ DOLLAR(3.1, 1, 1);
115+}, ERRORS.NA_ERROR);
116+
117
118 assertEquals(DOLLARDE(100.1, 32), 100.3125);
119
120diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
121index 69ea836..df3e23f 100644
122--- a/tests/SheetFormulaTest.ts
123+++ b/tests/SheetFormulaTest.ts
124@@ -209,7 +209,7 @@ testFormula('=DELTA(2, 2)', 1);
125 testFormula('=DEVSQ(1, 2)', 0.5);
126
127 // Test DOLLAR
128-testFormula('=DOLLAR(1.2351, 4)', "$1.2351");
129+testFormula('=DOLLAR(1.2351, 4)', 1.2351);
130
131 // Test DOLLARDE
132 testFormula('=DOLLARDE(100.1, 32)', 100.3125);