@odoo/o-spreadsheet 14.0.1 → 15.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/dist/o_spreadsheet.cjs.js +31302 -0
  2. package/dist/o_spreadsheet.d.ts +6604 -0
  3. package/dist/o_spreadsheet.esm.js +31257 -0
  4. package/dist/o_spreadsheet.iife.js +31304 -0
  5. package/dist/o_spreadsheet.iife.min.js +3071 -0
  6. package/package.json +57 -15
  7. package/.eslintrc.json +0 -20
  8. package/.husky/post-checkout +0 -9
  9. package/.husky/pre-commit +0 -39
  10. package/.prettierignore +0 -1
  11. package/astToFormula.patch +0 -0
  12. package/demo/data.js +0 -255
  13. package/demo/index.html +0 -9
  14. package/demo/libs/Chart.bundle.js +0 -20755
  15. package/demo/main.js +0 -101
  16. package/doc/readme.md +0 -46
  17. package/rollup.config.js +0 -23
  18. package/src/base_plugin.ts +0 -102
  19. package/src/components/autofill.ts +0 -146
  20. package/src/components/bottom_bar.ts +0 -199
  21. package/src/components/color_picker.ts +0 -150
  22. package/src/components/composer/autocomplete_dropdown.ts +0 -135
  23. package/src/components/composer/composer.ts +0 -487
  24. package/src/components/composer/content_editable_helper.ts +0 -146
  25. package/src/components/figures/chart.ts +0 -70
  26. package/src/components/figures/container.ts +0 -268
  27. package/src/components/figures/text_figure.ts +0 -36
  28. package/src/components/grid.ts +0 -635
  29. package/src/components/helpers/dom_helpers.ts +0 -7
  30. package/src/components/helpers/drag_and_drop.ts +0 -17
  31. package/src/components/icons.ts +0 -36
  32. package/src/components/index.ts +0 -1
  33. package/src/components/menu.ts +0 -288
  34. package/src/components/overlay.ts +0 -457
  35. package/src/components/scrollbar.ts +0 -22
  36. package/src/components/selection_input.ts +0 -168
  37. package/src/components/side_panel/cell_is_rule_editor.ts +0 -169
  38. package/src/components/side_panel/chart_panel.ts +0 -104
  39. package/src/components/side_panel/color_scale_rule_editor.ts +0 -145
  40. package/src/components/side_panel/conditional_formatting.ts +0 -396
  41. package/src/components/side_panel/side_panel.ts +0 -127
  42. package/src/components/side_panel/translations_terms.ts +0 -45
  43. package/src/components/spreadsheet.ts +0 -198
  44. package/src/components/top_bar.ts +0 -535
  45. package/src/constants.ts +0 -26
  46. package/src/data.ts +0 -149
  47. package/src/fonts.ts +0 -41
  48. package/src/formulas/compiler.ts +0 -258
  49. package/src/formulas/composer_tokenizer.ts +0 -70
  50. package/src/formulas/index.ts +0 -15
  51. package/src/formulas/normalize.ts +0 -52
  52. package/src/formulas/parser.ts +0 -280
  53. package/src/formulas/range_tokenizer.ts +0 -97
  54. package/src/formulas/tokenizer.ts +0 -242
  55. package/src/functions/arguments.ts +0 -114
  56. package/src/functions/dates.ts +0 -302
  57. package/src/functions/helpers.ts +0 -592
  58. package/src/functions/index.ts +0 -52
  59. package/src/functions/module_database.ts +0 -282
  60. package/src/functions/module_date.ts +0 -743
  61. package/src/functions/module_info.ts +0 -69
  62. package/src/functions/module_logical.ts +0 -208
  63. package/src/functions/module_lookup.ts +0 -185
  64. package/src/functions/module_math.ts +0 -1252
  65. package/src/functions/module_operators.ts +0 -291
  66. package/src/functions/module_statistical.ts +0 -882
  67. package/src/functions/module_text.ts +0 -370
  68. package/src/helpers/color.ts +0 -30
  69. package/src/helpers/coordinates.ts +0 -71
  70. package/src/helpers/grid_manipulation.ts +0 -68
  71. package/src/helpers/index.ts +0 -7
  72. package/src/helpers/misc.ts +0 -76
  73. package/src/helpers/numbers.ts +0 -117
  74. package/src/helpers/uuid.ts +0 -19
  75. package/src/helpers/zones.ts +0 -263
  76. package/src/history.ts +0 -186
  77. package/src/index.ts +0 -84
  78. package/src/model.ts +0 -261
  79. package/src/plugins/autofill.ts +0 -412
  80. package/src/plugins/chart.ts +0 -404
  81. package/src/plugins/clipboard.ts +0 -461
  82. package/src/plugins/conditional_format.ts +0 -445
  83. package/src/plugins/core.ts +0 -1502
  84. package/src/plugins/edition.ts +0 -157
  85. package/src/plugins/evaluation.ts +0 -428
  86. package/src/plugins/figures.ts +0 -123
  87. package/src/plugins/formatting.ts +0 -630
  88. package/src/plugins/highlight.ts +0 -187
  89. package/src/plugins/index.ts +0 -32
  90. package/src/plugins/merge.ts +0 -524
  91. package/src/plugins/renderer.ts +0 -571
  92. package/src/plugins/selection.ts +0 -562
  93. package/src/plugins/selection_inputs.ts +0 -326
  94. package/src/registries/autofill_modifiers.ts +0 -76
  95. package/src/registries/autofill_rules.ts +0 -98
  96. package/src/registries/figure_registry.ts +0 -30
  97. package/src/registries/index.ts +0 -7
  98. package/src/registries/menu_items_registry.ts +0 -110
  99. package/src/registries/menus/cell_menu_registry.ts +0 -79
  100. package/src/registries/menus/col_menu_registry.ts +0 -63
  101. package/src/registries/menus/index.ts +0 -6
  102. package/src/registries/menus/menu_items_actions.ts +0 -425
  103. package/src/registries/menus/row_menu_registry.ts +0 -63
  104. package/src/registries/menus/sheet_menu_registry.ts +0 -75
  105. package/src/registries/menus/topbar_menu_registry.ts +0 -204
  106. package/src/registries/side_panel_registry.ts +0 -26
  107. package/src/registries/topbar_component_registry.ts +0 -12
  108. package/src/registry.ts +0 -51
  109. package/src/translation.ts +0 -44
  110. package/src/types/autofill.ts +0 -48
  111. package/src/types/chart.ts +0 -26
  112. package/src/types/commands.ts +0 -716
  113. package/src/types/conditional_formatting.ts +0 -124
  114. package/src/types/env.ts +0 -13
  115. package/src/types/functions.ts +0 -35
  116. package/src/types/getters.ts +0 -103
  117. package/src/types/index.ts +0 -20
  118. package/src/types/misc.ts +0 -143
  119. package/src/types/rendering.ts +0 -41
  120. package/src/types/workbook_data.ts +0 -62
  121. package/tests/__mocks__/uuid.ts +0 -7
  122. package/tests/canvas.mock.ts +0 -34
  123. package/tests/components/__mocks__/content_editable_helper.ts +0 -79
  124. package/tests/components/__mocks__/scrollbar.ts +0 -18
  125. package/tests/components/__snapshots__/autocomplete_dropdown_test.ts.snap +0 -29
  126. package/tests/components/__snapshots__/bottom_bar_test.ts.snap +0 -75
  127. package/tests/components/__snapshots__/context_menu_test.ts.snap +0 -88
  128. package/tests/components/__snapshots__/grid_test.ts.snap +0 -60
  129. package/tests/components/__snapshots__/spreadsheet_test.ts.snap +0 -455
  130. package/tests/components/__snapshots__/top_bar_test.ts.snap +0 -705
  131. package/tests/components/autocomplete_dropdown_test.ts +0 -315
  132. package/tests/components/autofill_test.ts +0 -167
  133. package/tests/components/bottom_bar_test.ts +0 -262
  134. package/tests/components/chart_side_panel_test.ts +0 -123
  135. package/tests/components/composer_test.ts +0 -400
  136. package/tests/components/context_menu_test.ts +0 -825
  137. package/tests/components/grid_manipulation_test.ts +0 -163
  138. package/tests/components/grid_test.ts +0 -581
  139. package/tests/components/overlay_test.ts +0 -541
  140. package/tests/components/selection_input_test.ts +0 -259
  141. package/tests/components/side_panel_test.ts +0 -148
  142. package/tests/components/spreadsheet_test.ts +0 -194
  143. package/tests/components/top_bar_test.ts +0 -427
  144. package/tests/data_test.ts +0 -175
  145. package/tests/dom_helper.ts +0 -42
  146. package/tests/formulas/__snapshots__/compiler_test.ts.snap +0 -302
  147. package/tests/formulas/compiler_test.ts +0 -266
  148. package/tests/formulas/composer_tokenizer_test.ts +0 -137
  149. package/tests/formulas/expressions_test.ts +0 -57
  150. package/tests/formulas/formulas_test.ts +0 -80
  151. package/tests/formulas/normalize_test.ts +0 -82
  152. package/tests/formulas/parser_test.ts +0 -224
  153. package/tests/formulas/range_tokenizer_test.ts +0 -187
  154. package/tests/formulas/tokenizer_test.ts +0 -164
  155. package/tests/functions/arguments_test.ts +0 -141
  156. package/tests/functions/dates_test.ts +0 -1081
  157. package/tests/functions/functions_test.ts +0 -53
  158. package/tests/functions/helper_test.ts +0 -98
  159. package/tests/functions/module_database_test.ts +0 -311
  160. package/tests/functions/module_date_test.ts +0 -941
  161. package/tests/functions/module_info_test.ts +0 -139
  162. package/tests/functions/module_logical_test.ts +0 -369
  163. package/tests/functions/module_lookup_test.ts +0 -541
  164. package/tests/functions/module_math_test.ts +0 -2482
  165. package/tests/functions/module_operators_test.ts +0 -955
  166. package/tests/functions/module_statistical_test.ts +0 -2014
  167. package/tests/functions/module_text_test.ts +0 -667
  168. package/tests/helpers/coordinates_test.ts +0 -25
  169. package/tests/helpers/misc_test.ts +0 -95
  170. package/tests/helpers/numbers_test.ts +0 -196
  171. package/tests/helpers/zones_test.ts +0 -97
  172. package/tests/helpers.ts +0 -384
  173. package/tests/menu_items_registry_test.ts +0 -540
  174. package/tests/model/plugins/__snapshots__/chart_test.ts.snap +0 -90
  175. package/tests/model/plugins/chart_test.ts +0 -562
  176. package/tests/model_test.ts +0 -82
  177. package/tests/plugins/__snapshots__/conditional_formatting_test.ts.snap +0 -131
  178. package/tests/plugins/__snapshots__/renderer_test.ts.snap +0 -371
  179. package/tests/plugins/autofill_test.ts +0 -457
  180. package/tests/plugins/borders_test.ts +0 -295
  181. package/tests/plugins/clipboard_test.ts +0 -1180
  182. package/tests/plugins/conditional_formatting_test.ts +0 -1253
  183. package/tests/plugins/core_test.ts +0 -614
  184. package/tests/plugins/edition_test.ts +0 -100
  185. package/tests/plugins/evaluation_async_test.ts +0 -332
  186. package/tests/plugins/evaluation_dates_test.ts +0 -79
  187. package/tests/plugins/evaluation_test.ts +0 -901
  188. package/tests/plugins/figures_test.ts +0 -327
  189. package/tests/plugins/formatting_test.ts +0 -391
  190. package/tests/plugins/grid_manipulation_test.ts +0 -1366
  191. package/tests/plugins/highlight_test.ts +0 -413
  192. package/tests/plugins/history_test.ts +0 -142
  193. package/tests/plugins/import_export_test.ts +0 -276
  194. package/tests/plugins/merges_test.ts +0 -490
  195. package/tests/plugins/navigation_test.ts +0 -181
  196. package/tests/plugins/plugins/evaluation_test.ts +0 -111
  197. package/tests/plugins/renderer_test.ts +0 -598
  198. package/tests/plugins/resizing_test.ts +0 -152
  199. package/tests/plugins/selection_input_test.ts +0 -409
  200. package/tests/plugins/selection_test.ts +0 -442
  201. package/tests/plugins/sheets_test.ts +0 -643
  202. package/tests/plugins/style_test.ts +0 -90
  203. package/tsconfig.json +0 -22
@@ -1,2482 +0,0 @@
1
- import { toNumber } from "../../src/functions/helpers";
2
- import { evaluateCell, evaluateGrid } from "../helpers";
3
-
4
- describe("math", () => {
5
- //----------------------------------------------------------------------------
6
- // ACOS
7
- //----------------------------------------------------------------------------
8
-
9
- test.each([
10
- ["1", 0],
11
- ["-1", Math.PI],
12
- ["0", Math.PI / 2],
13
- ["0.5", Math.PI / 3],
14
- ])("ACOS(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
15
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: a })).toBeCloseTo(expected, 9);
16
- });
17
-
18
- test.each([["2"], ["-1.5"]])("ACOS(%s) - ERROR: take 1 parameter(s), return an error", (a) => {
19
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
20
- });
21
-
22
- test("ACOS: special value testing", () => {
23
- expect(evaluateCell("A1", { A1: "=ACOS()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
24
- expect(evaluateCell("A1", { A1: "=ACOS(TRUE)" })).toBeCloseTo(0, 9);
25
- expect(evaluateCell("A1", { A1: "=ACOS(FALSE)" })).toBeCloseTo(Math.PI / 2, 9);
26
-
27
- expect(evaluateCell("A1", { A1: '=ACOS("")' })).toBeCloseTo(Math.PI / 2, 9);
28
- expect(evaluateCell("A1", { A1: '=ACOS(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
29
- expect(evaluateCell("A1", { A1: '=ACOS("0")' })).toBeCloseTo(Math.PI / 2, 9);
30
-
31
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: "" })).toBeCloseTo(Math.PI / 2, 9);
32
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
33
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: "0" })).toBeCloseTo(Math.PI / 2, 9);
34
-
35
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
36
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
37
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: '"0"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
38
-
39
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: '=""' })).toBeCloseTo(Math.PI / 2, 9);
40
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
41
- expect(evaluateCell("A1", { A1: "=ACOS(A2)", A2: '="0"' })).toBeCloseTo(Math.PI / 2, 9);
42
- });
43
-
44
- //----------------------------------------------------------------------------
45
- // ACOSH
46
- //----------------------------------------------------------------------------
47
-
48
- test.each([
49
- ["1.54308063481524", 1],
50
- ["1", 0],
51
- ["1.25", Math.log(2)],
52
- ["2.125", Math.log(4)],
53
- ])("ACOSH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
54
- expect(evaluateCell("A1", { A1: "=ACOSH(A2)", A2: a })).toBeCloseTo(expected, 9);
55
- });
56
-
57
- test.each([["-2"], ["0.5"]])("ACOSH(%s) - ERROR: take 1 parameter(s), return an error", (a) => {
58
- expect(evaluateCell("A1", { A1: "=ACOSH(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
59
- });
60
-
61
- //----------------------------------------------------------------------------
62
- // ACOT
63
- //----------------------------------------------------------------------------
64
-
65
- test.each([
66
- ["0", Math.PI / 2],
67
- ["1", Math.PI / 4],
68
- ["-1", -Math.PI / 4],
69
- ["2", 0.463647609],
70
- ["-4", -0.244978663],
71
- ])("ACOT(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
72
- expect(evaluateCell("A1", { A1: "=ACOT(A2)", A2: a })).toBeCloseTo(expected, 9);
73
- });
74
-
75
- //----------------------------------------------------------------------------
76
- // ACOTH
77
- //----------------------------------------------------------------------------
78
-
79
- test.each([
80
- ["1.25", Math.log(3)],
81
- ["1.1", 1.522261219],
82
- ["2", 0.549306144],
83
- ["-3", -0.34657359],
84
- ["-4", -0.255412812],
85
- ])("ACOTH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
86
- expect(evaluateCell("A1", { A1: "=ACOTH(A2)", A2: a })).toBeCloseTo(expected, 9);
87
- });
88
-
89
- test.each([["0"], ["1"], ["-1"], ["0.5"]])(
90
- "ACOTH(%s) - ERROR: take 1 parameter(s), return an error",
91
- (a) => {
92
- expect(evaluateCell("A1", { A1: "=ACOTH(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
93
- }
94
- );
95
-
96
- //----------------------------------------------------------------------------
97
- // ASIN
98
- //----------------------------------------------------------------------------
99
-
100
- test.each([
101
- ["1", Math.PI / 2],
102
- ["-1", -Math.PI / 2],
103
- ["0", 0],
104
- ["0.5", Math.PI / 6],
105
- ])("ASIN(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
106
- expect(evaluateCell("A1", { A1: "=ASIN(A2)", A2: a })).toBeCloseTo(expected, 9);
107
- });
108
-
109
- test.each([["2"], ["-1.5"]])("ASIN(%s) - ERROR: take 1 parameter(s), return an error", (a) => {
110
- expect(evaluateCell("A1", { A1: "=ASIN(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
111
- });
112
-
113
- //----------------------------------------------------------------------------
114
- // ASINH
115
- //----------------------------------------------------------------------------
116
-
117
- test.each([
118
- ["1.175201194", 1],
119
- ["-3.626860408", -2],
120
- ["0", 0],
121
- ["0.75", Math.log(2)],
122
- ["-1.875", -Math.log(4)],
123
- ])("ASINH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
124
- expect(evaluateCell("A1", { A1: "=ASINH(A2)", A2: a })).toBeCloseTo(expected, 9);
125
- });
126
-
127
- //----------------------------------------------------------------------------
128
- // ATAN
129
- //----------------------------------------------------------------------------
130
-
131
- test.each([
132
- ["0", 0],
133
- ["1", Math.PI / 4],
134
- ["1.557407725", 1],
135
- ["-2", -1.107148718],
136
- ["-4", -1.325817664],
137
- ])("ATAN(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
138
- expect(evaluateCell("A1", { A1: "=ATAN(A2)", A2: a })).toBeCloseTo(expected, 9);
139
- });
140
-
141
- //----------------------------------------------------------------------------
142
- // ATAN2
143
- //----------------------------------------------------------------------------
144
-
145
- test.each([
146
- ["42", "0", 0],
147
- ["0", "42", Math.PI / 2],
148
- ["2", "2", Math.PI / 4],
149
- ["-2", "3", 2.15879893],
150
- ["4", "-7", -1.051650213],
151
- ])("ATAN2(%s, %s) - %s: take 1 parameter(s), return a number", (a, b, expected) => {
152
- expect(evaluateCell("A1", { A1: "=ATAN2(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected, 9);
153
- });
154
-
155
- test.each([["0", "0"]])("ATAN2(%s, %s) - ERROR: take 1 parameter(s), return an error", (a, b) => {
156
- expect(evaluateCell("A1", { A1: "=ATAN2(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
157
- });
158
-
159
- //----------------------------------------------------------------------------
160
- // ATANH
161
- //----------------------------------------------------------------------------
162
-
163
- test.each([
164
- ["0.8", Math.log(3)],
165
- ["0.6", Math.log(2)],
166
- ["0", 0],
167
- [" 0.761594156", 1],
168
- ["-0.9", -1.47221949],
169
- ])("ATANH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
170
- expect(evaluateCell("A1", { A1: "=ATANH(A2)", A2: a })).toBeCloseTo(expected, 9);
171
- });
172
-
173
- test.each([["1.1"], ["-1"], ["42"]])(
174
- "ATANH(%s) - ERROR: take 1 parameter(s), return an error",
175
- (a) => {
176
- expect(evaluateCell("A1", { A1: "=ATANH(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
177
- }
178
- );
179
-
180
- //----------------------------------------------------------------------------
181
- // CEILING / CEILING.MATH / CEILING.PRECISE / ISO.CEILING
182
- //----------------------------------------------------------------------------
183
-
184
- test.each([
185
- ["0", 0],
186
- ["6", 6],
187
- ["-6", -6],
188
- ["6.7", 7],
189
- ["7.89", 8],
190
- ["-6.7", -6],
191
- ["-7.89", -7],
192
- ])("CEILING FUNCTIONS(%s) - %s: take 1 parameters, return a number", (a, expected) => {
193
- expect(evaluateCell("A1", { A1: "=CEILING(A2)", A2: a })).toBe(expected);
194
- expect(evaluateCell("A1", { A1: "=CEILING.MATH(A2)", A2: a })).toBe(expected);
195
- expect(evaluateCell("A1", { A1: "=CEILING.PRECISE(A2)", A2: a })).toBe(expected);
196
- expect(evaluateCell("A1", { A1: "=ISO.CEILING(A2)", A2: a })).toBe(expected);
197
- });
198
-
199
- test.each([
200
- ["0", "0", 0],
201
- ["0", "0.1", 0],
202
- ["0", "-4", 0],
203
- ["6", "0", 0],
204
- ["6.7", "0", 0],
205
- ["-6", "0", 0],
206
- ["6", "0.1", 6],
207
- ["-6", "0.1", -6],
208
- ["6", "0.7", 6.3],
209
- ["-6", "0.7", -5.6],
210
- ["6.7", "0.2", 6.8],
211
- ["-6.7", "0.2", -6.6],
212
- ])("CEILING FUNCTIONS(%s, %s) - %s: take 2 parameters, return a number", (a, b, expected) => {
213
- expect(evaluateCell("A1", { A1: "=CEILING(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected, 9);
214
- expect(evaluateCell("A1", { A1: "=CEILING.MATH(A2, A3)", A2: a, A3: b })).toBeCloseTo(
215
- expected,
216
- 9
217
- );
218
- expect(evaluateCell("A1", { A1: "=CEILING.PRECISE(A2, A3)", A2: a, A3: b })).toBeCloseTo(
219
- expected,
220
- 9
221
- );
222
- expect(evaluateCell("A1", { A1: "=ISO.CEILING(A2, A3)", A2: a, A3: b })).toBeCloseTo(
223
- expected,
224
- 9
225
- );
226
- });
227
-
228
- test.each([
229
- ["0", "0.2", 0],
230
- ["0", "-0.2", 0],
231
- ["7.89", "0.2", 8],
232
- ["7.89", "-0.2", 8],
233
- ["-7.89", "0.2", -7.8],
234
- ["-7.89", "-0.2", -7.8],
235
- ])(
236
- "CEILING (MATH/PRECISE/ISO) FUNCTIONS(%s, %s) - %s: no effect with negative factor",
237
- (a, b, expected) => {
238
- expect(evaluateCell("A1", { A1: "=CEILING.MATH(A2, A3)", A2: a, A3: b })).toBeCloseTo(
239
- expected,
240
- 9
241
- );
242
- expect(evaluateCell("A1", { A1: "=CEILING.PRECISE(A2, A3)", A2: a, A3: b })).toBeCloseTo(
243
- expected,
244
- 9
245
- );
246
- expect(evaluateCell("A1", { A1: "=ISO.CEILING(A2, A3)", A2: a, A3: b })).toBeCloseTo(
247
- expected,
248
- 9
249
- );
250
- }
251
- );
252
-
253
- test.each([
254
- ["6", "-0.2"],
255
- ["7.89", "-0.2"],
256
- ])("CEILING(%s, %s) - error: if value positive, factor can't be negative", (a, b) => {
257
- expect(evaluateCell("A1", { A1: "=CEILING(A2, A3)", A2: a, A3: b })).toBe("#ERROR");
258
- });
259
-
260
- test.each([
261
- // Concerning CEILING function
262
- // if "a" is negative and "b" is negative, rounds a number down (and not up)
263
- // the nearest integer multiple of b
264
- ["-7.89", "0.2", -7.8],
265
- ["-7.89", "-0.2", -8],
266
- ])("CEILING(%s, %s) - %s: if factor negative, rounds number down", (a, b, expected) => {
267
- expect(evaluateCell("A1", { A1: "=CEILING(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected, 9);
268
- });
269
-
270
- test.each([
271
- // Concerning CEILING.MATH function
272
- // if "a" is negative and "c" different 0, rounds a number down (and not up)
273
- // the nearest integer multiple of b
274
- ["7.89", "0.2", "0", 8],
275
- ["7.89", "0.2", "1", 8],
276
- ["-7.89", "0.2", "0", -7.8],
277
- ["-7.89", "0.2", "1", -8],
278
- ["-7.89", "0.2", "2.2", -8],
279
- ["-7.89", "0.2", "-2.2", -8],
280
- ["-7.89", "-0.2", "0", -7.8],
281
- ["-7.89", "-0.2", "1", -8],
282
- ["-7.89", "-0.2", "2.2", -8],
283
- ["-7.89", "-0.2", "-2.2", -8],
284
- ])("CEILING.MATH(%s, %s, %s) - %s: take 3 parameters, return a number", (a, b, c, expected) => {
285
- expect(
286
- evaluateCell("A1", { A1: "=CEILING.MATH(A2, A3, A4)", A2: a, A3: b, A4: c })
287
- ).toBeCloseTo(expected, 9);
288
- });
289
-
290
- function evaluateCeilingFunction(functionName: string): void {
291
- expect(evaluateCell("A1", { A1: "=" + functionName + "()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
292
- expect(evaluateCell("A1", { A1: "=" + functionName + "( , )" })).toBeCloseTo(0, 9);
293
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, 0.2)" })).toBeCloseTo(-7.8, 9);
294
- expect(evaluateCell("A1", { A1: "=" + functionName + "( , 0.2)" })).toBeCloseTo(0, 9);
295
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, )" })).toBeCloseTo(0, 9); // @compatibility: on google sheets, return -7
296
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, TRUE)" })).toBeCloseTo(-7, 9);
297
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, FALSE)" })).toBeCloseTo(0, 9);
298
- expect(evaluateCell("A1", { A1: "=" + functionName + "(TRUE, 10)" })).toBeCloseTo(10, 9);
299
- expect(evaluateCell("A1", { A1: "=" + functionName + "(FALSE, 10)" })).toBeCloseTo(0, 9);
300
-
301
- expect(evaluateCell("A1", { A1: "=" + functionName + '("" , "")' })).toBeCloseTo(0, 9);
302
- expect(evaluateCell("A1", { A1: "=" + functionName + '(" " , " ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
303
- expect(evaluateCell("A1", { A1: "=" + functionName + '("-7.89", "0.2")' })).toBeCloseTo(
304
- -7.8,
305
- 9
306
- );
307
-
308
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "", A3: "" })).toBeCloseTo(
309
- 0,
310
- 9
311
- );
312
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: " ", A3: " " })).toBe(
313
- "#ERROR"
314
- ); // @compatibility: on google sheets, return #VALUE!
315
- expect(
316
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "0.2" })
317
- ).toBeCloseTo(-7.8, 9);
318
- expect(
319
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "", A3: "0.2" })
320
- ).toBeCloseTo(0, 9);
321
- expect(
322
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "" })
323
- ).toBeCloseTo(0, 9);
324
- expect(
325
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "TRUE" })
326
- ).toBeCloseTo(-7, 9);
327
- expect(
328
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "FALSE" })
329
- ).toBeCloseTo(0, 9);
330
- expect(
331
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "TRUE", A3: "10" })
332
- ).toBeCloseTo(10, 9);
333
- expect(
334
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "FALSE", A3: "10" })
335
- ).toBeCloseTo(0, 9);
336
-
337
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '""', A3: '""' })).toBe(
338
- "#ERROR"
339
- ); // @compatibility: on google sheets, return #VALUE!
340
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '" "', A3: '" "' })).toBe(
341
- "#ERROR"
342
- ); // @compatibility: on google sheets, return #VALUE!
343
- expect(
344
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '"-7.89"', A3: '"0.2"' })
345
- ).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
346
-
347
- expect(
348
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '=""', A3: '=""' })
349
- ).toBeCloseTo(0, 9);
350
- expect(
351
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '=" "', A3: '=" "' })
352
- ).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
353
- expect(
354
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '="-7.89"', A3: '="0.2"' })
355
- ).toBeCloseTo(-7.8, 9);
356
- }
357
-
358
- test.each([["CEILING"], ["CEILING.MATH"], ["CEILING.PRECISE"], ["ISO.CEILING"]])(
359
- "%s: special value testing",
360
- (functionName) => {
361
- evaluateCeilingFunction(functionName);
362
- }
363
- );
364
-
365
- //----------------------------------------------------------------------------
366
- // COS
367
- //----------------------------------------------------------------------------
368
-
369
- test.each([
370
- ["0", 1],
371
- ["=PI()", -1],
372
- ["=PI()*2", 1],
373
- ["=PI()/2", 0],
374
- ["=PI()/3", 0.5],
375
- ["=-PI()/2", 0],
376
- ])("COS(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
377
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: a })).toBeCloseTo(expected, 9);
378
- });
379
-
380
- test("COS: special value testing", () => {
381
- expect(evaluateCell("A1", { A1: "=COS()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
382
- expect(evaluateCell("A1", { A1: "=COS(TRUE)" })).toBeCloseTo(0.54030230586814, 9);
383
- expect(evaluateCell("A1", { A1: "=COS(FALSE)" })).toBeCloseTo(1, 9);
384
-
385
- expect(evaluateCell("A1", { A1: '=COS("")' })).toBeCloseTo(1, 9);
386
- expect(evaluateCell("A1", { A1: '=COS(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
387
- expect(evaluateCell("A1", { A1: '=COS("0")' })).toBeCloseTo(1, 9);
388
-
389
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: "" })).toBeCloseTo(1, 9);
390
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
391
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: "0" })).toBeCloseTo(1, 9);
392
-
393
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
394
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
395
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: '"0"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
396
-
397
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: '=""' })).toBeCloseTo(1, 9);
398
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
399
- expect(evaluateCell("A1", { A1: "=COS(A2)", A2: '="0"' })).toBeCloseTo(1, 9);
400
- });
401
-
402
- //----------------------------------------------------------------------------
403
- // COSH
404
- //----------------------------------------------------------------------------
405
-
406
- test.each([
407
- ["0", 1],
408
- ["1", 1.543080635],
409
- ["-1", 1.543080635],
410
- ["=LN(2)", 1.25],
411
- ["=LN(4)", 2.125],
412
- ])("COSH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
413
- expect(evaluateCell("A1", { A1: "=COSH(A2)", A2: a })).toBeCloseTo(expected, 9);
414
- });
415
-
416
- //----------------------------------------------------------------------------
417
- // COT
418
- //----------------------------------------------------------------------------
419
-
420
- test.each([
421
- ["=PI()/2", 0],
422
- ["=PI()/4", 1],
423
- ["=-PI()*5/4", -1],
424
- ["1", 0.642092616],
425
- ["2", -0.457657554],
426
- ])("COT(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
427
- expect(evaluateCell("A1", { A1: "=COT(A2)", A2: a })).toBeCloseTo(expected, 9);
428
- });
429
-
430
- test.each([["0"]])("COT(%s) - %s: take 1 parameter(s), return an error", (a) => {
431
- expect(evaluateCell("A1", { A1: "=COT(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!!
432
- });
433
-
434
- //----------------------------------------------------------------------------
435
- // COTH
436
- //----------------------------------------------------------------------------
437
-
438
- test.each([
439
- ["=LN(3)", 1.25],
440
- ["1", 1.313035285],
441
- ["2", 1.037314721],
442
- ["-3", -1.004969823],
443
- ["-4", -1.00067115],
444
- ])("COTH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
445
- expect(evaluateCell("A1", { A1: "=COTH(A2)", A2: a })).toBeCloseTo(expected, 9);
446
- });
447
-
448
- test.each([["0"]])("COTH(%s) - %s: take 1 parameter(s), return an error", (a) => {
449
- expect(evaluateCell("A1", { A1: "=COTH(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!!
450
- });
451
-
452
- //----------------------------------------------------------------------------
453
- // COUNTBLANK
454
- //----------------------------------------------------------------------------
455
-
456
- test("COUNTBLANK: functional tests on simple arguments", () => {
457
- expect(evaluateCell("A1", { A1: "=COUNTBLANK()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
458
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(,)" })).toBe(2);
459
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(0)" })).toBe(0);
460
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(42)" })).toBe(0);
461
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(TRUE)" })).toBe(0);
462
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(FALSE)" })).toBe(0);
463
-
464
- expect(evaluateCell("A1", { A1: '=COUNTBLANK("")' })).toBe(1);
465
- expect(evaluateCell("A1", { A1: '=COUNTBLANK(" ")' })).toBe(0);
466
- expect(evaluateCell("A1", { A1: '=COUNTBLANK("hello there")' })).toBe(0);
467
-
468
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: "" })).toBe(1);
469
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: " " })).toBe(0);
470
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: "0" })).toBe(0);
471
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: "42" })).toBe(0);
472
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: "TRUE" })).toBe(0);
473
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: "FALSE" })).toBe(0);
474
-
475
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: '""' })).toBe(0);
476
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: '" "' })).toBe(0);
477
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: '"42"' })).toBe(0);
478
-
479
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: '=""' })).toBe(1);
480
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: '=" "' })).toBe(0);
481
- expect(evaluateCell("A1", { A1: "=COUNTBLANK(A2)", A2: '="42"' })).toBe(0);
482
- });
483
-
484
- // prettier-ignore
485
- test("COUNTBLANK: count blank on ranges ", () => {
486
- const grid = {
487
-
488
- B1: "=COUNTBLANK(D1:I2)",
489
- C1: "=COUNTBLANK(D1:I1)",
490
- C2: "=COUNTBLANK(D2:I2)",
491
-
492
- D1: "0", E1: "1", F1: "2", G1: "", H1: '""', I1: "",
493
- D2: "", E2: "", F2: '""', G2: "FALSE", H2: "TRUE", I2: "42",
494
-
495
- A2: "=COUNTBLANK(A4:B9)",
496
- A3: "=COUNTBLANK(A4:A9)", B3: "=COUNTBLANK(B4:B9)",
497
-
498
- A4: "0", B4: "",
499
- A5: "1", B5: "",
500
- A6: "2", B6: '""',
501
- A7: "", B7: "FALSE",
502
- A8: '""', B8: "TRUE",
503
- A9: "", B9: "42",
504
- };
505
-
506
- const gridResult = evaluateGrid(grid);
507
- expect(gridResult.B1).toBe(4);
508
- expect(gridResult.C1).toBe(2);
509
- expect(gridResult.C2).toBe(2);
510
- expect(gridResult.A2).toBe(4);
511
- expect(gridResult.A3).toBe(2);
512
- expect(gridResult.B3).toBe(2);
513
- });
514
-
515
- //----------------------------------------------------------------------------
516
- // COUNTIF
517
- //----------------------------------------------------------------------------
518
-
519
- // prettier-ignore
520
- test("COUNTIF: operator tests on type number and type string", () => {
521
-
522
- const grid = {
523
- A1 : "1" , B1 : '="1"',
524
- A2 : "10", B2 : '="10"',
525
- A3 : "2" , B3 : '="2"',
526
- A4 : "20", B4 : '="20"',
527
- A5 : "3" , B5 : '="3"',
528
- A6 : "30", B6 : '="30"',
529
- A7 : "4" , B7 : '="4"',
530
- A8 : "40", B8 : '="40"',
531
-
532
- A10: "=COUNTIF(A1:A8, 20)" , B10: "=COUNTIF(B1:B8, 20)",
533
- A11: '=COUNTIF(A1:A8, "20")' , B11: '=COUNTIF(B1:B8, "20")',
534
- A12: '=COUNTIF(A1:A8, "=20")' , B12: '=COUNTIF(B1:B8, "=20")',
535
-
536
- A14: '=COUNTIF(A1:A8, "2*")' , B14: '=COUNTIF(B1:B8, "2*")',
537
-
538
- A16: '=COUNTIF(A1:A8, "<20")' , B16: '=COUNTIF(B1:B8, "<20")',
539
- A17: '=COUNTIF(A1:A8, ">20")' , B17: '=COUNTIF(B1:B8, ">20")',
540
-
541
- A19: '=COUNTIF(A1:A8, "< 20 ")' , B19: '=COUNTIF(B1:B8, "< 20 ")',
542
- A20: '=COUNTIF(A1:A8, "> 20 ")' , B20: '=COUNTIF(B1:B8, "> 20 ")',
543
-
544
- A22: '=COUNTIF(A1:A8, "< 20% ")', B22: '=COUNTIF(B1:B8, "< 20% ")',
545
- A23: '=COUNTIF(A1:A8, "> 20% ")', B23: '=COUNTIF(B1:B8, "> 20% ")',
546
-
547
- A25: '=COUNTIF(A1:A8, "<a")' , B25: '=COUNTIF(B1:B8, "<a")',
548
- A26: '=COUNTIF(A1:A8, ">a")' , B26: '=COUNTIF(B1:B8, ">a")',
549
-
550
- A28: '=COUNTIF(A1:A8, "<20A")' , B28: '=COUNTIF(B1:B8, "<20A")',
551
- A29: '=COUNTIF(A1:A8, ">20A")' , B29: '=COUNTIF(B1:B8, ">20A")',
552
-
553
- A31: '=COUNTIF(A1:A8, "<2*")' , B31: '=COUNTIF(B1:B8, "<2*")',
554
- A32: '=COUNTIF(A1:A8, ">2*")' , B32: '=COUNTIF(B1:B8, ">2*")',
555
-
556
- A34: '=COUNTIF(A1:A8, "<2?")' , B34: '=COUNTIF(B1:B8, "<2?")',
557
- A35: '=COUNTIF(A1:A8, ">2?")' , B35: '=COUNTIF(B1:B8, ">2?")',
558
-
559
- A37: '=COUNTIF(A1:A8, "<>20")' , B37: '=COUNTIF(B1:B8, "<>20")',
560
- };
561
-
562
- const gridResult = evaluateGrid(grid);
563
-
564
- expect(gridResult.A10).toBe(1); expect(gridResult.B10).toBe(1);
565
- expect(gridResult.A11).toBe(1); expect(gridResult.B11).toBe(1);
566
- expect(gridResult.A12).toBe(1); expect(gridResult.B12).toBe(1);
567
-
568
- expect(gridResult.A14).toBe(0); expect(gridResult.B14).toBe(2);
569
-
570
- expect(gridResult.A16).toBe(5); expect(gridResult.B16).toBe(0);
571
- expect(gridResult.A17).toBe(2); expect(gridResult.B17).toBe(0);
572
-
573
- expect(gridResult.A19).toBe(5); expect(gridResult.B19).toBe(0);
574
- expect(gridResult.A20).toBe(2); expect(gridResult.B20).toBe(0);
575
-
576
- expect(gridResult.A22).toBe(0); expect(gridResult.B22).toBe(0);
577
- expect(gridResult.A23).toBe(8); expect(gridResult.B23).toBe(0);
578
-
579
- expect(gridResult.A25).toBe(0); expect(gridResult.B25).toBe(8);
580
- expect(gridResult.A26).toBe(0); expect(gridResult.B26).toBe(0);
581
-
582
- expect(gridResult.A28).toBe(0); expect(gridResult.B28).toBe(4);
583
- expect(gridResult.A29).toBe(0); expect(gridResult.B29).toBe(4);
584
-
585
- expect(gridResult.A31).toBe(0); expect(gridResult.B31).toBe(3);
586
- expect(gridResult.A32).toBe(0); expect(gridResult.B32).toBe(5);
587
-
588
- expect(gridResult.A34).toBe(0); expect(gridResult.B34).toBe(4); // @compatibility: on google sheet, return 3
589
- expect(gridResult.A35).toBe(0); expect(gridResult.B35).toBe(4); // @compatibility: on google sheet, return 5
590
-
591
- expect(gridResult.A37).toBe(7); expect(gridResult.B37).toBe(8);
592
- });
593
-
594
- test("COUNTIF: operator tests on type boolean", () => {
595
- expect(evaluateCell("A41", { A41: "=COUNTIF(A39, TRUE)", A39: "TRUE" })).toBe(1);
596
- expect(evaluateCell("A42", { A42: '=COUNTIF(A39, "TRUE")', A39: "TRUE" })).toBe(1);
597
- expect(evaluateCell("A43", { A43: '=COUNTIF(A39, "=TRUE")', A39: "TRUE" })).toBe(1);
598
-
599
- expect(evaluateCell("B41", { B41: "=COUNTIF(B39, TRUE)", B39: '="TRUE"' })).toBe(0);
600
- expect(evaluateCell("B42", { B42: '=COUNTIF(B39, "TRUE")', B39: '="TRUE"' })).toBe(0);
601
- expect(evaluateCell("B43", { B43: '=COUNTIF(B39, "=TRUE")', B39: '="TRUE"' })).toBe(0);
602
- });
603
-
604
- test("COUNTIF: operator tests on criterion expression", () => {
605
- const grid1 = {
606
- A45: "abc",
607
- A46: "abd",
608
- A47: "bcd",
609
- A48: "b~e",
610
- A49: "x*y",
611
- A50: "x?z",
612
- A51: "zZz",
613
- A52: "zzz",
614
-
615
- C45: '=COUNTIF(A45:A52, "abd")',
616
- C46: '=COUNTIF(A45:A52, "ab")',
617
- C47: '=COUNTIF(A45:A52, "=abd")',
618
- C48: '=COUNTIF(A45:A52, "<abd")',
619
- C49: '=COUNTIF(A45:A52, ">abd")',
620
- C50: '=COUNTIF(A45:A52, "<>abd")',
621
- C51: '=COUNTIF(A45:A52, "><abd")',
622
-
623
- D45: '=COUNTIF(A45:A52, "ab*")',
624
- D46: '=COUNTIF(A45:A52, "a*")',
625
- D47: '=COUNTIF(A45:A52, "a*c")',
626
- D48: '=COUNTIF(A45:A52, "a?")',
627
- D49: '=COUNTIF(A45:A52, "a?c")',
628
- D50: '=COUNTIF(A45:A52, "zzz")',
629
- D51: '=COUNTIF(A45:A52, "x*z")',
630
- D52: '=COUNTIF(A45:A52, "x~*z")',
631
- D53: '=COUNTIF(A45:A52, "x~*y")',
632
- D54: '=COUNTIF(A45:A52, "x?y")',
633
- D55: '=COUNTIF(A45:A52, "x~?y")',
634
- D56: '=COUNTIF(A45:A52, "x~?z")',
635
- D57: '=COUNTIF(A45:A52, "b~e")',
636
- };
637
-
638
- const grid1Result = evaluateGrid(grid1);
639
-
640
- expect(grid1Result.C45).toBe(1);
641
- expect(grid1Result.C46).toBe(0);
642
- expect(grid1Result.C47).toBe(1);
643
- expect(grid1Result.C48).toBe(1);
644
- expect(grid1Result.C49).toBe(6);
645
- expect(grid1Result.C50).toBe(7);
646
- expect(grid1Result.C51).toBe(8);
647
-
648
- expect(grid1Result.D45).toBe(2);
649
- expect(grid1Result.D46).toBe(2);
650
- expect(grid1Result.D47).toBe(1);
651
- expect(grid1Result.D48).toBe(0);
652
- expect(grid1Result.D49).toBe(1);
653
- expect(grid1Result.D50).toBe(2);
654
- expect(grid1Result.D51).toBe(1);
655
- expect(grid1Result.D52).toBe(0);
656
- expect(grid1Result.D53).toBe(1);
657
- expect(grid1Result.D54).toBe(1);
658
- expect(grid1Result.D55).toBe(0);
659
- expect(grid1Result.D56).toBe(1);
660
- expect(grid1Result.D57).toBe(1);
661
-
662
- const grid2 = {
663
- A59: "abc",
664
- A60: "abd",
665
- A61: "abe",
666
- A62: "bcd",
667
- A63: "bce",
668
- A64: "b$f",
669
- A65: "b",
670
- A66: "cdf",
671
- A67: "cdg",
672
-
673
- C59: '=COUNTIF(A59:A67, "> bcf")',
674
- C60: '=COUNTIF(A59:A67, ">bcf")',
675
- C61: '=COUNTIF(A59:A67, ">b?f")',
676
- C62: '=COUNTIF(A59:A67, ">c*")',
677
-
678
- E59: '=COUNTIF(A59:A67, ">b?e")',
679
- E60: '=COUNTIF(A59:A67, "<b?e")',
680
-
681
- E62: '=COUNTIF(A59:A67, ">b*e")',
682
- E63: '=COUNTIF(A59:A67, "<b*e")',
683
-
684
- E65: '=COUNTIF(A59:A67, ">b*")',
685
- E66: '=COUNTIF(A59:A67, "<b*")',
686
-
687
- F65: '=COUNTIF(A59:A67, ">b")',
688
- F66: '=COUNTIF(A59:A67, "<b")',
689
- };
690
-
691
- const grid2Result = evaluateGrid(grid2);
692
-
693
- expect(grid2Result.C59).toBe(9);
694
- expect(grid2Result.C60).toBe(2);
695
- expect(grid2Result.C61).toBe(4);
696
- expect(grid2Result.C62).toBe(2);
697
-
698
- expect(grid2Result.E59).toBe(4);
699
- expect(grid2Result.E60).toBe(5);
700
-
701
- expect(grid2Result.E62).toBe(4);
702
- expect(grid2Result.E63).toBe(5);
703
-
704
- expect(grid2Result.E65).toBe(4);
705
- expect(grid2Result.E66).toBe(5);
706
-
707
- expect(grid2Result.F65).toBe(5);
708
- expect(grid2Result.F66).toBe(3);
709
-
710
- const grid3 = {
711
- A69: "b$f",
712
-
713
- C69: '=COUNTIF(A69, ">b?f")',
714
- C70: '=COUNTIF(A69, ">b*f")',
715
- C71: '=COUNTIF(A69, ">b#f")',
716
- C72: '=COUNTIF(A69, ">b&f")',
717
-
718
- D69: '=COUNTIF(A69, "<b?f")',
719
- D70: '=COUNTIF(A69, "<b*f")',
720
- D71: '=COUNTIF(A69, "<b#f")',
721
- D72: '=COUNTIF(A69, "<b&f")',
722
- };
723
-
724
- const grid3Result = evaluateGrid(grid3);
725
-
726
- expect(grid3Result.C69).toBe(0);
727
- expect(grid3Result.C70).toBe(0);
728
- expect(grid3Result.C71).toBe(1);
729
- expect(grid3Result.C72).toBe(0);
730
-
731
- expect(grid3Result.D69).toBe(1);
732
- expect(grid3Result.D70).toBe(1);
733
- expect(grid3Result.D71).toBe(0);
734
- expect(grid3Result.D72).toBe(1);
735
-
736
- const grid4 = {
737
- A74: "ab",
738
- A75: "abc",
739
- A76: "abcd",
740
- A77: "abcde",
741
-
742
- C74: '=COUNTIF(A74:A77, "a")',
743
- C75: '=COUNTIF(A74:A77, "ab")',
744
-
745
- E74: '=COUNTIF(A74:A77, "*")',
746
- E75: '=COUNTIF(A74:A77, "a*")',
747
- E76: '=COUNTIF(A74:A77, "ab*")',
748
- E77: '=COUNTIF(A74:A77, "abc*")',
749
-
750
- G74: '=COUNTIF(A74:A77, "?")',
751
- G75: '=COUNTIF(A74:A77, "a?")',
752
- G76: '=COUNTIF(A74:A77, "ab?")',
753
- G77: '=COUNTIF(A74:A77, "abc?")',
754
- };
755
-
756
- const grid4Result = evaluateGrid(grid4);
757
-
758
- expect(grid4Result.C74).toBe(0);
759
- expect(grid4Result.C75).toBe(1);
760
-
761
- expect(grid4Result.E74).toBe(4);
762
- expect(grid4Result.E75).toBe(4);
763
- expect(grid4Result.E76).toBe(4);
764
- expect(grid4Result.E77).toBe(3);
765
-
766
- expect(grid4Result.G74).toBe(0);
767
- expect(grid4Result.G75).toBe(1);
768
- expect(grid4Result.G76).toBe(1);
769
- expect(grid4Result.G77).toBe(1);
770
-
771
- const grid5 = {
772
- J73: "aslnlsngj",
773
-
774
- J74: '=COUNTIF(J73, "a*d")',
775
- J75: '=COUNTIF(J73, "a*j")',
776
- J76: '=COUNTIF(J73, "a*g")',
777
- J77: '=COUNTIF(J73, "a*gj")',
778
- J78: '=COUNTIF(J73, "a*nl*")',
779
- J79: '=COUNTIF(J73, "a*nl*?n*j")',
780
-
781
- J80: '=COUNTIF(J73, "<>*")',
782
- J81: '=COUNTIF(J73, "<>a*")',
783
- J82: '=COUNTIF(J73, "<>a*b")',
784
- };
785
-
786
- const grid5Result = evaluateGrid(grid5);
787
-
788
- expect(grid5Result.J74).toBe(0);
789
- expect(grid5Result.J75).toBe(1);
790
- expect(grid5Result.J76).toBe(0);
791
- expect(grid5Result.J77).toBe(1);
792
- expect(grid5Result.J78).toBe(1);
793
- expect(grid5Result.J79).toBe(1);
794
-
795
- expect(grid5Result.J80).toBe(0);
796
- expect(grid5Result.J81).toBe(0);
797
- expect(grid5Result.J82).toBe(1);
798
- });
799
-
800
- //----------------------------------------------------------------------------
801
- // COUNTIFS
802
- //----------------------------------------------------------------------------
803
-
804
- test("COUNTIFS: functional tests on range", () => {
805
- // prettier-ignore
806
- const grid = {
807
- A1: "Jim" , B1: "MN", C1: "100",
808
- A2: "Sarah", B2: "CA", C2: "125",
809
- A3: "Jane" , B3: "GA", C3: "200",
810
- A4: "Steve", B4: "CA", C4: "50" ,
811
- A5: "Jim" , B5: "WY", C5: "75" ,
812
- A6: "Joan" , B6: "WA", C6: "150",
813
- A7: "Jane" , B7: "GA", C7: "200",
814
- A8: "Jim" , B8: "WY", C8: "50" ,
815
-
816
- D1: '=COUNTIFS(A1:A8, "JIM", B1:B8, "??" , C1:C8, ">=100")',
817
- D2: '=COUNTIFS(A1:A8, "JIM", B1:B8, "??" , C1:C8, ">=50")',
818
- D3: '=COUNTIFS(A1:A8, "JIM", B1:B8, "WY" , C1:C8, ">=50")',
819
- D4: '=COUNTIFS(A1:A8, "J*" , B1:B8, "W?" , C1:C8, ">=50")',
820
- D5: '=COUNTIFS(A1:A8, "J*" , B1:B8, "?A" , C1:C8, ">=50")',
821
- D6: '=COUNTIFS(A1:A8, "J*" , B1:B8, "?A" , C1:C8, "<>200")',
822
- D7: '=COUNTIFS(A1:A8, "J*" , B1:B8, "*" , C1:C8, "50")',
823
- D8: '=COUNTIFS(A1:A8, "*a*", B1:B8, "*a*", C1:C8, ">0")',
824
- };
825
-
826
- const gridResult = evaluateGrid(grid);
827
- expect(gridResult.D1).toBe(1);
828
- expect(gridResult.D2).toBe(3);
829
- expect(gridResult.D3).toBe(2);
830
- expect(gridResult.D4).toBe(3);
831
- expect(gridResult.D5).toBe(3);
832
- expect(gridResult.D6).toBe(1);
833
- expect(gridResult.D7).toBe(1);
834
- expect(gridResult.D8).toBe(4);
835
- });
836
-
837
- //----------------------------------------------------------------------------
838
- // COUNTUNIQUE
839
- //----------------------------------------------------------------------------
840
-
841
- test("COUNTUNIQUE: functional tests on simple arguments", () => {
842
- expect(evaluateCell("A1", { A1: "=countunique()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
843
- expect(evaluateCell("A1", { A1: "=countunique(,)" })).toBe(0);
844
- expect(evaluateCell("A1", { A1: "=countunique(0)" })).toBe(1);
845
- expect(evaluateCell("A1", { A1: "=countunique(1, 2, 3, 1, 2)" })).toBe(3);
846
- expect(evaluateCell("A1", { A1: "=countunique(1, , 2, , 3)" })).toBe(3);
847
- expect(evaluateCell("A1", { A1: "=countunique(1.5, 1.4)" })).toBe(2);
848
- expect(evaluateCell("A1", { A1: '=countunique("Jean Saisrien", "Jean Prendnote")' })).toBe(2);
849
- expect(evaluateCell("A1", { A1: '=countunique("")' })).toBe(0);
850
- expect(evaluateCell("A1", { A1: '=countunique(" ")' })).toBe(1);
851
- expect(evaluateCell("A1", { A1: '=countunique("2", "-2")' })).toBe(2);
852
- expect(evaluateCell("A1", { A1: '=countunique("2", "")' })).toBe(1);
853
- expect(evaluateCell("A1", { A1: '=countunique("2", " ")' })).toBe(2);
854
- expect(evaluateCell("A1", { A1: "=countunique(TRUE, FALSE)" })).toBe(2);
855
- expect(evaluateCell("A1", { A1: '=countunique(1, "1", TRUE)' })).toBe(3);
856
- });
857
-
858
- test("COUNTUNIQUE: functional tests on cell arguments", () => {
859
- expect(evaluateCell("A1", { A1: "=countunique(A2)", A2: "" })).toBe(0);
860
- expect(evaluateCell("A1", { A1: "=countunique(A2)", A2: " " })).toBe(1);
861
- expect(evaluateCell("A1", { A1: "=countunique(A2)", A2: "," })).toBe(1);
862
- expect(evaluateCell("A1", { A1: "=countunique(A2)", A2: "0" })).toBe(1);
863
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "1", A3: "2" })).toBe(2);
864
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3, A4)", A2: "1", A3: "", A4: "1" })).toBe(
865
- 1
866
- );
867
- expect(
868
- evaluateCell("A1", {
869
- A1: "=countunique(A2, A3, A4)",
870
- A2: "1.4",
871
- A3: "-1",
872
- A4: "Jean Peuxplus",
873
- })
874
- ).toBe(3);
875
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "", A3: "" })).toBe(0);
876
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: " ", A3: "" })).toBe(1);
877
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "", A3: '=" "' })).toBe(1);
878
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: " ", A3: '=" "' })).toBe(1);
879
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: " ", A3: '=" "' })).toBe(2);
880
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: " ", A3: '=" "' })).toBe(2);
881
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "42", A3: "42" })).toBe(1);
882
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "42", A3: '"42"' })).toBe(2);
883
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "42", A3: "=42" })).toBe(1);
884
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "42", A3: '="42"' })).toBe(2);
885
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: '"42"', A3: '"42"' })).toBe(1);
886
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: '"42"', A3: "=42" })).toBe(2);
887
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: '"42"', A3: '="42"' })).toBe(2);
888
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "=42", A3: "=42" })).toBe(1);
889
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: "=42", A3: '="42"' })).toBe(2);
890
- expect(evaluateCell("A1", { A1: "=countunique(A2, A3)", A2: '="42"', A3: '="42"' })).toBe(1);
891
- });
892
-
893
- test("COUNTUNIQUE: functional tests on simple and cell arguments", () => {
894
- expect(evaluateCell("A1", { A1: "=countunique(A2,)", A2: "" })).toBe(0);
895
- expect(evaluateCell("A1", { A1: "=countunique(A2,)", A2: " " })).toBe(1);
896
- expect(evaluateCell("A1", { A1: "=countunique(A2,)", A2: '=""' })).toBe(0);
897
- expect(evaluateCell("A1", { A1: "=countunique(A2,)", A2: '=" "' })).toBe(1);
898
- expect(evaluateCell("A1", { A1: '=countunique(A2, "")', A2: "" })).toBe(0);
899
- expect(evaluateCell("A1", { A1: '=countunique(A2, "")', A2: " " })).toBe(1);
900
- expect(evaluateCell("A1", { A1: '=countunique(A2, "")', A2: '=""' })).toBe(0);
901
- expect(evaluateCell("A1", { A1: '=countunique(A2, "")', A2: '=" "' })).toBe(1);
902
- expect(evaluateCell("A1", { A1: '=countunique(A2, " ")', A2: "" })).toBe(1);
903
- expect(evaluateCell("A1", { A1: '=countunique(A2, " ")', A2: " " })).toBe(1);
904
- expect(evaluateCell("A1", { A1: '=countunique(A2, " ")', A2: '=""' })).toBe(1);
905
- expect(evaluateCell("A1", { A1: '=countunique(A2, " ")', A2: '=" "' })).toBe(1);
906
- expect(evaluateCell("A1", { A1: '=countunique(42, "42")' })).toBe(2);
907
- expect(evaluateCell("A1", { A1: "=countunique(A2, 42)", A2: "42" })).toBe(1);
908
- expect(evaluateCell("A1", { A1: "=countunique(A2, 42)", A2: '"42"' })).toBe(2);
909
- expect(evaluateCell("A1", { A1: "=countunique(A2, 42)", A2: "=42" })).toBe(1);
910
- expect(evaluateCell("A1", { A1: "=countunique(A2, 42)", A2: '="42"' })).toBe(2);
911
- expect(evaluateCell("A1", { A1: '=countunique(A2, "42")', A2: "42" })).toBe(2);
912
- expect(evaluateCell("A1", { A1: '=countunique(A2, "42")', A2: '"42"' })).toBe(2);
913
- expect(evaluateCell("A1", { A1: '=countunique(A2, "42")', A2: "=42" })).toBe(2);
914
- expect(evaluateCell("A1", { A1: '=countunique(A2, "42")', A2: '="42"' })).toBe(1);
915
- expect(evaluateCell("A1", { A1: "=countunique(A2, TRUE)", A2: "1" })).toBe(2);
916
- expect(evaluateCell("A1", { A1: "=countunique(A2, TRUE)", A2: '"1"' })).toBe(2);
917
- expect(evaluateCell("A1", { A1: "=countunique(A2, TRUE)", A2: "=1" })).toBe(2);
918
- expect(evaluateCell("A1", { A1: "=countunique(A2, TRUE)", A2: '="1"' })).toBe(2);
919
- });
920
-
921
- test("COUNTUNIQUE: functional tests on range arguments", () => {
922
- const grid = {
923
- A1: "=COUNTUNIQUE(B2:D3,B4:D4,E2:E3,E4)",
924
-
925
- A2: "=COUNTUNIQUE(B2:E2)",
926
- A3: "=COUNTUNIQUE(B3:E3)",
927
- A4: "=COUNTUNIQUE(B4:E4)",
928
-
929
- B1: "=COUNTUNIQUE(B2:B4)",
930
- C1: "=COUNTUNIQUE(C2:C4)",
931
- D1: "=COUNTUNIQUE(D2:D4)",
932
- E1: "=COUNTUNIQUE(E2:E4)",
933
-
934
- B2: "=3",
935
- C2: "3",
936
- D2: '"3"',
937
- E2: '="3"',
938
-
939
- B3: '=" "',
940
- C3: "0",
941
- D3: "Jean Registre",
942
- E3: '"Jean Titouplin"',
943
-
944
- B4: " ",
945
- C4: '""',
946
- D4: '=""',
947
- E4: '" "',
948
- };
949
-
950
- const gridResult = evaluateGrid(grid);
951
- expect(gridResult.A1).toBe(9);
952
- expect(gridResult.A2).toBe(3);
953
- expect(gridResult.A3).toBe(4);
954
- expect(gridResult.A4).toBe(3);
955
- expect(gridResult.B1).toBe(2);
956
- expect(gridResult.C1).toBe(3);
957
- expect(gridResult.D1).toBe(2);
958
- expect(gridResult.E1).toBe(3);
959
- });
960
-
961
- //----------------------------------------------------------------------------
962
- // COUNTUNIQUEIFS
963
- //----------------------------------------------------------------------------
964
-
965
- test("COUNTUNIQUEIFS: functional tests on range", () => {
966
- // prettier-ignore
967
- const grid = {
968
- A1: "car" , B1: "4" , C1: "14", D1: "Yes",
969
- A2: "toy" , B2: "28", C2: "30", D2: "Yes",
970
- A3: "shirt" , B3: "31", C3: "47", D3: "Yes",
971
- A4: "car" , B4: "12", C4: "0" , D4: "Yes",
972
- A5: "toy" , B5: "31", C5: "47", D5: "Yes",
973
- A6: "milk" , B6: "13", C6: "5" , D6: "No" ,
974
- A7: "butter", B7: "18", C7: "43", D7: "No" ,
975
- A8: "shirt" , B8: "24", C8: "7" , D8: "Yes",
976
- A9: "car" , B9: "44", C9: "28", D9: "No" ,
977
- A10: '=""' , B10: "22", C10: "23", D10: "No" ,
978
- B11: "9" , C11: "13", D11: "No" ,
979
-
980
- A12: '=COUNTUNIQUEIFS(A1:A11, B1:B11, ">20")',
981
- A13: '=COUNTUNIQUEIFS(A1:A11, B1:B11, ">20", C1:C11, "<30")',
982
- A14: '=COUNTUNIQUEIFS(A1:A11, D1:D11, "No")',
983
- };
984
-
985
- const gridResult = evaluateGrid(grid);
986
- expect(gridResult.A12).toBe(3);
987
- expect(gridResult.A13).toBe(2);
988
- expect(gridResult.A14).toBe(3);
989
- });
990
-
991
- //----------------------------------------------------------------------------
992
- // CSC
993
- //----------------------------------------------------------------------------
994
-
995
- test.each([
996
- ["=3*PI()/2", -1],
997
- ["=PI()/2", 1],
998
- ["=-PI()/2", -1],
999
- ["1", 1.188395106],
1000
- ["-2", -1.09975017],
1001
- ])("CSC(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1002
- expect(evaluateCell("A1", { A1: "=CSC(A2)", A2: a })).toBeCloseTo(expected, 9);
1003
- });
1004
-
1005
- test.each([["0"]])("CSC(%s) - ERROR: take 1 parameter(s), return an error", (a) => {
1006
- expect(evaluateCell("A1", { A1: "=CSC(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1007
- });
1008
-
1009
- //----------------------------------------------------------------------------
1010
- // CSCH
1011
- //----------------------------------------------------------------------------
1012
-
1013
- test.each([
1014
- ["1", 0.850918128],
1015
- ["-2", -0.275720565],
1016
- ["=LN(3)", 0.75],
1017
- ["=-LN(9)", -0.225],
1018
- ])("CSCH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1019
- expect(evaluateCell("A1", { A1: "=CSCH(A2)", A2: a })).toBeCloseTo(expected, 9);
1020
- });
1021
-
1022
- test.each([["0"]])("CSCH(%s) - ERROR: take 1 parameter(s), return an error", (a) => {
1023
- expect(evaluateCell("A1", { A1: "=CSCH(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1024
- });
1025
-
1026
- //----------------------------------------------------------------------------
1027
- // DECIMAL
1028
- //----------------------------------------------------------------------------
1029
-
1030
- test.each([
1031
- ["0", "2", 0],
1032
- ["0", "4", 0],
1033
- ["0", "36", 0],
1034
- ["1010", "2", 10],
1035
- ["1010", "4", 68],
1036
- ["1010", "36", 46692],
1037
- ["2020", "36", 93384],
1038
- ["3030", "4", 204],
1039
- ["-1010", "16", -4112], // @compatibility: return error on parameter 1 on google sheets
1040
- ["ABAB", "16", 43947],
1041
- ["ABAB", "36", 481187],
1042
- ["A1A1", "16", 41377],
1043
- ["a1a1", "16", 41377],
1044
- ["a1a1", "36", 468217],
1045
- ["-ABAB", "16", -43947], // @compatibility: return error on parameter 1 on google sheets
1046
- ["-ABAB", "36", -481187], // @compatibility: return error on parameter 1 on google sheets
1047
- ["zzzz", "36", 1679615],
1048
- ])("DECIMAL(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
1049
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: a, A3: b })).toBe(expected);
1050
- });
1051
-
1052
- test.each([
1053
- ["1010", "-1"],
1054
- ["1010", "0"],
1055
- ["1010", "0.1"],
1056
- ["1010", "1"],
1057
- ["1010", "37"],
1058
- ["-", "2"],
1059
- ["A-", "36"],
1060
- ["@ABAB", "36"],
1061
- ["AB AB", "36"],
1062
- ])("DECIMAL(%s, %s) - error: take 2 parameter(s), return error on parameter 2", (a, b) => {
1063
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1064
- });
1065
-
1066
- test.each([
1067
- ["0.1", "2"],
1068
- ["2020", "2"],
1069
- ["-ABAB", "2"],
1070
- ["-ABAB", "10"],
1071
- ["ZZZZ", "16"],
1072
- ["-", "36"],
1073
- ["A-", "36"],
1074
- ["@ABAB", "36"],
1075
- ["ABAB@", "36"],
1076
- ["ABAB.2", "36"],
1077
- ["ABAB.21@", "36"],
1078
- ["AB AB", "36"],
1079
- ])("DECIMAL(%s, %s) - error: take 2 parameter(s), return error on parameter 1", (a, b) => {
1080
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1081
- });
1082
-
1083
- test("DECIMAL: special value testing", () => {
1084
- expect(evaluateCell("A1", { A1: "=DECIMAL()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1085
- expect(evaluateCell("A1", { A1: "=DECIMAL( , )" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1086
- expect(evaluateCell("A1", { A1: "=DECIMAL(42, 12)" })).toBe(50);
1087
- expect(evaluateCell("A1", { A1: "=DECIMAL( , 12)" })).toBe(0);
1088
- expect(evaluateCell("A1", { A1: "=DECIMAL(42, )" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1089
- expect(evaluateCell("A1", { A1: "=DECIMAL(42, TRUE)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1090
- expect(evaluateCell("A1", { A1: "=DECIMAL(42, FALSE)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1091
- expect(evaluateCell("A1", { A1: "=DECIMAL(TRUE, 10)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1092
- expect(evaluateCell("A1", { A1: "=DECIMAL(FALSE, 10)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1093
-
1094
- expect(evaluateCell("A1", { A1: '=DECIMAL("" , "")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1095
- expect(evaluateCell("A1", { A1: '=DECIMAL("" , 12)' })).toBe(0);
1096
- expect(evaluateCell("A1", { A1: '=DECIMAL(" " , 12)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1097
- expect(evaluateCell("A1", { A1: '=DECIMAL("42", 12)' })).toBe(50);
1098
- expect(evaluateCell("A1", { A1: '=DECIMAL("42", "12")' })).toBe(50);
1099
- expect(evaluateCell("A1", { A1: '=DECIMAL("42", "")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1100
-
1101
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "", A3: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1102
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "42", A3: "12" })).toBe(50);
1103
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "", A3: "12" })).toBe(0);
1104
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "42", A3: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1105
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "42", A3: "TRUE" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1106
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "42", A3: "FALSE" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1107
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "42", A3: "FALSE" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1108
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "TRUE", A3: "10" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1109
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: "FALSE", A3: "10" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1110
-
1111
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: '"42"', A3: '"12"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1112
-
1113
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
1114
- expect(evaluateCell("A1", { A1: "=DECIMAL(A2, A3)", A2: '="42"', A3: '="36"' })).toBe(146);
1115
- });
1116
-
1117
- //----------------------------------------------------------------------------
1118
- // DEGREES
1119
- //----------------------------------------------------------------------------
1120
-
1121
- test.each([
1122
- ["-5", -286.4788975654116], // @compatibility: on google sheets return -286.47889756541(2) and not (16)
1123
- ["-3.14", -179.90874767107852], // @compatibility: on google sheets return -179.90874767107(9) and not (852)
1124
- ["0", 0],
1125
- ["3.14", 179.90874767107852], // @compatibility: on google sheets return 179.90874767107(9) and not (852)
1126
- ["5", 286.4788975654116], // @compatibility: on google sheets return 286.47889756541(2) and not (16)
1127
- ["=-PI()", -180],
1128
- ["=PI()", 180],
1129
- ["=PI() * 3", 540],
1130
- ["3.141592653589793", 180],
1131
- ["3.14159265358979", 179.99999999999983], // @compatibility: on google sheets return 180
1132
- ["3.1415926535897", 179.99999999999466], // @compatibility: on google sheets return 179.99999999999(5) and not (466)
1133
- ])("DEGREES(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1134
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: a })).toBe(expected);
1135
- });
1136
-
1137
- test("DEGREES: functional tests on simple arguments", () => {
1138
- expect(evaluateCell("A1", { A1: "=DEGREES()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1139
- expect(evaluateCell("A1", { A1: "=DEGREES(0)" })).toBe(0);
1140
- expect(evaluateCell("A1", { A1: "=DEGREES(PI())" })).toBe(180);
1141
- expect(evaluateCell("A1", { A1: "=DEGREES(TRUE)" })).toBeCloseTo(57.29577951, 8);
1142
- expect(evaluateCell("A1", { A1: "=DEGREES(FALSE)" })).toBe(0);
1143
-
1144
- expect(evaluateCell("A1", { A1: '=DEGREES("")' })).toBe(0);
1145
- expect(evaluateCell("A1", { A1: '=DEGREES(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1146
- expect(evaluateCell("A1", { A1: '=DEGREES("hello there")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1147
-
1148
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: "" })).toBe(0);
1149
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1150
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: "0" })).toBe(0);
1151
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: "=PI()" })).toBe(180);
1152
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: "TRUE" })).toBeCloseTo(57.29577951, 8);
1153
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: "FALSE" })).toBe(0);
1154
-
1155
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1156
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1157
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1158
-
1159
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: '=""' })).toBe(0);
1160
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1161
- expect(evaluateCell("A1", { A1: "=DEGREES(A2)", A2: '="0"' })).toBe(0);
1162
- });
1163
-
1164
- //----------------------------------------------------------------------------
1165
- // EXP
1166
- //----------------------------------------------------------------------------
1167
-
1168
- test.each([
1169
- ["1", Math.exp(1)],
1170
- ["=LN(1)", 1],
1171
- ["0", 1],
1172
- ["-1", 0.3678794412],
1173
- ["2", 7.389056099],
1174
- ])("EXP(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1175
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: a })).toBeCloseTo(expected, 9);
1176
- });
1177
-
1178
- test("EXP: special value testing", () => {
1179
- expect(evaluateCell("A1", { A1: "=EXP()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1180
- expect(evaluateCell("A1", { A1: "=EXP(TRUE)" })).toBeCloseTo(Math.exp(1), 9);
1181
- expect(evaluateCell("A1", { A1: "=EXP(FALSE)" })).toBeCloseTo(1, 9);
1182
-
1183
- expect(evaluateCell("A1", { A1: '=EXP("")' })).toBeCloseTo(1, 9);
1184
- expect(evaluateCell("A1", { A1: '=EXP(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1185
- expect(evaluateCell("A1", { A1: '=EXP("1")' })).toBeCloseTo(Math.exp(1), 9);
1186
-
1187
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: "" })).toBeCloseTo(1, 9);
1188
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1189
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: "1" })).toBeCloseTo(Math.exp(1), 9);
1190
-
1191
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1192
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1193
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: '"1"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1194
-
1195
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: '=""' })).toBeCloseTo(1, 9);
1196
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1197
- expect(evaluateCell("A1", { A1: "=EXP(A2)", A2: '="1"' })).toBeCloseTo(Math.exp(1), 9);
1198
- });
1199
-
1200
- //----------------------------------------------------------------------------
1201
- // FLOOR / FLOOR.MATH / FLOOR.PRECISE
1202
- //----------------------------------------------------------------------------
1203
-
1204
- test.each([
1205
- ["0", 0],
1206
- ["6", 6],
1207
- ["6.7", 6],
1208
- ["7.89", 7],
1209
- ["-6", -6],
1210
- ["-6.7", -7],
1211
- ["-7.89", -8],
1212
- ])("FLOOR FUNCTIONS(%s) - %s: take 1 parameters, return a number", (a, expected) => {
1213
- expect(evaluateCell("A1", { A1: "=FLOOR(A2)", A2: a })).toBe(expected);
1214
- expect(evaluateCell("A1", { A1: "=FLOOR.MATH(A2)", A2: a })).toBe(expected);
1215
- expect(evaluateCell("A1", { A1: "=FLOOR.PRECISE(A2)", A2: a })).toBe(expected);
1216
- });
1217
-
1218
- test.each([
1219
- ["0", "0", 0],
1220
- ["0", "0.1", 0],
1221
- ["0", "-4", 0],
1222
- ["6", "0", 0], // @compatibility on google sheets: concerning basic floor function, return error div by 0
1223
- ["6.7", "0", 0], // @compatibility on google sheets: concerning basic floor function, return error div by 0
1224
- ["-6", "0", 0], // @compatibility on google sheets: concerning basic floor function, return error div by 0
1225
- ["6", "0.1", 6],
1226
- ["-6", "0.1", -6],
1227
- ["6", "0.7", 5.6],
1228
- ["-6", "0.7", -6.3],
1229
- ["6.7", "0.2", 6.6],
1230
- ["-6.7", "0.2", -6.8],
1231
- ])("FLOOR FUNCTIONS(%s, %s) - %s: take 2 parameters, return a number", (a, b, expected) => {
1232
- expect(evaluateCell("A1", { A1: "=FLOOR(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected);
1233
- expect(evaluateCell("A1", { A1: "=FLOOR.MATH(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected);
1234
- expect(evaluateCell("A1", { A1: "=FLOOR.PRECISE(A2, A3)", A2: a, A3: b })).toBeCloseTo(
1235
- expected
1236
- );
1237
- });
1238
-
1239
- test.each([
1240
- ["0", "0.2", 0],
1241
- ["0", "-0.2", 0],
1242
- ["7.89", "0.2", 7.8],
1243
- ["7.89", "-0.2", 7.8],
1244
- ["-7.89", "0.2", -8],
1245
- ["-7.89", "-0.2", -8],
1246
- ])(
1247
- "FLOOR (MATH/PRECISE) FUNCTIONS(%s, %s) - %s: no effect with negative factor",
1248
- (a, b, expected) => {
1249
- expect(evaluateCell("A1", { A1: "=FLOOR.MATH(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected);
1250
- expect(evaluateCell("A1", { A1: "=FLOOR.PRECISE(A2, A3)", A2: a, A3: b })).toBeCloseTo(
1251
- expected
1252
- );
1253
- }
1254
- );
1255
-
1256
- test.each([
1257
- ["6", "-0.2"],
1258
- ["7.89", "-0.2"],
1259
- ])("FLOOR(%s, %s) - error: if value positive, factor can't be negative", (a, b) => {
1260
- expect(evaluateCell("A1", { A1: "=FLOOR(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1261
- });
1262
-
1263
- test.each([
1264
- // Concerning FLOOR function
1265
- // if "a" is negative and "b" is negative, rounds a number up (and not down)
1266
- // the nearest integer multiple of b
1267
- ["-7.89", "0.2", -8],
1268
- ["-7.89", "-0.2", -7.8],
1269
- ])("FLOOR(%s, %s) - %s: if factor negative, rouds number down", (a, b, expected) => {
1270
- expect(evaluateCell("A1", { A1: "=FLOOR(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected, 9);
1271
- });
1272
-
1273
- test.each([
1274
- // Concerning FLOOR.MATH function
1275
- // if "a" is negative and "c" different 0, rounds a number up (and not down)
1276
- // the nearest integer multiple of b
1277
- ["7.89", "0.2", "0", 7.8],
1278
- ["7.89", "0.2", "1", 7.8],
1279
- ["-7.89", "0.2", "0", -8],
1280
- ["-7.89", "0.2", "1", -7.8],
1281
- ["-7.89", "0.2", "2.2", -7.8],
1282
- ["-7.89", "0.2", "-2.2", -7.8],
1283
- ["-7.89", "-0.2", "0", -8],
1284
- ["-7.89", "-0.2", "1", -7.8],
1285
- ["-7.89", "-0.2", "2.2", -7.8],
1286
- ["-7.89", "-0.2", "-2.2", -7.8],
1287
- ])("FLOOR.MATH(%s, %s, %s) - %s: take 3 parameters, return a number", (a, b, c, expected) => {
1288
- expect(evaluateCell("A1", { A1: "=FLOOR.MATH(A2, A3, A4)", A2: a, A3: b, A4: c })).toBeCloseTo(
1289
- expected,
1290
- 9
1291
- );
1292
- });
1293
-
1294
- function evaluateFloorFunction(functionName: string): void {
1295
- expect(evaluateCell("A1", { A1: "=" + functionName + "()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1296
- expect(evaluateCell("A1", { A1: "=" + functionName + "( , )" })).toBeCloseTo(0, 9);
1297
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, 0.2)" })).toBeCloseTo(-8, 9);
1298
- expect(evaluateCell("A1", { A1: "=" + functionName + "( , 0.2)" })).toBeCloseTo(0, 9);
1299
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, )" })).toBeCloseTo(0, 9); // @compatibility: on google sheets, return -8
1300
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, TRUE)" })).toBeCloseTo(-8, 9);
1301
- expect(evaluateCell("A1", { A1: "=" + functionName + "(-7.89, FALSE)" })).toBeCloseTo(0, 9); // @compatibility on google sheets: concerning basic floor function, return error div by 0
1302
- expect(evaluateCell("A1", { A1: "=" + functionName + "(TRUE, 10)" })).toBeCloseTo(0, 9);
1303
- expect(evaluateCell("A1", { A1: "=" + functionName + "(FALSE, 10)" })).toBeCloseTo(0, 9);
1304
-
1305
- expect(evaluateCell("A1", { A1: "=" + functionName + '("" , "")' })).toBeCloseTo(0, 9);
1306
- expect(evaluateCell("A1", { A1: "=" + functionName + '(" " , " ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1307
- expect(evaluateCell("A1", { A1: "=" + functionName + '("-7.89", "0.2")' })).toBeCloseTo(-8, 9);
1308
-
1309
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "", A3: "" })).toBeCloseTo(
1310
- 0,
1311
- 9
1312
- );
1313
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: " ", A3: " " })).toBe(
1314
- "#ERROR"
1315
- ); // @compatibility: on google sheets, return #VALUE!
1316
- expect(
1317
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "0.2" })
1318
- ).toBeCloseTo(-8, 9);
1319
- expect(
1320
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "", A3: "0.2" })
1321
- ).toBeCloseTo(0, 9);
1322
- expect(
1323
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "" })
1324
- ).toBeCloseTo(0, 9); // @compatibility on google sheets: concerning basic floor function, return error div by 0
1325
- expect(
1326
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "TRUE" })
1327
- ).toBeCloseTo(-8, 9);
1328
- expect(
1329
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "-7.89", A3: "FALSE" })
1330
- ).toBeCloseTo(0, 9); // @compatibility on google sheets: concerning basic floor function, return error div by 0
1331
- expect(
1332
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "TRUE", A3: "10" })
1333
- ).toBeCloseTo(0, 9);
1334
- expect(
1335
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: "FALSE", A3: "10" })
1336
- ).toBeCloseTo(0, 9);
1337
-
1338
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '""', A3: '""' })).toBe(
1339
- "#ERROR"
1340
- ); // @compatibility: on google sheets, return #VALUE!
1341
- expect(evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '" "', A3: '" "' })).toBe(
1342
- "#ERROR"
1343
- ); // @compatibility: on google sheets, return #VALUE!
1344
- expect(
1345
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '"-7.89"', A3: '"0.2"' })
1346
- ).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1347
-
1348
- expect(
1349
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '=""', A3: '=""' })
1350
- ).toBeCloseTo(0, 9);
1351
- expect(
1352
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '=" "', A3: '=" "' })
1353
- ).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1354
- expect(
1355
- evaluateCell("A1", { A1: "=" + functionName + "(A2, A3)", A2: '="-7.89"', A3: '="0.2"' })
1356
- ).toBeCloseTo(-8, 9);
1357
- }
1358
-
1359
- test.each([["FLOOR"], ["FLOOR.MATH"], ["FLOOR.PRECISE"]])(
1360
- "%s: special value testing",
1361
- (functionName) => {
1362
- evaluateFloorFunction(functionName);
1363
- }
1364
- );
1365
-
1366
- //----------------------------------------------------------------------------
1367
- // ISEVEN
1368
- //----------------------------------------------------------------------------
1369
-
1370
- test.each([
1371
- ["-3", false],
1372
- ["-2.3", true],
1373
- ["-2", true],
1374
- ["0", true],
1375
- ["2", true],
1376
- ["2.3", true],
1377
- ["3", false],
1378
- ])("ISEVEN(%s) - %s: take 1 parameter(s), return a boolean", (a, expected) => {
1379
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: a })).toBe(expected);
1380
- });
1381
-
1382
- test("ISEVEN: functional tests on simple arguments", () => {
1383
- expect(evaluateCell("A1", { A1: "=ISEVEN()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1384
- expect(evaluateCell("A1", { A1: "=ISEVEN(0)" })).toBe(true);
1385
- expect(evaluateCell("A1", { A1: "=ISEVEN(1)" })).toBe(false);
1386
- expect(evaluateCell("A1", { A1: "=ISEVEN(TRUE)" })).toBe(false);
1387
- expect(evaluateCell("A1", { A1: "=ISEVEN(FALSE)" })).toBe(true);
1388
-
1389
- expect(evaluateCell("A1", { A1: '=ISEVEN("")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1390
- expect(evaluateCell("A1", { A1: '=ISEVEN(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1391
- expect(evaluateCell("A1", { A1: '=ISEVEN("hello there")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1392
-
1393
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: "" })).toBe(true);
1394
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1395
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: "0" })).toBe(true);
1396
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: "1" })).toBe(false);
1397
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: "TRUE" })).toBe(false);
1398
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: "FALSE" })).toBe(true);
1399
-
1400
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1401
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1402
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1403
-
1404
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: '=""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1405
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1406
- expect(evaluateCell("A1", { A1: "=ISEVEN(A2)", A2: '="0"' })).toBe(true);
1407
- });
1408
-
1409
- //----------------------------------------------------------------------------
1410
- // ISODD
1411
- //----------------------------------------------------------------------------
1412
-
1413
- test.each([
1414
- ["-3", true],
1415
- ["-2.2", false],
1416
- ["-2", false],
1417
- ["0", false],
1418
- ["2", false],
1419
- ["2.3", false],
1420
- ["3", true],
1421
- ])("ISODD(%s) - %s: take 1 parameter(s), return a boolean", (a, expected) => {
1422
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: a })).toBe(expected);
1423
- });
1424
-
1425
- test("ISODD: functional tests on simple arguments", () => {
1426
- expect(evaluateCell("A1", { A1: "=ISODD()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1427
- expect(evaluateCell("A1", { A1: "=ISODD(0)" })).toBe(false);
1428
- expect(evaluateCell("A1", { A1: "=ISODD(1)" })).toBe(true);
1429
- expect(evaluateCell("A1", { A1: "=ISODD(TRUE)" })).toBe(true);
1430
- expect(evaluateCell("A1", { A1: "=ISODD(FALSE)" })).toBe(false);
1431
-
1432
- expect(evaluateCell("A1", { A1: '=ISODD("")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1433
- expect(evaluateCell("A1", { A1: '=ISODD(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1434
- expect(evaluateCell("A1", { A1: '=ISODD("hello there")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1435
-
1436
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: "" })).toBe(false);
1437
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1438
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: "0" })).toBe(false);
1439
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: "1" })).toBe(true);
1440
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: "TRUE" })).toBe(true);
1441
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: "FALSE" })).toBe(false);
1442
-
1443
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1444
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1445
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1446
-
1447
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: '=""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1448
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1449
- expect(evaluateCell("A1", { A1: "=ISODD(A2)", A2: '="0"' })).toBe(false);
1450
- });
1451
-
1452
- //----------------------------------------------------------------------------
1453
- // LN
1454
- //----------------------------------------------------------------------------
1455
-
1456
- test.each([
1457
- ["1", 0],
1458
- ["=EXP(1)", 1],
1459
- ["2", 0.6931471806],
1460
- ["9", Math.log(3) + Math.log(3)],
1461
- ])("LN(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1462
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: a })).toBeCloseTo(expected, 9);
1463
- });
1464
-
1465
- test.each([["0"], ["-42"]])("LN(%s) - %s: take 1 parameter(s), return an error", (a) => {
1466
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1467
- });
1468
-
1469
- test("LN: special value testing", () => {
1470
- expect(evaluateCell("A1", { A1: "=LN()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1471
- expect(evaluateCell("A1", { A1: "=LN(TRUE)" })).toBeCloseTo(0, 9);
1472
- expect(evaluateCell("A1", { A1: "=LN(FALSE)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1473
-
1474
- expect(evaluateCell("A1", { A1: '=LN("")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1475
- expect(evaluateCell("A1", { A1: '=LN(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1476
- expect(evaluateCell("A1", { A1: '=LN("1")' })).toBeCloseTo(0, 9);
1477
-
1478
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1479
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1480
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: "1" })).toBeCloseTo(0, 9);
1481
-
1482
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1483
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1484
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: '"1"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1485
-
1486
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: '=""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1487
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1488
- expect(evaluateCell("A1", { A1: "=LN(A2)", A2: '="1"' })).toBeCloseTo(0, 9);
1489
- });
1490
-
1491
- //----------------------------------------------------------------------------
1492
- // MOD
1493
- //----------------------------------------------------------------------------
1494
-
1495
- test.each([
1496
- ["-42", "-10", -2],
1497
- ["-42", "-2.2", -0.2],
1498
- ["-42", "-2", 0],
1499
- ["-42", "2", 0],
1500
- ["-42", "2.2", 2],
1501
- ["-42", "10", 8],
1502
- ["0", "-10", 0],
1503
- ["0", "-2.2", 0],
1504
- ["0", "-2", 0],
1505
- ["0", "2", 0],
1506
- ["0", "2.2", 0],
1507
- ["0", "10", 0],
1508
- ["2.2", "-10", -7.8],
1509
- ["2.2", "-2.2", 0],
1510
- ["2.2", "-2", -1.8],
1511
- ["2.2", "2", 0.2],
1512
- ["2.2", "2.2", 0],
1513
- ["2.2", "10", 2.2],
1514
- ])("MOD(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
1515
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: a, A3: b })).toBeCloseTo(expected, 9);
1516
- });
1517
-
1518
- test.each([
1519
- ["-42", "0"],
1520
- ["0", "0"],
1521
- ["2.2", "0"],
1522
- ])("MOD(%s, %s) - error: take 2 parameter(s), return error on parameter 2", (a, b) => {
1523
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1524
- });
1525
-
1526
- test("MOD: special value testing", () => {
1527
- expect(evaluateCell("A1", { A1: "=MOD()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1528
- expect(evaluateCell("A1", { A1: "=MOD( , )" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1529
- expect(evaluateCell("A1", { A1: "=MOD(42, 12)" })).toBe(6);
1530
- expect(evaluateCell("A1", { A1: "=MOD( , 12)" })).toBe(0);
1531
- expect(evaluateCell("A1", { A1: "=MOD(42, )" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1532
- expect(evaluateCell("A1", { A1: "=MOD(42.42, TRUE)" })).toBeCloseTo(0.42, 9);
1533
- expect(evaluateCell("A1", { A1: "=MOD(42, FALSE)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1534
- expect(evaluateCell("A1", { A1: "=MOD(TRUE, 10)" })).toBe(1);
1535
- expect(evaluateCell("A1", { A1: "=MOD(FALSE, 10)" })).toBe(0);
1536
-
1537
- expect(evaluateCell("A1", { A1: '=MOD("" , "")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1538
- expect(evaluateCell("A1", { A1: '=MOD("" , 12)' })).toBe(0);
1539
- expect(evaluateCell("A1", { A1: '=MOD(" " , 12)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1540
- expect(evaluateCell("A1", { A1: '=MOD("42", 12)' })).toBe(6);
1541
- expect(evaluateCell("A1", { A1: '=MOD("42", "12")' })).toBe(6);
1542
- expect(evaluateCell("A1", { A1: '=MOD("42", "")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1543
-
1544
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "", A3: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1545
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "42", A3: "12" })).toBe(6);
1546
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "", A3: "12" })).toBe(0);
1547
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "42", A3: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1548
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "42.42", A3: "TRUE" })).toBeCloseTo(
1549
- 0.42,
1550
- 9
1551
- );
1552
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "42.42", A3: "FALSE" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
1553
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "TRUE", A3: "10" })).toBe(1);
1554
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: "FALSE", A3: "10" })).toBe(0);
1555
-
1556
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: '"42"', A3: '"12"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1557
-
1558
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
1559
- expect(evaluateCell("A1", { A1: "=MOD(A2, A3)", A2: '="42"', A3: '="36"' })).toBe(6);
1560
- });
1561
-
1562
- //----------------------------------------------------------------------------
1563
- // ODD
1564
- //----------------------------------------------------------------------------
1565
-
1566
- test.each([
1567
- ["-3.9", -5],
1568
- ["-3.1", -5],
1569
- ["-3", -3],
1570
- ["-2.9", -3],
1571
- ["-2.1", -3],
1572
- ["-2", -3],
1573
- ["0", 1],
1574
- ["2", 3],
1575
- ["2.1", 3],
1576
- ["2.9", 3],
1577
- ["3", 3],
1578
- ["3.1", 5],
1579
- ["3.9", 5],
1580
- ])("ODD(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1581
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: a })).toBe(expected);
1582
- });
1583
-
1584
- test("ODD: functional tests on simple arguments", () => {
1585
- expect(evaluateCell("A1", { A1: "=ODD()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1586
- expect(evaluateCell("A1", { A1: "=ODD(0)" })).toBe(1);
1587
- expect(evaluateCell("A1", { A1: "=ODD(2)" })).toBe(3);
1588
- expect(evaluateCell("A1", { A1: "=ODD(TRUE)" })).toBe(1);
1589
- expect(evaluateCell("A1", { A1: "=ODD(FALSE)" })).toBe(1);
1590
-
1591
- expect(evaluateCell("A1", { A1: '=ODD("")' })).toBe(1);
1592
- expect(evaluateCell("A1", { A1: '=ODD(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1593
- expect(evaluateCell("A1", { A1: '=ODD("hello there")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1594
-
1595
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: "" })).toBe(1);
1596
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1597
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: "0" })).toBe(1);
1598
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: "2" })).toBe(3);
1599
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: "TRUE" })).toBe(1);
1600
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: "FALSE" })).toBe(1);
1601
-
1602
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1603
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1604
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1605
-
1606
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: '=""' })).toBe(1);
1607
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1608
- expect(evaluateCell("A1", { A1: "=ODD(A2)", A2: '="42"' })).toBe(43);
1609
- });
1610
-
1611
- //----------------------------------------------------------------------------
1612
- // PI
1613
- //----------------------------------------------------------------------------
1614
-
1615
- test("PI", () => {
1616
- expect(evaluateCell("A1", { A1: "=PI()" })).toBeCloseTo(Math.PI, 9); // @compatibility: on google sheets return 3.14159265358979
1617
- });
1618
-
1619
- //----------------------------------------------------------------------------
1620
- // POWER
1621
- //----------------------------------------------------------------------------
1622
-
1623
- test.each([
1624
- ["0", "0", 1],
1625
- ["0", "0.5", 0],
1626
- ["4", "0", 1],
1627
- ["0", "4", 0],
1628
- ["4", "2", 16],
1629
- ["-4", "2", 16],
1630
- ["4", "3", 64],
1631
- ["-4", "3", -64],
1632
- ["4", "0.5", 2],
1633
- ["4", "-0.5", 0.5],
1634
- ["4", "-2", 0.0625],
1635
- ])("POWER(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
1636
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: a, A3: b })).toBe(expected);
1637
- });
1638
-
1639
- test.each([
1640
- ["-4", "0.5"],
1641
- ["-4", "1.5"],
1642
- ["-4", "0.2"],
1643
- ])("POWER(%s, %s) - error: take 2 parameter(s), return an error on parameter 2", (a, b) => {
1644
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1645
- });
1646
-
1647
- test("POWER: special value testing", () => {
1648
- expect(evaluateCell("A1", { A1: "=POWER()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1649
- expect(evaluateCell("A1", { A1: "=POWER( , )" })).toBe(1);
1650
- expect(evaluateCell("A1", { A1: "=POWER(42, 2)" })).toBe(1764);
1651
- expect(evaluateCell("A1", { A1: "=POWER( , 12)" })).toBe(0);
1652
- expect(evaluateCell("A1", { A1: "=POWER(42, )" })).toBe(1);
1653
- expect(evaluateCell("A1", { A1: "=POWER(42.42, TRUE)" })).toBe(42.42);
1654
- expect(evaluateCell("A1", { A1: "=POWER(42.42, FALSE)" })).toBe(1);
1655
- expect(evaluateCell("A1", { A1: "=POWER(TRUE, 10)" })).toBe(1);
1656
- expect(evaluateCell("A1", { A1: "=POWER(FALSE, 10)" })).toBe(0);
1657
-
1658
- expect(evaluateCell("A1", { A1: '=POWER("" , "")' })).toBe(1);
1659
- expect(evaluateCell("A1", { A1: '=POWER("" , 12)' })).toBe(0);
1660
- expect(evaluateCell("A1", { A1: '=POWER(" " , 12)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1661
- expect(evaluateCell("A1", { A1: '=POWER("42", 2)' })).toBe(1764);
1662
- expect(evaluateCell("A1", { A1: '=POWER("42", "2")' })).toBe(1764);
1663
- expect(evaluateCell("A1", { A1: '=POWER("42", "")' })).toBe(1);
1664
-
1665
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "", A3: "" })).toBe(1);
1666
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "42", A3: "2" })).toBe(1764);
1667
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "", A3: "12" })).toBe(0);
1668
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "42", A3: "" })).toBe(1);
1669
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "42.42", A3: "TRUE" })).toBe(42.42);
1670
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "42.42", A3: "FALSE" })).toBe(1);
1671
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "TRUE", A3: "10" })).toBe(1);
1672
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: "FALSE", A3: "10" })).toBe(0);
1673
-
1674
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: '"42"', A3: '"12"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1675
-
1676
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
1677
- expect(evaluateCell("A1", { A1: "=POWER(A2, A3)", A2: '="42"', A3: '="2"' })).toBe(1764);
1678
- });
1679
-
1680
- //----------------------------------------------------------------------------
1681
- // PRODUCT
1682
- //----------------------------------------------------------------------------
1683
-
1684
- test("PRODUCT: functional tests on simple arguments", () => {
1685
- expect(evaluateCell("A1", { A1: "=PRODUCT()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1686
- expect(evaluateCell("A1", { A1: "=PRODUCT(,)" })).toBe(0);
1687
- expect(evaluateCell("A1", { A1: "=PRODUCT(0)" })).toBe(0);
1688
- expect(evaluateCell("A1", { A1: "=PRODUCT(1, 2, 3, 1, 2)" })).toBe(12);
1689
- expect(evaluateCell("A1", { A1: "=PRODUCT(1, , 2, , 3)" })).toBe(6);
1690
- expect(evaluateCell("A1", { A1: "=PRODUCT(1.5, 1.4)" })).toBeCloseTo(2.1);
1691
- expect(evaluateCell("A1", { A1: '=PRODUCT("Jean Chante", "Jean Courage")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1692
- expect(evaluateCell("A1", { A1: '=PRODUCT("")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1693
- expect(evaluateCell("A1", { A1: '=PRODUCT(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1694
- expect(evaluateCell("A1", { A1: '=PRODUCT("2", "-2")' })).toBe(-4);
1695
- expect(evaluateCell("A1", { A1: '=PRODUCT("2", "")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1696
- expect(evaluateCell("A1", { A1: '=PRODUCT("2", " ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1697
- expect(evaluateCell("A1", { A1: "=PRODUCT(TRUE, FALSE)" })).toBe(0);
1698
- expect(evaluateCell("A1", { A1: '=PRODUCT(1, "1", TRUE)' })).toBe(1);
1699
- });
1700
-
1701
- test("PRODUCT: functional tests on cell arguments", () => {
1702
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2)", A2: "" })).toBe(0);
1703
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2)", A2: " " })).toBe(0);
1704
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2)", A2: "," })).toBe(0);
1705
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2)", A2: "0" })).toBe(0);
1706
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "1", A3: "2" })).toBe(2);
1707
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3, A4)", A2: "1", A3: "", A4: "1" })).toBe(1);
1708
- expect(
1709
- evaluateCell("A1", { A1: "=PRODUCT(A2, A3, A4)", A2: "1.5", A3: "-10", A4: "Jean Brasse" })
1710
- ).toBe(-15);
1711
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "", A3: "" })).toBe(0);
1712
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: " ", A3: "" })).toBe(0);
1713
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "", A3: '=" "' })).toBe(0);
1714
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: " ", A3: '=" "' })).toBe(0);
1715
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: " ", A3: '=" "' })).toBe(0);
1716
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: " ", A3: '=" "' })).toBe(0);
1717
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "42", A3: "42" })).toBe(1764);
1718
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "42", A3: '"42"' })).toBe(42);
1719
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "42", A3: "=42" })).toBe(1764);
1720
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "42", A3: '="42"' })).toBe(42);
1721
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: '"42"', A3: '"42"' })).toBe(0);
1722
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: '"42"', A3: "=42" })).toBe(42);
1723
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: '"42"', A3: '="42"' })).toBe(0);
1724
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "=42", A3: "=42" })).toBe(1764);
1725
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: "=42", A3: '="42"' })).toBe(42);
1726
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, A3)", A2: '="42"', A3: '="42"' })).toBe(0);
1727
- });
1728
-
1729
- test("PRODUCT: functional tests on simple and cell arguments", () => {
1730
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2,)", A2: "" })).toBe(0);
1731
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2,)", A2: " " })).toBe(0);
1732
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2,)", A2: '=""' })).toBe(0);
1733
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2,)", A2: '=" "' })).toBe(0);
1734
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "")', A2: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1735
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "")', A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1736
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "")', A2: '=""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1737
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "")', A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1738
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, " ")', A2: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1739
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, " ")', A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1740
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, " ")', A2: '=""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1741
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, " ")', A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1742
- expect(evaluateCell("A1", { A1: '=PRODUCT(42, "42")' })).toBe(1764);
1743
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, 42)", A2: "42" })).toBe(1764);
1744
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, 42)", A2: '"42"' })).toBe(42);
1745
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, 42)", A2: "=42" })).toBe(1764);
1746
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, 42)", A2: '="42"' })).toBe(42);
1747
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "42")', A2: "42" })).toBe(1764);
1748
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "42")', A2: '"42"' })).toBe(42);
1749
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "42")', A2: "=42" })).toBe(1764);
1750
- expect(evaluateCell("A1", { A1: '=PRODUCT(A2, "42")', A2: '="42"' })).toBe(42);
1751
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, TRUE)", A2: "1" })).toBe(1);
1752
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, TRUE)", A2: '"1"' })).toBe(1);
1753
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, TRUE)", A2: "=1" })).toBe(1);
1754
- expect(evaluateCell("A1", { A1: "=PRODUCT(A2, TRUE)", A2: '="1"' })).toBe(1);
1755
- });
1756
-
1757
- test("PRODUCT: functional tests on range arguments", () => {
1758
- const grid = {
1759
- A1: "=PRODUCT(B2:D3,B4:D4,E2:E3,E4)",
1760
-
1761
- A2: "=PRODUCT(B2:E2)",
1762
- A3: "=PRODUCT(B3:E3)",
1763
- A4: "=PRODUCT(B4:E4)",
1764
-
1765
- B1: "=PRODUCT(B2:B4)",
1766
- C1: "=PRODUCT(C2:C4)",
1767
- D1: "=PRODUCT(D2:D4)",
1768
- E1: "=PRODUCT(E2:E4)",
1769
-
1770
- B2: "=3",
1771
- C2: "3",
1772
- D2: '"3"',
1773
- E2: '="3"',
1774
-
1775
- B3: '=" "',
1776
- C3: "0",
1777
- D3: "Jean Jardindu",
1778
- E3: '"Jean Fortroche"',
1779
-
1780
- B4: " ",
1781
- C4: '""',
1782
- D4: '=""',
1783
- E4: '" "',
1784
- };
1785
-
1786
- const gridResult = evaluateGrid(grid);
1787
- expect(gridResult.A1).toBe(0);
1788
- expect(gridResult.A2).toBe(9);
1789
- expect(gridResult.A3).toBe(0);
1790
- expect(gridResult.A4).toBe(0);
1791
- expect(gridResult.B1).toBe(3);
1792
- expect(gridResult.C1).toBe(0);
1793
- expect(gridResult.D1).toBe(0);
1794
- expect(gridResult.E1).toBe(0);
1795
- });
1796
-
1797
- //----------------------------------------------------------------------------
1798
- // RAND
1799
- //----------------------------------------------------------------------------
1800
-
1801
- test("RAND(): return a number", () => {
1802
- expect(evaluateCell("A1", { A1: "=RAND()" })).toBeGreaterThanOrEqual(0);
1803
- expect(evaluateCell("A1", { A1: "=RAND()" })).toBeLessThan(1);
1804
- });
1805
-
1806
- //----------------------------------------------------------------------------
1807
- // RANDBETWEEN
1808
- //----------------------------------------------------------------------------
1809
-
1810
- test.each([
1811
- ["0", "0", 0],
1812
- ["42", "42", 42],
1813
- ["-42", "-42", -42],
1814
- ["1.1", "2", 2],
1815
- ])("RANDBETWEEN(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
1816
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: a, A3: b })).toBe(expected);
1817
- });
1818
-
1819
- test.each([
1820
- ["-42", "42"],
1821
- ["24", "42"],
1822
- ["-42", "-24"],
1823
- ])("RANDBETWEEN(%s, %s): take 2 parameter(s), return a number", (a, b) => {
1824
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: a, A3: b })).toBeGreaterThanOrEqual(
1825
- toNumber(a)
1826
- );
1827
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: a, A3: b })).toBeLessThanOrEqual(
1828
- toNumber(b)
1829
- );
1830
- });
1831
-
1832
- test.each([
1833
- ["1.1", "1.2"], // @compatibility: on google sheets, return 2
1834
- ["-24", "-42"],
1835
- ["42", "24"],
1836
- ])("RANDBETWEEN(%s, %s) - error: take 2 parameter(s), return an error", (a, b) => {
1837
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1838
- });
1839
-
1840
- test("RANDBETWEEN: special value testing", () => {
1841
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1842
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN( , )" })).toBe(0);
1843
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(2, 2)" })).toBe(2);
1844
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN( , 0)" })).toBe(0);
1845
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(42, )" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1846
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(42.42, TRUE)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1847
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(42.42, FALSE)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1848
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(TRUE, 1)" })).toBe(1);
1849
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(FALSE, 0)" })).toBe(0);
1850
-
1851
- expect(evaluateCell("A1", { A1: '=RANDBETWEEN("" , "")' })).toBe(0);
1852
- expect(evaluateCell("A1", { A1: '=RANDBETWEEN("" , 0)' })).toBe(0);
1853
- expect(evaluateCell("A1", { A1: '=RANDBETWEEN(" " , 12)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1854
- expect(evaluateCell("A1", { A1: '=RANDBETWEEN("42", 42)' })).toBe(42);
1855
- expect(evaluateCell("A1", { A1: '=RANDBETWEEN("42", "42")' })).toBe(42);
1856
- expect(evaluateCell("A1", { A1: '=RANDBETWEEN("42", "")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1857
-
1858
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "", A3: "" })).toBe(0);
1859
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "2", A3: "2" })).toBe(2);
1860
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "", A3: "0" })).toBe(0);
1861
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "42", A3: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!
1862
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "42.42", A3: "TRUE" })).toBe(
1863
- "#ERROR"
1864
- ); // @compatibility: on google sheets, return #NUM!
1865
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "42.42", A3: "FALSE" })).toBe(
1866
- "#ERROR"
1867
- ); // @compatibility: on google sheets, return #NUM!
1868
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "TRUE", A3: "1" })).toBe(1);
1869
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: "FALSE", A3: "0" })).toBe(0);
1870
-
1871
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: '"42"', A3: '"42"' })).toBe(
1872
- "#ERROR"
1873
- ); // @compatibility: on google sheets, return #VALUE!
1874
-
1875
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: '=""', A3: '="0"' })).toBe(0);
1876
- expect(evaluateCell("A1", { A1: "=RANDBETWEEN(A2, A3)", A2: '="42"', A3: '="42"' })).toBe(42);
1877
- });
1878
-
1879
- //----------------------------------------------------------------------------
1880
- // ROUND
1881
- //----------------------------------------------------------------------------
1882
-
1883
- test.each([
1884
- ["-1.6", -2],
1885
- ["-1.5", -2],
1886
- ["-1.4", -1],
1887
- ["0", 0],
1888
- ["1.4", 1],
1889
- ["1.5", 2],
1890
- ["1.6", 2],
1891
- ])("ROUND(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1892
- expect(evaluateCell("A1", { A1: "=ROUND(A2)", A2: a })).toBe(expected);
1893
- });
1894
-
1895
- test.each([
1896
- ["0.3", "2", 0.3],
1897
- ["0.34", "2", 0.34],
1898
- ["0.345", "2", 0.35],
1899
- ["-0.3", "2", -0.3],
1900
- ["-0.34", "2", -0.34],
1901
- ["-0.345", "2", -0.35],
1902
- ["0.345", "1.9", 0.3],
1903
- ["-0.345", "1.9", -0.3],
1904
- ["4", "-1", 0],
1905
- ["5", "-1", 10],
1906
- ["50", "-2", 100],
1907
- ["-5", "-1", -10],
1908
- ["-50", "-2", -100],
1909
- ["5", "-1.9", 10],
1910
- ["-5", "-1.9", -10],
1911
- ])("ROUND(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
1912
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: a, A3: b })).toBe(expected);
1913
- });
1914
-
1915
- test("ROUND: special value testing", () => {
1916
- expect(evaluateCell("A1", { A1: "=ROUND()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1917
- expect(evaluateCell("A1", { A1: "=ROUND( , )" })).toBe(0);
1918
- expect(evaluateCell("A1", { A1: "=ROUND(42, -1)" })).toBe(40);
1919
- expect(evaluateCell("A1", { A1: "=ROUND( , 42)" })).toBe(0);
1920
- expect(evaluateCell("A1", { A1: "=ROUND(42, )" })).toBe(42);
1921
- expect(evaluateCell("A1", { A1: "=ROUND(42.42, TRUE)" })).toBe(42.4);
1922
- expect(evaluateCell("A1", { A1: "=ROUND(42.42, FALSE)" })).toBe(42);
1923
- expect(evaluateCell("A1", { A1: "=ROUND(TRUE, 10)" })).toBe(1);
1924
- expect(evaluateCell("A1", { A1: "=ROUND(FALSE, 10)" })).toBe(0);
1925
-
1926
- expect(evaluateCell("A1", { A1: '=ROUND("" , "")' })).toBe(0);
1927
- expect(evaluateCell("A1", { A1: '=ROUND("" , 12)' })).toBe(0);
1928
- expect(evaluateCell("A1", { A1: '=ROUND(" " , 0)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1929
- expect(evaluateCell("A1", { A1: '=ROUND("42", -1)' })).toBe(40);
1930
- expect(evaluateCell("A1", { A1: '=ROUND("42", "-1")' })).toBe(40);
1931
- expect(evaluateCell("A1", { A1: '=ROUND("42", "")' })).toBe(42);
1932
-
1933
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "", A3: "" })).toBe(0);
1934
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "42", A3: "-1" })).toBe(40);
1935
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "", A3: "42" })).toBe(0);
1936
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "42", A3: "" })).toBe(42);
1937
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "42.42", A3: "TRUE" })).toBe(42.4);
1938
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "42.42", A3: "FALSE" })).toBe(42);
1939
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "TRUE", A3: "10" })).toBe(1);
1940
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: "FALSE", A3: "10" })).toBe(0);
1941
-
1942
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: '"42"', A3: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1943
-
1944
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
1945
- expect(evaluateCell("A1", { A1: "=ROUND(A2, A3)", A2: '="42"', A3: '="-1"' })).toBe(40);
1946
- });
1947
-
1948
- //----------------------------------------------------------------------------
1949
- // ROUNDDOWN
1950
- //----------------------------------------------------------------------------
1951
-
1952
- test.each([
1953
- ["-1.9", -1],
1954
- ["-1.5", -1],
1955
- ["-1.4", -1],
1956
- ["0", 0],
1957
- ["1.4", 1],
1958
- ["1.5", 1],
1959
- ["1.9", 1],
1960
- ])("ROUNDDOWN(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
1961
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2)", A2: a })).toBe(expected);
1962
- });
1963
-
1964
- test.each([
1965
- ["0.3", "2", 0.3],
1966
- ["0.34", "2", 0.34],
1967
- ["0.349", "2", 0.34],
1968
- ["-0.3", "2", -0.3],
1969
- ["-0.34", "2", -0.34],
1970
- ["-0.349", "2", -0.34],
1971
- ["0.349", "1.9", 0.3],
1972
- ["-0.349", "1.9", -0.3],
1973
- ["9", "-1", 0],
1974
- ["19", "-1", 10],
1975
- ["599", "-2", 500],
1976
- ["-19", "-1", -10],
1977
- ["-599", "-2", -500],
1978
- ["19", "-1.9", 10],
1979
- ["-19", "-1.9", -10],
1980
- ])("ROUNDDOWN(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
1981
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: a, A3: b })).toBe(expected);
1982
- });
1983
-
1984
- test("ROUNDDOWN: special value testing", () => {
1985
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
1986
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN( , )" })).toBe(0);
1987
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(49, -1)" })).toBe(40);
1988
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN( , 49)" })).toBe(0);
1989
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(49, )" })).toBe(49);
1990
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(49.49, TRUE)" })).toBe(49.4);
1991
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(49.49, FALSE)" })).toBe(49);
1992
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(TRUE, 10)" })).toBe(1);
1993
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(FALSE, 10)" })).toBe(0);
1994
-
1995
- expect(evaluateCell("A1", { A1: '=ROUNDDOWN("" , "")' })).toBe(0);
1996
- expect(evaluateCell("A1", { A1: '=ROUNDDOWN("" , 12)' })).toBe(0);
1997
- expect(evaluateCell("A1", { A1: '=ROUNDDOWN(" " , 0)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
1998
- expect(evaluateCell("A1", { A1: '=ROUNDDOWN("49", -1)' })).toBe(40);
1999
- expect(evaluateCell("A1", { A1: '=ROUNDDOWN("49", "-1")' })).toBe(40);
2000
- expect(evaluateCell("A1", { A1: '=ROUNDDOWN("49", "")' })).toBe(49);
2001
-
2002
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "", A3: "" })).toBe(0);
2003
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "49", A3: "-1" })).toBe(40);
2004
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "", A3: "49" })).toBe(0);
2005
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "49", A3: "" })).toBe(49);
2006
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "49.49", A3: "TRUE" })).toBe(49.4);
2007
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "49.49", A3: "FALSE" })).toBe(49);
2008
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "TRUE", A3: "10" })).toBe(1);
2009
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: "FALSE", A3: "10" })).toBe(0);
2010
-
2011
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: '"49"', A3: '"49"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2012
-
2013
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
2014
- expect(evaluateCell("A1", { A1: "=ROUNDDOWN(A2, A3)", A2: '="49"', A3: '="-1"' })).toBe(40);
2015
- });
2016
-
2017
- //----------------------------------------------------------------------------
2018
- // ROUNDUP
2019
- //----------------------------------------------------------------------------
2020
-
2021
- test.each([
2022
- ["-1.6", -2],
2023
- ["-1.5", -2],
2024
- ["-1.1", -2],
2025
- ["0", 0],
2026
- ["1.1", 2],
2027
- ["1.5", 2],
2028
- ["1.6", 2],
2029
- ])("ROUNDUP(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2030
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2)", A2: a })).toBe(expected);
2031
- });
2032
-
2033
- test.each([
2034
- ["0.3", "2", 0.3],
2035
- ["0.34", "2", 0.34],
2036
- ["0.341", "2", 0.35],
2037
- ["-0.3", "2", -0.3],
2038
- ["-0.34", "2", -0.34],
2039
- ["-0.341", "2", -0.35],
2040
- ["0.311", "1.9", 0.4],
2041
- ["-0.311", "1.9", -0.4],
2042
- ["1", "-1", 10],
2043
- ["11", "-1", 20],
2044
- ["1", "-2", 100],
2045
- ["-11", "-1", -20],
2046
- ["1", "-2", 100],
2047
- ["11", "-1.9", 20],
2048
- ["-11", "-1.9", -20],
2049
- ])("ROUNDUP(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
2050
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: a, A3: b })).toBe(expected);
2051
- });
2052
-
2053
- test("ROUNDUP: special value testing", () => {
2054
- expect(evaluateCell("A1", { A1: "=ROUNDUP()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
2055
- expect(evaluateCell("A1", { A1: "=ROUNDUP( , )" })).toBe(0);
2056
- expect(evaluateCell("A1", { A1: "=ROUNDUP(42, -1)" })).toBe(50);
2057
- expect(evaluateCell("A1", { A1: "=ROUNDUP( , 42)" })).toBe(0);
2058
- expect(evaluateCell("A1", { A1: "=ROUNDUP(42, )" })).toBe(42);
2059
- expect(evaluateCell("A1", { A1: "=ROUNDUP(42.42, TRUE)" })).toBe(42.5);
2060
- expect(evaluateCell("A1", { A1: "=ROUNDUP(42.42, FALSE)" })).toBe(43);
2061
- expect(evaluateCell("A1", { A1: "=ROUNDUP(TRUE, 10)" })).toBe(1);
2062
- expect(evaluateCell("A1", { A1: "=ROUNDUP(FALSE, 10)" })).toBe(0);
2063
-
2064
- expect(evaluateCell("A1", { A1: '=ROUNDUP("" , "")' })).toBe(0);
2065
- expect(evaluateCell("A1", { A1: '=ROUNDUP("" , 12)' })).toBe(0);
2066
- expect(evaluateCell("A1", { A1: '=ROUNDUP(" " , 0)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2067
- expect(evaluateCell("A1", { A1: '=ROUNDUP("42", -1)' })).toBe(50);
2068
- expect(evaluateCell("A1", { A1: '=ROUNDUP("42", "-1")' })).toBe(50);
2069
- expect(evaluateCell("A1", { A1: '=ROUNDUP("42", "")' })).toBe(42);
2070
-
2071
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "", A3: "" })).toBe(0);
2072
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "42", A3: "-1" })).toBe(50);
2073
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "", A3: "42" })).toBe(0);
2074
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "42", A3: "" })).toBe(42);
2075
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "42.42", A3: "TRUE" })).toBe(42.5);
2076
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "42.42", A3: "FALSE" })).toBe(43);
2077
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "TRUE", A3: "10" })).toBe(1);
2078
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: "FALSE", A3: "10" })).toBe(0);
2079
-
2080
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: '"42"', A3: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2081
-
2082
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
2083
- expect(evaluateCell("A1", { A1: "=ROUNDUP(A2, A3)", A2: '="42"', A3: '="-1"' })).toBe(50);
2084
- });
2085
-
2086
- //----------------------------------------------------------------------------
2087
- // SEC
2088
- //----------------------------------------------------------------------------
2089
-
2090
- test.each([
2091
- ["=PI()/3", 2],
2092
- ["1", 1.850815718],
2093
- ["-2", -2.402997962],
2094
- ["3", -1.010108666],
2095
- ["-4", -1.529885656],
2096
- ["0", 1],
2097
- ])("SEC(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2098
- expect(evaluateCell("A1", { A1: "=SEC(A2)", A2: a })).toBeCloseTo(expected, 9);
2099
- });
2100
-
2101
- //----------------------------------------------------------------------------
2102
- // SECH
2103
- //----------------------------------------------------------------------------
2104
-
2105
- test.each([
2106
- ["1", 0.648054274],
2107
- ["-1", 0.648054274],
2108
- ["0", 1],
2109
- ["=LN(2)", 0.8],
2110
- ["=-LN(3)", 0.6],
2111
- ])("SECH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2112
- expect(evaluateCell("A1", { A1: "=SECH(A2)", A2: a })).toBeCloseTo(expected, 9);
2113
- });
2114
-
2115
- //----------------------------------------------------------------------------
2116
- // SIN
2117
- //----------------------------------------------------------------------------
2118
-
2119
- test.each([
2120
- ["0", 0],
2121
- ["=PI()", 0],
2122
- ["=PI()*2", 0],
2123
- ["=PI()/2", 1],
2124
- ["=PI()/6", 0.5],
2125
- ["=-PI()/2", -1],
2126
- ])("SIN(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2127
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: a })).toBeCloseTo(expected, 9);
2128
- });
2129
-
2130
- test("SIN: special value testing", () => {
2131
- expect(evaluateCell("A1", { A1: "=SIN()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
2132
- expect(evaluateCell("A1", { A1: "=SIN(TRUE)" })).toBeCloseTo(0.841470984807897, 9);
2133
- expect(evaluateCell("A1", { A1: "=SIN(FALSE)" })).toBeCloseTo(0, 9);
2134
-
2135
- expect(evaluateCell("A1", { A1: '=SIN("")' })).toBeCloseTo(0, 9);
2136
- expect(evaluateCell("A1", { A1: '=SIN(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2137
- expect(evaluateCell("A1", { A1: '=SIN("0")' })).toBeCloseTo(0, 9);
2138
-
2139
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: "" })).toBeCloseTo(0, 9);
2140
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2141
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: "0" })).toBeCloseTo(0, 9);
2142
-
2143
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2144
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2145
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: '"0"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2146
-
2147
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: '=""' })).toBeCloseTo(0, 9);
2148
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2149
- expect(evaluateCell("A1", { A1: "=SIN(A2)", A2: '="0"' })).toBeCloseTo(0, 9);
2150
- });
2151
-
2152
- //----------------------------------------------------------------------------
2153
- // SINH
2154
- //----------------------------------------------------------------------------
2155
-
2156
- test.each([
2157
- ["1", 1.175201194],
2158
- ["-2", -3.626860408],
2159
- ["0", 0],
2160
- ["=LN(2)", 0.75],
2161
- ["=-LN(4)", -1.875],
2162
- ])("SINH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2163
- expect(evaluateCell("A1", { A1: "=SINH(A2)", A2: a })).toBeCloseTo(expected, 9);
2164
- });
2165
-
2166
- //----------------------------------------------------------------------------
2167
- // SQRT
2168
- //----------------------------------------------------------------------------
2169
-
2170
- test.each([
2171
- ["0", 0],
2172
- ["4", 2],
2173
- ["9", 3],
2174
- ])("SQRT(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2175
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: a })).toBe(expected);
2176
- });
2177
-
2178
- test.each([["-4"], ["-9"]])("SQRT(%s) - error: take 1 parameter(s), return an error ", (a) => {
2179
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: a })).toBe("#ERROR"); // @compatibility: on google sheets, return #NUM!!
2180
- });
2181
-
2182
- test("SQRT: special value testing", () => {
2183
- expect(evaluateCell("A1", { A1: "=SQRT()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
2184
- expect(evaluateCell("A1", { A1: "=SQRT(TRUE)" })).toBe(1);
2185
- expect(evaluateCell("A1", { A1: "=SQRT(FALSE)" })).toBe(0);
2186
-
2187
- expect(evaluateCell("A1", { A1: '=SQRT("")' })).toBe(0);
2188
- expect(evaluateCell("A1", { A1: '=SQRT(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2189
- expect(evaluateCell("A1", { A1: '=SQRT("49")' })).toBe(7);
2190
-
2191
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: "" })).toBe(0);
2192
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2193
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: "49" })).toBe(7);
2194
-
2195
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2196
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2197
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: '"0"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2198
-
2199
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: '=""' })).toBe(0);
2200
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2201
- expect(evaluateCell("A1", { A1: "=SQRT(A2)", A2: '="49"' })).toBe(7);
2202
- });
2203
-
2204
- //----------------------------------------------------------------------------
2205
- // SUM
2206
- //----------------------------------------------------------------------------
2207
-
2208
- test("SUM: functional tests on simple arguments", () => {
2209
- expect(evaluateCell("A1", { A1: "=SUM()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
2210
- expect(evaluateCell("A1", { A1: "=SUM(,)" })).toBe(0);
2211
- expect(evaluateCell("A1", { A1: "=SUM(0)" })).toBe(0);
2212
- expect(evaluateCell("A1", { A1: "=SUM(1, 2, 3, 1, 2)" })).toBe(9);
2213
- expect(evaluateCell("A1", { A1: "=SUM(1, , 2, , 3)" })).toBe(6);
2214
- expect(evaluateCell("A1", { A1: "=SUM(1.5, 1.4)" })).toBe(2.9);
2215
- expect(evaluateCell("A1", { A1: '=SUM("Jean Saigne", "Jean Tanrien")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2216
- expect(evaluateCell("A1", { A1: '=SUM("")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2217
- expect(evaluateCell("A1", { A1: '=SUM(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2218
- expect(evaluateCell("A1", { A1: '=SUM("2", "-2")' })).toBe(0);
2219
- expect(evaluateCell("A1", { A1: '=SUM("2", "")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2220
- expect(evaluateCell("A1", { A1: '=SUM("2", " ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2221
- expect(evaluateCell("A1", { A1: "=SUM(TRUE, FALSE)" })).toBe(1);
2222
- expect(evaluateCell("A1", { A1: '=SUM(1, "1", TRUE)' })).toBe(3);
2223
- expect(evaluateCell("A1", { A1: '=SUM(1, "10/10/10")' })).toBe(40462);
2224
- });
2225
-
2226
- test("SUM: functional tests on cell arguments", () => {
2227
- expect(evaluateCell("A1", { A1: "=SUM(A2)", A2: "" })).toBe(0);
2228
- expect(evaluateCell("A1", { A1: "=SUM(A2)", A2: " " })).toBe(0);
2229
- expect(evaluateCell("A1", { A1: "=SUM(A2)", A2: "," })).toBe(0);
2230
- expect(evaluateCell("A1", { A1: "=SUM(A2)", A2: "0" })).toBe(0);
2231
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "1", A3: "2" })).toBe(3);
2232
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3, A4)", A2: "1", A3: "", A4: "1" })).toBe(2);
2233
- expect(
2234
- evaluateCell("A1", { A1: "=SUM(A2, A3, A4)", A2: "1.5", A3: "-10", A4: "Jean Vier" })
2235
- ).toBe(-8.5);
2236
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "", A3: "" })).toBe(0);
2237
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: " ", A3: "" })).toBe(0);
2238
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "", A3: '=" "' })).toBe(0);
2239
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: " ", A3: '=" "' })).toBe(0);
2240
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: " ", A3: '=" "' })).toBe(0);
2241
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: " ", A3: '=" "' })).toBe(0);
2242
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "42", A3: "42" })).toBe(84);
2243
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "42", A3: '"42"' })).toBe(42);
2244
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "42", A3: "=42" })).toBe(84);
2245
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "42", A3: '="42"' })).toBe(42);
2246
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: '"42"', A3: '"42"' })).toBe(0);
2247
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: '"42"', A3: "=42" })).toBe(42);
2248
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: '"42"', A3: '="42"' })).toBe(0);
2249
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "=42", A3: "=42" })).toBe(84);
2250
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: "=42", A3: '="42"' })).toBe(42);
2251
- expect(evaluateCell("A1", { A1: "=SUM(A2, A3)", A2: '="42"', A3: '="42"' })).toBe(0);
2252
- });
2253
-
2254
- test("SUM: functional tests on simple and cell arguments", () => {
2255
- expect(evaluateCell("A1", { A1: "=SUM(A2,)", A2: "" })).toBe(0);
2256
- expect(evaluateCell("A1", { A1: "=SUM(A2,)", A2: " " })).toBe(0);
2257
- expect(evaluateCell("A1", { A1: "=SUM(A2,)", A2: '=""' })).toBe(0);
2258
- expect(evaluateCell("A1", { A1: "=SUM(A2,)", A2: '=" "' })).toBe(0);
2259
- expect(evaluateCell("A1", { A1: '=SUM(A2, "")', A2: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2260
- expect(evaluateCell("A1", { A1: '=SUM(A2, "")', A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2261
- expect(evaluateCell("A1", { A1: '=SUM(A2, "")', A2: '=""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2262
- expect(evaluateCell("A1", { A1: '=SUM(A2, "")', A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2263
- expect(evaluateCell("A1", { A1: '=SUM(A2, " ")', A2: "" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2264
- expect(evaluateCell("A1", { A1: '=SUM(A2, " ")', A2: " " })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2265
- expect(evaluateCell("A1", { A1: '=SUM(A2, " ")', A2: '=""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2266
- expect(evaluateCell("A1", { A1: '=SUM(A2, " ")', A2: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2267
- expect(evaluateCell("A1", { A1: '=SUM(42, "42")' })).toBe(84);
2268
- expect(evaluateCell("A1", { A1: "=SUM(A2, 42)", A2: "10/10/10" })).toBe(40503);
2269
- expect(evaluateCell("A1", { A1: "=SUM(A2, 42)", A2: "42" })).toBe(84);
2270
- expect(evaluateCell("A1", { A1: "=SUM(A2, 42)", A2: '"42"' })).toBe(42);
2271
- expect(evaluateCell("A1", { A1: "=SUM(A2, 42)", A2: "=42" })).toBe(84);
2272
- expect(evaluateCell("A1", { A1: "=SUM(A2, 42)", A2: '="42"' })).toBe(42);
2273
- expect(evaluateCell("A1", { A1: '=SUM(A2, "42")', A2: "42" })).toBe(84);
2274
- expect(evaluateCell("A1", { A1: '=SUM(A2, "42")', A2: '"42"' })).toBe(42);
2275
- expect(evaluateCell("A1", { A1: '=SUM(A2, "42")', A2: "=42" })).toBe(84);
2276
- expect(evaluateCell("A1", { A1: '=SUM(A2, "42")', A2: '="42"' })).toBe(42);
2277
- expect(evaluateCell("A1", { A1: "=SUM(A2, TRUE)", A2: "1" })).toBe(2);
2278
- expect(evaluateCell("A1", { A1: "=SUM(A2, TRUE)", A2: '"1"' })).toBe(1);
2279
- expect(evaluateCell("A1", { A1: "=SUM(A2, TRUE)", A2: "=1" })).toBe(2);
2280
- expect(evaluateCell("A1", { A1: "=SUM(A2, TRUE)", A2: '="1"' })).toBe(1);
2281
- });
2282
-
2283
- test("SUM: functional tests on range arguments", () => {
2284
- const grid = {
2285
- A1: "=SUM(B2:D3,B4:D4,E2:E3,E4)",
2286
-
2287
- A2: "=SUM(B2:E2)",
2288
- A3: "=SUM(B3:E3)",
2289
- A4: "=SUM(B4:E4)",
2290
- A5: "=SUM(B4:E2000)",
2291
-
2292
- B1: "=SUM(B2:B4)",
2293
- C1: "=SUM(C2:C4)",
2294
- D1: "=SUM(D2:D4)",
2295
- E1: "=SUM(E2:E4)",
2296
-
2297
- B2: "=3",
2298
- C2: "3",
2299
- D2: '"3"',
2300
- E2: '="3"',
2301
-
2302
- B3: '=" "',
2303
- C3: "0",
2304
- D3: "Jean Bave",
2305
- E3: '"Jean Darme"',
2306
-
2307
- B4: " ",
2308
- C4: '""',
2309
- D4: '=""',
2310
- E4: '" "',
2311
- };
2312
-
2313
- const gridResult = evaluateGrid(grid);
2314
- expect(gridResult.A1).toBe(6);
2315
- expect(gridResult.A2).toBe(6);
2316
- expect(gridResult.A3).toBe(0);
2317
- expect(gridResult.A4).toBe(0);
2318
- expect(gridResult.A5).toBe(0);
2319
- expect(gridResult.B1).toBe(3);
2320
- expect(gridResult.C1).toBe(3);
2321
- expect(gridResult.D1).toBe(0);
2322
- expect(gridResult.E1).toBe(0);
2323
- });
2324
-
2325
- //----------------------------------------------------------------------------
2326
- // SUMIF
2327
- //----------------------------------------------------------------------------
2328
-
2329
- test("COUNTUNIQUEIFS: functional tests on range", () => {
2330
- // prettier-ignore
2331
- const grid = {
2332
- A1: "Coffee" , B1: "4" ,
2333
- A2: "Newspaper" , B2: "1" ,
2334
- A3: "Taxi" , B3: "10" ,
2335
- A4: "Golf" , B4: "26" ,
2336
- A5: "Taxi" , B5: "8" ,
2337
- A6: "Coffee" , B6: "3.5",
2338
- A7: "Gas" , B7: "46" ,
2339
- A8: "Restaurant", B8: "31" ,
2340
-
2341
-
2342
- A12: '=SUMIF(A1:A8, "Taxi", B1:B8)',
2343
- A13: '=SUMIF(B1:B8, ">=10", B1:B8)',
2344
- A14: '=SUMIF(B1:B8, ">=10")',
2345
- A15: '=SUMIF(A1:A8, "G*", B1:B8)',
2346
- };
2347
-
2348
- const gridResult = evaluateGrid(grid);
2349
- expect(gridResult.A12).toBe(18);
2350
- expect(gridResult.A13).toBe(113);
2351
- expect(gridResult.A14).toBe(113);
2352
- expect(gridResult.A15).toBe(72);
2353
- });
2354
-
2355
- //----------------------------------------------------------------------------
2356
- // SUMIFS
2357
- //----------------------------------------------------------------------------
2358
-
2359
- test("COUNTUNIQUEIFS: functional tests on range", () => {
2360
- // prettier-ignore
2361
- const grid = {
2362
- B1: "4" , C1: "14", D1: "Yes",
2363
- B2: "28", C2: "30", D2: "Yes",
2364
- B3: "31", C3: "47", D3: "Yes",
2365
- B4: "12", C4: "0" , D4: "Yes",
2366
- B5: "31", C5: "47", D5: "Yes",
2367
- B6: "13", C6: "5" , D6: "No" ,
2368
- B7: "18", C7: "43", D7: "No" ,
2369
- B8: "24", C8: "7" , D8: "Yes",
2370
- B9: "44", C9: "28", D9: "No" ,
2371
- B10: "22", C10: "23", D10: "No" ,
2372
- B11: "9" , C11: "13", D11: "No" ,
2373
-
2374
- A12: '=SUMIFS(B1:B11, B1:B11, ">20")',
2375
- A13: '=SUMIFS(B1:B11, B1:B11, ">20", C1:C11, "<30")',
2376
- A14: '=SUMIFS(B1:B11, D1:D11, "No")',
2377
- };
2378
-
2379
- const gridResult = evaluateGrid(grid);
2380
- expect(gridResult.A12).toBe(180);
2381
- expect(gridResult.A13).toBe(90);
2382
- expect(gridResult.A14).toBe(106);
2383
- });
2384
-
2385
- //----------------------------------------------------------------------------
2386
- // TAN
2387
- //----------------------------------------------------------------------------
2388
-
2389
- test.each([
2390
- ["0", 0],
2391
- ["=PI()/4", 1],
2392
- ["1", 1.557407725],
2393
- ["2", -2.185039863],
2394
- ["-3", 0.142546543],
2395
- ["-4", -1.157821282],
2396
- ])("TAN(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2397
- expect(evaluateCell("A1", { A1: "=TAN(A2)", A2: a })).toBeCloseTo(expected, 9);
2398
- });
2399
-
2400
- //----------------------------------------------------------------------------
2401
- // TANH
2402
- //----------------------------------------------------------------------------
2403
-
2404
- test.each([
2405
- ["=LN(3)", 0.8],
2406
- ["=LN(2)", 0.6],
2407
- ["0", 0],
2408
- ["1", 0.761594156],
2409
- ["-2", -0.96402758],
2410
- ])("TANH(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2411
- expect(evaluateCell("A1", { A1: "=TANH(A2)", A2: a })).toBeCloseTo(expected, 9);
2412
- });
2413
-
2414
- //----------------------------------------------------------------------------
2415
- // TRUNC
2416
- //----------------------------------------------------------------------------
2417
-
2418
- test.each([
2419
- ["-1.6", -1],
2420
- ["-1.5", -1],
2421
- ["-1.4", -1],
2422
- ["0", 0],
2423
- ["1.4", 1],
2424
- ["1.5", 1],
2425
- ["1.6", 1],
2426
- ])("TRUNC(%s) - %s: take 1 parameter(s), return a number", (a, expected) => {
2427
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: a })).toBe(expected);
2428
- });
2429
-
2430
- test.each([
2431
- ["0.3", "2", 0.3],
2432
- ["0.34", "2", 0.34],
2433
- ["0.345", "2", 0.34],
2434
- ["-0.3", "2", -0.3],
2435
- ["-0.34", "2", -0.34],
2436
- ["-0.345", "2", -0.34],
2437
- ["0.345", "1.9", 0.3],
2438
- ["-0.345", "1.9", -0.3],
2439
- ["12345", "-1", 12340],
2440
- ["123456", "-1", 123450],
2441
- ["12345", "-2", 12300],
2442
- ["-123456", "-1", -123450],
2443
- ["-12345", "-2", -12300],
2444
- ["12345", "-1.9", 12340],
2445
- ["-12345", "-1.9", -12340],
2446
- ])("TRUNC(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
2447
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: a, A3: b })).toBe(expected);
2448
- });
2449
-
2450
- test("TRUNC: special value testing", () => {
2451
- expect(evaluateCell("A1", { A1: "=TRUNC()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
2452
- expect(evaluateCell("A1", { A1: "=TRUNC( , )" })).toBe(0);
2453
- expect(evaluateCell("A1", { A1: "=TRUNC(42, -1)" })).toBe(40);
2454
- expect(evaluateCell("A1", { A1: "=TRUNC( , 42)" })).toBe(0);
2455
- expect(evaluateCell("A1", { A1: "=TRUNC(42, )" })).toBe(42);
2456
- expect(evaluateCell("A1", { A1: "=TRUNC(42.42, TRUE)" })).toBe(42.4);
2457
- expect(evaluateCell("A1", { A1: "=TRUNC(42.42, FALSE)" })).toBe(42);
2458
- expect(evaluateCell("A1", { A1: "=TRUNC(TRUE, 10)" })).toBe(1);
2459
- expect(evaluateCell("A1", { A1: "=TRUNC(FALSE, 10)" })).toBe(0);
2460
-
2461
- expect(evaluateCell("A1", { A1: '=TRUNC("" , "")' })).toBe(0);
2462
- expect(evaluateCell("A1", { A1: '=TRUNC("" , 12)' })).toBe(0);
2463
- expect(evaluateCell("A1", { A1: '=TRUNC(" " , 0)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2464
- expect(evaluateCell("A1", { A1: '=TRUNC("42", -1)' })).toBe(40);
2465
- expect(evaluateCell("A1", { A1: '=TRUNC("42", "-1")' })).toBe(40);
2466
- expect(evaluateCell("A1", { A1: '=TRUNC("42", "")' })).toBe(42);
2467
-
2468
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "", A3: "" })).toBe(0);
2469
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "42", A3: "-1" })).toBe(40);
2470
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "", A3: "42" })).toBe(0);
2471
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "42", A3: "" })).toBe(42);
2472
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "42.42", A3: "TRUE" })).toBe(42.4);
2473
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "42.42", A3: "FALSE" })).toBe(42);
2474
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "TRUE", A3: "10" })).toBe(1);
2475
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: "FALSE", A3: "10" })).toBe(0);
2476
-
2477
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: '"42"', A3: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
2478
-
2479
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
2480
- expect(evaluateCell("A1", { A1: "=TRUNC(A2, A3)", A2: '="42"', A3: '="-1"' })).toBe(40);
2481
- });
2482
- });