@odoo/o-spreadsheet 14.0.0 → 14.0.1

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 (198) hide show
  1. package/.eslintrc.json +20 -0
  2. package/.husky/post-checkout +9 -0
  3. package/.husky/pre-commit +39 -0
  4. package/.prettierignore +1 -0
  5. package/astToFormula.patch +0 -0
  6. package/demo/data.js +255 -0
  7. package/demo/index.html +9 -0
  8. package/demo/libs/Chart.bundle.js +20755 -0
  9. package/demo/main.js +101 -0
  10. package/doc/readme.md +46 -0
  11. package/package.json +3 -17
  12. package/rollup.config.js +23 -0
  13. package/src/base_plugin.ts +102 -0
  14. package/src/components/autofill.ts +146 -0
  15. package/src/components/bottom_bar.ts +199 -0
  16. package/src/components/color_picker.ts +150 -0
  17. package/src/components/composer/autocomplete_dropdown.ts +135 -0
  18. package/src/components/composer/composer.ts +487 -0
  19. package/src/components/composer/content_editable_helper.ts +146 -0
  20. package/src/components/figures/chart.ts +70 -0
  21. package/src/components/figures/container.ts +268 -0
  22. package/src/components/figures/text_figure.ts +36 -0
  23. package/src/components/grid.ts +635 -0
  24. package/src/components/helpers/dom_helpers.ts +7 -0
  25. package/src/components/helpers/drag_and_drop.ts +17 -0
  26. package/src/components/icons.ts +36 -0
  27. package/src/components/index.ts +1 -0
  28. package/src/components/menu.ts +288 -0
  29. package/src/components/overlay.ts +457 -0
  30. package/src/components/scrollbar.ts +22 -0
  31. package/src/components/selection_input.ts +168 -0
  32. package/src/components/side_panel/cell_is_rule_editor.ts +169 -0
  33. package/src/components/side_panel/chart_panel.ts +104 -0
  34. package/src/components/side_panel/color_scale_rule_editor.ts +145 -0
  35. package/src/components/side_panel/conditional_formatting.ts +396 -0
  36. package/src/components/side_panel/side_panel.ts +127 -0
  37. package/src/components/side_panel/translations_terms.ts +45 -0
  38. package/src/components/spreadsheet.ts +198 -0
  39. package/src/components/top_bar.ts +535 -0
  40. package/src/constants.ts +26 -0
  41. package/src/data.ts +149 -0
  42. package/src/fonts.ts +41 -0
  43. package/src/formulas/compiler.ts +258 -0
  44. package/src/formulas/composer_tokenizer.ts +70 -0
  45. package/src/formulas/index.ts +15 -0
  46. package/src/formulas/normalize.ts +52 -0
  47. package/src/formulas/parser.ts +280 -0
  48. package/src/formulas/range_tokenizer.ts +97 -0
  49. package/src/formulas/tokenizer.ts +242 -0
  50. package/src/functions/arguments.ts +114 -0
  51. package/src/functions/dates.ts +302 -0
  52. package/src/functions/helpers.ts +592 -0
  53. package/src/functions/index.ts +52 -0
  54. package/src/functions/module_database.ts +282 -0
  55. package/src/functions/module_date.ts +743 -0
  56. package/src/functions/module_info.ts +69 -0
  57. package/src/functions/module_logical.ts +208 -0
  58. package/src/functions/module_lookup.ts +185 -0
  59. package/src/functions/module_math.ts +1252 -0
  60. package/src/functions/module_operators.ts +291 -0
  61. package/src/functions/module_statistical.ts +882 -0
  62. package/src/functions/module_text.ts +370 -0
  63. package/src/helpers/color.ts +30 -0
  64. package/src/helpers/coordinates.ts +71 -0
  65. package/src/helpers/grid_manipulation.ts +68 -0
  66. package/src/helpers/index.ts +7 -0
  67. package/src/helpers/misc.ts +76 -0
  68. package/src/helpers/numbers.ts +117 -0
  69. package/src/helpers/uuid.ts +19 -0
  70. package/src/helpers/zones.ts +263 -0
  71. package/src/history.ts +186 -0
  72. package/src/index.ts +84 -0
  73. package/src/model.ts +261 -0
  74. package/src/plugins/autofill.ts +412 -0
  75. package/src/plugins/chart.ts +404 -0
  76. package/src/plugins/clipboard.ts +461 -0
  77. package/src/plugins/conditional_format.ts +445 -0
  78. package/src/plugins/core.ts +1502 -0
  79. package/src/plugins/edition.ts +157 -0
  80. package/src/plugins/evaluation.ts +428 -0
  81. package/src/plugins/figures.ts +123 -0
  82. package/src/plugins/formatting.ts +630 -0
  83. package/src/plugins/highlight.ts +187 -0
  84. package/src/plugins/index.ts +32 -0
  85. package/src/plugins/merge.ts +524 -0
  86. package/src/plugins/renderer.ts +571 -0
  87. package/src/plugins/selection.ts +562 -0
  88. package/src/plugins/selection_inputs.ts +326 -0
  89. package/src/registries/autofill_modifiers.ts +76 -0
  90. package/src/registries/autofill_rules.ts +98 -0
  91. package/src/registries/figure_registry.ts +30 -0
  92. package/src/registries/index.ts +7 -0
  93. package/src/registries/menu_items_registry.ts +110 -0
  94. package/src/registries/menus/cell_menu_registry.ts +79 -0
  95. package/src/registries/menus/col_menu_registry.ts +63 -0
  96. package/src/registries/menus/index.ts +6 -0
  97. package/src/registries/menus/menu_items_actions.ts +425 -0
  98. package/src/registries/menus/row_menu_registry.ts +63 -0
  99. package/src/registries/menus/sheet_menu_registry.ts +75 -0
  100. package/src/registries/menus/topbar_menu_registry.ts +204 -0
  101. package/src/registries/side_panel_registry.ts +26 -0
  102. package/src/registries/topbar_component_registry.ts +12 -0
  103. package/src/registry.ts +51 -0
  104. package/src/translation.ts +44 -0
  105. package/src/types/autofill.ts +48 -0
  106. package/src/types/chart.ts +26 -0
  107. package/src/types/commands.ts +716 -0
  108. package/src/types/conditional_formatting.ts +124 -0
  109. package/src/types/env.ts +13 -0
  110. package/src/types/functions.ts +35 -0
  111. package/src/types/getters.ts +103 -0
  112. package/src/types/index.ts +20 -0
  113. package/src/types/misc.ts +143 -0
  114. package/src/types/rendering.ts +41 -0
  115. package/src/types/workbook_data.ts +62 -0
  116. package/tests/__mocks__/uuid.ts +7 -0
  117. package/tests/canvas.mock.ts +34 -0
  118. package/tests/components/__mocks__/content_editable_helper.ts +79 -0
  119. package/tests/components/__mocks__/scrollbar.ts +18 -0
  120. package/tests/components/__snapshots__/autocomplete_dropdown_test.ts.snap +29 -0
  121. package/tests/components/__snapshots__/bottom_bar_test.ts.snap +75 -0
  122. package/tests/components/__snapshots__/context_menu_test.ts.snap +88 -0
  123. package/tests/components/__snapshots__/grid_test.ts.snap +60 -0
  124. package/tests/components/__snapshots__/spreadsheet_test.ts.snap +455 -0
  125. package/tests/components/__snapshots__/top_bar_test.ts.snap +705 -0
  126. package/tests/components/autocomplete_dropdown_test.ts +315 -0
  127. package/tests/components/autofill_test.ts +167 -0
  128. package/tests/components/bottom_bar_test.ts +262 -0
  129. package/tests/components/chart_side_panel_test.ts +123 -0
  130. package/tests/components/composer_test.ts +400 -0
  131. package/tests/components/context_menu_test.ts +825 -0
  132. package/tests/components/grid_manipulation_test.ts +163 -0
  133. package/tests/components/grid_test.ts +581 -0
  134. package/tests/components/overlay_test.ts +541 -0
  135. package/tests/components/selection_input_test.ts +259 -0
  136. package/tests/components/side_panel_test.ts +148 -0
  137. package/tests/components/spreadsheet_test.ts +194 -0
  138. package/tests/components/top_bar_test.ts +427 -0
  139. package/tests/data_test.ts +175 -0
  140. package/tests/dom_helper.ts +42 -0
  141. package/tests/formulas/__snapshots__/compiler_test.ts.snap +302 -0
  142. package/tests/formulas/compiler_test.ts +266 -0
  143. package/tests/formulas/composer_tokenizer_test.ts +137 -0
  144. package/tests/formulas/expressions_test.ts +57 -0
  145. package/tests/formulas/formulas_test.ts +80 -0
  146. package/tests/formulas/normalize_test.ts +82 -0
  147. package/tests/formulas/parser_test.ts +224 -0
  148. package/tests/formulas/range_tokenizer_test.ts +187 -0
  149. package/tests/formulas/tokenizer_test.ts +164 -0
  150. package/tests/functions/arguments_test.ts +141 -0
  151. package/tests/functions/dates_test.ts +1081 -0
  152. package/tests/functions/functions_test.ts +53 -0
  153. package/tests/functions/helper_test.ts +98 -0
  154. package/tests/functions/module_database_test.ts +311 -0
  155. package/tests/functions/module_date_test.ts +941 -0
  156. package/tests/functions/module_info_test.ts +139 -0
  157. package/tests/functions/module_logical_test.ts +369 -0
  158. package/tests/functions/module_lookup_test.ts +541 -0
  159. package/tests/functions/module_math_test.ts +2482 -0
  160. package/tests/functions/module_operators_test.ts +955 -0
  161. package/tests/functions/module_statistical_test.ts +2014 -0
  162. package/tests/functions/module_text_test.ts +667 -0
  163. package/tests/helpers/coordinates_test.ts +25 -0
  164. package/tests/helpers/misc_test.ts +95 -0
  165. package/tests/helpers/numbers_test.ts +196 -0
  166. package/tests/helpers/zones_test.ts +97 -0
  167. package/tests/helpers.ts +384 -0
  168. package/tests/menu_items_registry_test.ts +540 -0
  169. package/tests/model/plugins/__snapshots__/chart_test.ts.snap +90 -0
  170. package/tests/model/plugins/chart_test.ts +562 -0
  171. package/tests/model_test.ts +82 -0
  172. package/tests/plugins/__snapshots__/conditional_formatting_test.ts.snap +131 -0
  173. package/tests/plugins/__snapshots__/renderer_test.ts.snap +371 -0
  174. package/tests/plugins/autofill_test.ts +457 -0
  175. package/tests/plugins/borders_test.ts +295 -0
  176. package/tests/plugins/clipboard_test.ts +1180 -0
  177. package/tests/plugins/conditional_formatting_test.ts +1253 -0
  178. package/tests/plugins/core_test.ts +614 -0
  179. package/tests/plugins/edition_test.ts +100 -0
  180. package/tests/plugins/evaluation_async_test.ts +332 -0
  181. package/tests/plugins/evaluation_dates_test.ts +79 -0
  182. package/tests/plugins/evaluation_test.ts +901 -0
  183. package/tests/plugins/figures_test.ts +327 -0
  184. package/tests/plugins/formatting_test.ts +391 -0
  185. package/tests/plugins/grid_manipulation_test.ts +1366 -0
  186. package/tests/plugins/highlight_test.ts +413 -0
  187. package/tests/plugins/history_test.ts +142 -0
  188. package/tests/plugins/import_export_test.ts +276 -0
  189. package/tests/plugins/merges_test.ts +490 -0
  190. package/tests/plugins/navigation_test.ts +181 -0
  191. package/tests/plugins/plugins/evaluation_test.ts +111 -0
  192. package/tests/plugins/renderer_test.ts +598 -0
  193. package/tests/plugins/resizing_test.ts +152 -0
  194. package/tests/plugins/selection_input_test.ts +409 -0
  195. package/tests/plugins/selection_test.ts +442 -0
  196. package/tests/plugins/sheets_test.ts +643 -0
  197. package/tests/plugins/style_test.ts +90 -0
  198. package/tsconfig.json +22 -0
@@ -0,0 +1,955 @@
1
+ import { evaluateCell } from "../helpers";
2
+
3
+ describe("operators", () => {
4
+ //----------------------------------------------------------------------------
5
+ // ADD
6
+ //----------------------------------------------------------------------------
7
+
8
+ test("ADD: functional tests on simple arguments", () => {
9
+ expect(evaluateCell("A1", { A1: "=ADD()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
10
+ expect(evaluateCell("A1", { A1: "=ADD( , )" })).toBe(0);
11
+ expect(evaluateCell("A1", { A1: "=ADD( , 1)" })).toBe(1);
12
+ expect(evaluateCell("A1", { A1: "=ADD(42, 24)" })).toBe(66);
13
+ expect(evaluateCell("A1", { A1: "=ADD(42, -24)" })).toBe(18);
14
+ expect(evaluateCell("A1", { A1: "=ADD(42, 0.42)" })).toBe(42.42);
15
+ expect(evaluateCell("A1", { A1: "=ADD(42, 42%)" })).toBe(42.42);
16
+ });
17
+
18
+ test("ADD: casting tests on simple arguments", () => {
19
+ expect(evaluateCell("A1", { A1: '=ADD(1, "")' })).toBe(1);
20
+ expect(evaluateCell("A1", { A1: '=ADD(1, " ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
21
+ expect(evaluateCell("A1", { A1: '=ADD(1, "3")' })).toBe(4);
22
+ expect(evaluateCell("A1", { A1: '=ADD(1, "-3")' })).toBe(-2);
23
+ expect(evaluateCell("A1", { A1: "=ADD(1, TRUE)" })).toBe(2);
24
+ expect(evaluateCell("A1", { A1: "=ADD(1, FALSE)" })).toBe(1);
25
+ expect(evaluateCell("A1", { A1: '=ADD(1, "3%")' })).toBe(1.03);
26
+ });
27
+
28
+ test("ADD: functional tests on cell arguments", () => {
29
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)" })).toBe(0);
30
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "1" })).toBe(1);
31
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "1", A3: "42" })).toBe(43);
32
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "-1", A3: "4.2" })).toBe(3.2);
33
+ });
34
+
35
+ test("ADD: casting tests on cell arguments", () => {
36
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
37
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
38
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: '"3"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
39
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: "TRUE" })).toBe(43);
40
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: "FALSE" })).toBe(42);
41
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: '=""' })).toBe(42);
42
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
43
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "42", A3: '="42"' })).toBe(84);
44
+
45
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "03/01/2020", A3: "03/01/2020" })).toBe(
46
+ 87782
47
+ );
48
+ expect(
49
+ evaluateCell("A1", {
50
+ A1: "=ADD(A2, A3)",
51
+ A2: "=A4+1",
52
+ A3: "=A4+1",
53
+ A4: "03/01/2020",
54
+ A5: "03/01/2020",
55
+ })
56
+ ).toBe(87784);
57
+ expect(
58
+ evaluateCell("A1", {
59
+ A1: "=ADD(A2, A3)",
60
+ A2: "=A4+0.1",
61
+ A3: "=A4+0.1",
62
+ A4: "03/01/2020",
63
+ A5: "03/01/2020",
64
+ })
65
+ ).toBe(87782.2);
66
+ expect(evaluateCell("A1", { A1: "=ADD(A2, A3)", A2: "03/01/2020", A3: "2" })).toMatchObject({
67
+ value: 43893,
68
+ });
69
+ });
70
+
71
+ //----------------------------------------------------------------------------
72
+ // CONCAT
73
+ //----------------------------------------------------------------------------
74
+
75
+ test("CONCAT: functional tests on simple arguments", () => {
76
+ expect(evaluateCell("A1", { A1: "=CONCAT()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
77
+ expect(evaluateCell("A1", { A1: "=CONCAT( , )" })).toBe("");
78
+ expect(evaluateCell("A1", { A1: "=CONCAT( , 1)" })).toBe("1");
79
+ expect(evaluateCell("A1", { A1: "=CONCAT(42, 24)" })).toBe("4224");
80
+ expect(evaluateCell("A1", { A1: "=CONCAT(42, -24)" })).toBe("42-24");
81
+ expect(evaluateCell("A1", { A1: "=CONCAT(42, 0.42)" })).toBe("420.42");
82
+ expect(evaluateCell("A1", { A1: "=CONCAT(42, 42%)" })).toBe("420.42");
83
+ expect(evaluateCell("A1", { A1: '=CONCAT(1, "")' })).toBe("1");
84
+ expect(evaluateCell("A1", { A1: '=CONCAT(1, " ")' })).toBe("1 ");
85
+ expect(evaluateCell("A1", { A1: '=CONCAT(1, "3")' })).toBe("13");
86
+ expect(evaluateCell("A1", { A1: '=CONCAT(1, "-3")' })).toBe("1-3");
87
+ expect(evaluateCell("A1", { A1: "=CONCAT(1, TRUE)" })).toBe("1TRUE");
88
+ expect(evaluateCell("A1", { A1: "=CONCAT(1, FALSE)" })).toBe("1FALSE");
89
+ expect(evaluateCell("A1", { A1: '=CONCAT(1, "3%")' })).toBe("13%");
90
+ expect(evaluateCell("A1", { A1: '=CONCAT("ki", "kou")' })).toBe("kikou");
91
+ expect(evaluateCell("A1", { A1: '=CONCAT("TRUE", TRUE)' })).toBe("TRUETRUE");
92
+ });
93
+
94
+ test("CONCAT: functional tests on cell arguments", () => {
95
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)" })).toBe("");
96
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "1" })).toBe("1");
97
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "1", A3: "42" })).toBe("142");
98
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "42", A3: '""' })).toBe('42""');
99
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "42", A3: '"42"' })).toBe('42"42"');
100
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "42", A3: "TRUE" })).toBe("42TRUE");
101
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: '"TRUE"', A3: "TRUE" })).toBe(
102
+ '"TRUE"TRUE'
103
+ );
104
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "42", A3: '=""' })).toBe("42");
105
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "42", A3: '=" "' })).toBe("42 ");
106
+ expect(evaluateCell("A1", { A1: "=CONCAT(A2, A3)", A2: "42", A3: '="24"' })).toBe("4224");
107
+ });
108
+
109
+ //----------------------------------------------------------------------------
110
+ // DIVIDE
111
+ //----------------------------------------------------------------------------
112
+
113
+ test("DIVIDE: functional tests on simple arguments", () => {
114
+ expect(evaluateCell("A1", { A1: "=DIVIDE()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
115
+ expect(evaluateCell("A1", { A1: "=DIVIDE( , )" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
116
+ expect(evaluateCell("A1", { A1: "=DIVIDE( , 1)" })).toBe(0);
117
+ expect(evaluateCell("A1", { A1: "=DIVIDE(84, 42)" })).toBe(2);
118
+ expect(evaluateCell("A1", { A1: "=DIVIDE(48, -24)" })).toBe(-2);
119
+ expect(evaluateCell("A1", { A1: "=DIVIDE(1, 0.5)" })).toBe(2);
120
+ expect(evaluateCell("A1", { A1: "=DIVIDE(1, 5%)" })).toBe(20);
121
+ });
122
+
123
+ test("DIVIDE: casting tests on simple arguments", () => {
124
+ expect(evaluateCell("A1", { A1: '=DIVIDE("", 1)' })).toBe(0);
125
+ expect(evaluateCell("A1", { A1: '=DIVIDE(" ", 1)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
126
+ expect(evaluateCell("A1", { A1: '=DIVIDE("4", 2)' })).toBe(2);
127
+ expect(evaluateCell("A1", { A1: '=DIVIDE("-4", 2)' })).toBe(-2);
128
+ expect(evaluateCell("A1", { A1: "=DIVIDE(TRUE, 0.5)" })).toBe(2);
129
+ expect(evaluateCell("A1", { A1: "=DIVIDE(FALSE, 42)" })).toBe(0);
130
+ expect(evaluateCell("A1", { A1: '=DIVIDE(1, "50%")' })).toBe(2);
131
+ });
132
+
133
+ test("DIVIDE: functional tests on cell arguments", () => {
134
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)" })).toBe("#ERROR"); // @compatibility: on google sheets, return #DIV/0!
135
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A3: "42" })).toBe(0);
136
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: "42", A3: "2" })).toBe(21);
137
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: "4.2", A3: "-1" })).toBe(-4.2);
138
+ });
139
+
140
+ test("DIVIDE: casting tests on cell arguments", () => {
141
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: '""', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
142
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: '" "', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
143
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: '"3"', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
144
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: "TRUE", A3: "2" })).toBe(0.5);
145
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: '=""', A3: "42" })).toBe(0);
146
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: '=" "', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
147
+ expect(evaluateCell("A1", { A1: "=DIVIDE(A2, A3)", A2: "42", A3: '="42"' })).toBe(1);
148
+ });
149
+
150
+ //----------------------------------------------------------------------------
151
+ // EQ
152
+ //----------------------------------------------------------------------------
153
+
154
+ test("EQ: functional tests on simple arguments", () => {
155
+ expect(evaluateCell("A1", { A1: "=EQ()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
156
+ expect(evaluateCell("A1", { A1: "=EQ( , )" })).toBe(true);
157
+ expect(evaluateCell("A1", { A1: "=EQ( , 0)" })).toBe(true);
158
+ expect(evaluateCell("A1", { A1: "=EQ(42, 42)" })).toBe(true);
159
+ expect(evaluateCell("A1", { A1: "=EQ(42, -42)" })).toBe(false);
160
+ expect(evaluateCell("A1", { A1: "=EQ(42, 42%)" })).toBe(false);
161
+ expect(evaluateCell("A1", { A1: "=EQ(0.42, 42%)" })).toBe(true);
162
+ expect(evaluateCell("A1", { A1: '=EQ("", )' })).toBe(true);
163
+ expect(evaluateCell("A1", { A1: '=EQ("", 0)' })).toBe(false);
164
+ expect(evaluateCell("A1", { A1: '=EQ("", " ")' })).toBe(false);
165
+ expect(evaluateCell("A1", { A1: '=EQ("", "kikou")' })).toBe(false);
166
+ expect(evaluateCell("A1", { A1: '=EQ("KIKOU", "kikou")' })).toBe(true);
167
+ expect(evaluateCell("A1", { A1: "=EQ(TRUE, 1)" })).toBe(false);
168
+ expect(evaluateCell("A1", { A1: "=EQ(TRUE, )" })).toBe(false);
169
+ expect(evaluateCell("A1", { A1: "=EQ(FALSE, 0)" })).toBe(false);
170
+ expect(evaluateCell("A1", { A1: "=EQ(FALSE, )" })).toBe(true);
171
+ });
172
+
173
+ test("EQ: functional tests on cell arguments", () => {
174
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)" })).toBe(true);
175
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A3: "0" })).toBe(true);
176
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "42", A3: "42" })).toBe(true);
177
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "42", A3: "-42" })).toBe(false);
178
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "0.42", A3: "42%" })).toBe(true);
179
+
180
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A3: "test" })).toBe(false);
181
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "TEST", A3: "test" })).toBe(true);
182
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "TRUE", A3: "1" })).toBe(false);
183
+
184
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: '=""' })).toBe(true);
185
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: '=""', A3: "0" })).toBe(false);
186
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "=TRUE", A3: "1" })).toBe(false);
187
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: '="42"', A3: "42" })).toBe(false);
188
+
189
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "03/01/2020", A3: "03/01/2020" })).toBe(
190
+ true
191
+ );
192
+ expect(
193
+ evaluateCell("A1", {
194
+ A1: "=EQ(A2, A3)",
195
+ A2: "=A4+1",
196
+ A3: "=A4+1",
197
+ A4: "03/01/2020",
198
+ A5: "03/01/2020",
199
+ })
200
+ ).toBe(true);
201
+ expect(
202
+ evaluateCell("A1", {
203
+ A1: "=EQ(A2, A3)",
204
+ A2: "=A4+0.1",
205
+ A3: "=A4+0.2",
206
+ A4: "03/01/2020",
207
+ A5: "03/01/2020",
208
+ })
209
+ ).toBe(false);
210
+ expect(evaluateCell("A1", { A1: "=EQ(A2, A3)", A2: "03/01/2020", A3: "43891" })).toBe(true);
211
+ });
212
+
213
+ //----------------------------------------------------------------------------
214
+ // GT
215
+ //----------------------------------------------------------------------------
216
+
217
+ test("GT: functional tests on simple arguments", () => {
218
+ expect(evaluateCell("A1", { A1: "=GT()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
219
+ expect(evaluateCell("A1", { A1: "=GT( , )" })).toBe(false);
220
+ expect(evaluateCell("A1", { A1: "=GT( , 1)" })).toBe(false);
221
+ expect(evaluateCell("A1", { A1: "=GT(1, )" })).toBe(true);
222
+ expect(evaluateCell("A1", { A1: "=GT(42, 42)" })).toBe(false);
223
+ expect(evaluateCell("A1", { A1: "=GT(42, 24)" })).toBe(true);
224
+ expect(evaluateCell("A1", { A1: "=GT(24, -22)" })).toBe(true);
225
+ expect(evaluateCell("A1", { A1: "=GT(42, 42%)" })).toBe(true);
226
+ expect(evaluateCell("A1", { A1: "=GT(0.42, 0.41)" })).toBe(true);
227
+
228
+ expect(evaluateCell("A1", { A1: '=GT("", )' })).toBe(false);
229
+ expect(evaluateCell("A1", { A1: '=GT( , "")' })).toBe(false);
230
+ expect(evaluateCell("A1", { A1: "=GT(0, )" })).toBe(false);
231
+ expect(evaluateCell("A1", { A1: "=GT( , 0)" })).toBe(false);
232
+ expect(evaluateCell("A1", { A1: '=GT("", 0)' })).toBe(true);
233
+ expect(evaluateCell("A1", { A1: '=GT(0, "")' })).toBe(false);
234
+
235
+ expect(evaluateCell("A1", { A1: '=GT("", " ")' })).toBe(false);
236
+ expect(evaluateCell("A1", { A1: '=GT(" ", "")' })).toBe(true);
237
+
238
+ expect(evaluateCell("A1", { A1: '=GT("b", "a")' })).toBe(true);
239
+ expect(evaluateCell("A1", { A1: '=GT("a", "b")' })).toBe(false);
240
+ expect(evaluateCell("A1", { A1: '=GT("KIKOU", "kikou")' })).toBe(false);
241
+ expect(evaluateCell("A1", { A1: '=GT("kikou", "KIKOU")' })).toBe(false);
242
+ expect(evaluateCell("A1", { A1: '=GT("5", "100")' })).toBe(true);
243
+ expect(evaluateCell("A1", { A1: '=GT("100", "5")' })).toBe(false);
244
+
245
+ expect(evaluateCell("A1", { A1: "=GT(TRUE, 0)" })).toBe(true);
246
+ expect(evaluateCell("A1", { A1: "=GT(0, TRUE)" })).toBe(false);
247
+ expect(evaluateCell("A1", { A1: "=GT(FALSE, 1)" })).toBe(true);
248
+ expect(evaluateCell("A1", { A1: "=GT(1, FALSE)" })).toBe(false);
249
+ expect(evaluateCell("A1", { A1: "=GT(TRUE, )" })).toBe(true);
250
+ expect(evaluateCell("A1", { A1: "=GT( , TRUE)" })).toBe(false);
251
+ expect(evaluateCell("A1", { A1: "=GT(FALSE, )" })).toBe(false);
252
+ expect(evaluateCell("A1", { A1: "=GT( , FALSE)" })).toBe(false);
253
+ expect(evaluateCell("A1", { A1: "=GT(TRUE, FALSE)" })).toBe(true);
254
+ expect(evaluateCell("A1", { A1: "=GT(FALSE, TRUE)" })).toBe(false);
255
+
256
+ expect(evaluateCell("A1", { A1: '=GT(32, "32")' })).toBe(false);
257
+ expect(evaluateCell("A1", { A1: '=GT(32, "31")' })).toBe(false);
258
+ expect(evaluateCell("A1", { A1: '=GT("32", 31)' })).toBe(true);
259
+ expect(evaluateCell("A1", { A1: '=GT("32", 99)' })).toBe(true);
260
+ expect(evaluateCell("A1", { A1: '=GT("32", 1)' })).toBe(true);
261
+ expect(evaluateCell("A1", { A1: '=GT("1", 99999)' })).toBe(true);
262
+ expect(evaluateCell("A1", { A1: '=GT("1", "99999")' })).toBe(false);
263
+ });
264
+
265
+ test("GT: functional tests on cell arguments", () => {
266
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)" })).toBe(false);
267
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "1" })).toBe(true);
268
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A3: "1" })).toBe(false);
269
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "42", A3: "42" })).toBe(false);
270
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "42", A3: "24" })).toBe(true);
271
+
272
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: '=""' })).toBe(false);
273
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A3: '=""' })).toBe(false);
274
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "0" })).toBe(false);
275
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A3: "0" })).toBe(false);
276
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: '=""', A3: "0" })).toBe(true);
277
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "0", A3: '=""' })).toBe(false);
278
+
279
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "b", A3: "a" })).toBe(true);
280
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "a", A3: "b" })).toBe(false);
281
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "A", A3: "a" })).toBe(false);
282
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "a", A3: "A" })).toBe(false);
283
+
284
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "TRUE", A3: "0" })).toBe(true);
285
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "0", A3: "TRUE" })).toBe(false);
286
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "FALSE", A3: "1" })).toBe(true);
287
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "1", A3: "FALSE" })).toBe(false);
288
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "TRUE" })).toBe(true);
289
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A3: "TRUE" })).toBe(false);
290
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "FALSE" })).toBe(false);
291
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A3: "FALSE" })).toBe(false);
292
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "TRUE", A3: "FALSE" })).toBe(true);
293
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "FALSE", A3: "TRUE" })).toBe(false);
294
+
295
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: '="1"', A3: "99999" })).toBe(true);
296
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: '="1"', A3: '="99999"' })).toBe(false);
297
+
298
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "03/01/2020", A3: "03/01/2020" })).toBe(
299
+ false
300
+ );
301
+ expect(
302
+ evaluateCell("A1", {
303
+ A1: "=GT(A2, A3)",
304
+ A2: "=A4+1",
305
+ A3: "=A4",
306
+ A4: "03/01/2020",
307
+ A5: "03/01/2020",
308
+ })
309
+ ).toBe(true);
310
+ expect(
311
+ evaluateCell("A1", {
312
+ A1: "=GT(A3, A2)",
313
+ A2: "=A4+1",
314
+ A3: "=A4",
315
+ A4: "03/01/2020",
316
+ A5: "03/01/2020",
317
+ })
318
+ ).toBe(false);
319
+ expect(
320
+ evaluateCell("A1", {
321
+ A1: "=GT(A2, A3)",
322
+ A2: "=A4+0.1",
323
+ A3: "=A4+0.2",
324
+ A4: "03/01/2020",
325
+ A5: "03/01/2020",
326
+ })
327
+ ).toBe(false);
328
+ expect(evaluateCell("A1", { A1: "=GT(A2, A3)", A2: "03/01/2020", A3: "4" })).toBe(true);
329
+ expect(evaluateCell("A1", { A1: "=GT(A3, A2)", A2: "03/01/2020", A3: "4" })).toBe(false);
330
+ });
331
+
332
+ //----------------------------------------------------------------------------
333
+ // GTE
334
+ //----------------------------------------------------------------------------
335
+
336
+ test("GTE: functional tests on simple arguments", () => {
337
+ expect(evaluateCell("A1", { A1: "=GTE()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
338
+ expect(evaluateCell("A1", { A1: "=GTE( , )" })).toBe(true);
339
+ expect(evaluateCell("A1", { A1: "=GTE( , 1)" })).toBe(false);
340
+ expect(evaluateCell("A1", { A1: "=GTE(1, )" })).toBe(true);
341
+ expect(evaluateCell("A1", { A1: "=GTE(42, 42)" })).toBe(true);
342
+ expect(evaluateCell("A1", { A1: "=GTE(42, 24)" })).toBe(true);
343
+ expect(evaluateCell("A1", { A1: "=GTE(24, -22)" })).toBe(true);
344
+ expect(evaluateCell("A1", { A1: "=GTE(42, 42%)" })).toBe(true);
345
+ expect(evaluateCell("A1", { A1: "=GTE(0.42, 0.41)" })).toBe(true);
346
+
347
+ expect(evaluateCell("A1", { A1: '=GTE("", )' })).toBe(true);
348
+ expect(evaluateCell("A1", { A1: '=GTE( , "")' })).toBe(true);
349
+ expect(evaluateCell("A1", { A1: "=GTE(0, )" })).toBe(true);
350
+ expect(evaluateCell("A1", { A1: "=GTE( , 0)" })).toBe(true);
351
+ expect(evaluateCell("A1", { A1: '=GTE("", 0)' })).toBe(true);
352
+ expect(evaluateCell("A1", { A1: '=GTE(0, "")' })).toBe(false);
353
+
354
+ expect(evaluateCell("A1", { A1: '=GTE("", " ")' })).toBe(false);
355
+ expect(evaluateCell("A1", { A1: '=GTE(" ", "")' })).toBe(true);
356
+
357
+ expect(evaluateCell("A1", { A1: '=GTE("b", "a")' })).toBe(true);
358
+ expect(evaluateCell("A1", { A1: '=GTE("a", "b")' })).toBe(false);
359
+ expect(evaluateCell("A1", { A1: '=GTE("KIKOU", "kikou")' })).toBe(true);
360
+ expect(evaluateCell("A1", { A1: '=GTE("kikou", "KIKOU")' })).toBe(true);
361
+ expect(evaluateCell("A1", { A1: '=GTE("5", "100")' })).toBe(true);
362
+ expect(evaluateCell("A1", { A1: '=GTE("100", "5")' })).toBe(false);
363
+
364
+ expect(evaluateCell("A1", { A1: "=GTE(TRUE, 0)" })).toBe(true);
365
+ expect(evaluateCell("A1", { A1: "=GTE(0, TRUE)" })).toBe(false);
366
+ expect(evaluateCell("A1", { A1: "=GTE(FALSE, 1)" })).toBe(true);
367
+ expect(evaluateCell("A1", { A1: "=GTE(1, FALSE)" })).toBe(false);
368
+ expect(evaluateCell("A1", { A1: "=GTE(TRUE, )" })).toBe(true);
369
+ expect(evaluateCell("A1", { A1: "=GTE( , TRUE)" })).toBe(false);
370
+ expect(evaluateCell("A1", { A1: "=GTE(FALSE, )" })).toBe(true);
371
+ expect(evaluateCell("A1", { A1: "=GTE( , FALSE)" })).toBe(true);
372
+ expect(evaluateCell("A1", { A1: "=GTE(TRUE, FALSE)" })).toBe(true);
373
+ expect(evaluateCell("A1", { A1: "=GTE(FALSE, TRUE)" })).toBe(false);
374
+
375
+ expect(evaluateCell("A1", { A1: '=GTE(32, "32")' })).toBe(false);
376
+ expect(evaluateCell("A1", { A1: '=GTE(32, "31")' })).toBe(false);
377
+ expect(evaluateCell("A1", { A1: '=GTE("32", 31)' })).toBe(true);
378
+ expect(evaluateCell("A1", { A1: '=GTE("32", 99)' })).toBe(true);
379
+ expect(evaluateCell("A1", { A1: '=GTE("32", 1)' })).toBe(true);
380
+
381
+ expect(evaluateCell("A1", { A1: '=GTE("1", 99999)' })).toBe(true);
382
+ expect(evaluateCell("A1", { A1: '=GTE("1", "99999")' })).toBe(false);
383
+ });
384
+
385
+ test("GTE: functional tests on cell arguments", () => {
386
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)" })).toBe(true);
387
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "1" })).toBe(true);
388
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A3: "1" })).toBe(false);
389
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "42", A3: "42" })).toBe(true);
390
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "42", A3: "24" })).toBe(true);
391
+
392
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: '=""' })).toBe(true);
393
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A3: '=""' })).toBe(true);
394
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "0" })).toBe(true);
395
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A3: "0" })).toBe(true);
396
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: '=""', A3: "0" })).toBe(true);
397
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "0", A3: '=""' })).toBe(false);
398
+
399
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "b", A3: "a" })).toBe(true);
400
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "a", A3: "b" })).toBe(false);
401
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "A", A3: "a" })).toBe(true);
402
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "a", A3: "A" })).toBe(true);
403
+
404
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "TRUE", A3: "0" })).toBe(true);
405
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "0", A3: "TRUE" })).toBe(false);
406
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "FALSE", A3: "1" })).toBe(true);
407
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "1", A3: "FALSE" })).toBe(false);
408
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "TRUE" })).toBe(true);
409
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A3: "TRUE" })).toBe(false);
410
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "FALSE" })).toBe(true);
411
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A3: "FALSE" })).toBe(true);
412
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "TRUE", A3: "FALSE" })).toBe(true);
413
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "FALSE", A3: "TRUE" })).toBe(false);
414
+
415
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: '="1"', A3: "99999" })).toBe(true);
416
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: '="1"', A3: '="99999"' })).toBe(false);
417
+
418
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "03/01/2020", A3: "03/01/2020" })).toBe(
419
+ true
420
+ );
421
+ expect(
422
+ evaluateCell("A1", {
423
+ A1: "=GTE(A2, A3)",
424
+ A2: "=A4+1",
425
+ A3: "=A4",
426
+ A4: "03/01/2020",
427
+ A5: "03/01/2020",
428
+ })
429
+ ).toBe(true);
430
+ expect(
431
+ evaluateCell("A1", {
432
+ A1: "=GTE(A3, A2)",
433
+ A2: "=A4+1",
434
+ A3: "=A4",
435
+ A4: "03/01/2020",
436
+ A5: "03/01/2020",
437
+ })
438
+ ).toBe(false);
439
+ expect(
440
+ evaluateCell("A1", {
441
+ A1: "=GTE(A2, A3)",
442
+ A2: "=A4+0.1",
443
+ A3: "=A4+0.2",
444
+ A4: "03/01/2020",
445
+ A5: "03/01/2020",
446
+ })
447
+ ).toBe(false);
448
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "03/01/2020", A3: "4" })).toBe(true);
449
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "03/01/2020", A3: "43891" })).toBe(true);
450
+ expect(evaluateCell("A1", { A1: "=GTE(A2, A3)", A2: "03/01/2020", A3: "100000" })).toBe(false);
451
+ });
452
+
453
+ //----------------------------------------------------------------------------
454
+ // LT
455
+ //----------------------------------------------------------------------------
456
+
457
+ test("LT: functional tests on simple arguments", () => {
458
+ expect(evaluateCell("A1", { A1: "=LT()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
459
+ expect(evaluateCell("A1", { A1: "=LT( , )" })).toBe(false);
460
+ expect(evaluateCell("A1", { A1: "=LT( , 1)" })).toBe(true);
461
+ expect(evaluateCell("A1", { A1: "=LT(1, )" })).toBe(false);
462
+ expect(evaluateCell("A1", { A1: "=LT(42, 42)" })).toBe(false);
463
+ expect(evaluateCell("A1", { A1: "=LT(42, 24)" })).toBe(false);
464
+ expect(evaluateCell("A1", { A1: "=LT(24, -22)" })).toBe(false);
465
+ expect(evaluateCell("A1", { A1: "=LT(42, 42%)" })).toBe(false);
466
+ expect(evaluateCell("A1", { A1: "=LT(0.42, 0.41)" })).toBe(false);
467
+
468
+ expect(evaluateCell("A1", { A1: '=LT("", )' })).toBe(false);
469
+ expect(evaluateCell("A1", { A1: '=LT( , "")' })).toBe(false);
470
+ expect(evaluateCell("A1", { A1: "=LT(0, )" })).toBe(false);
471
+ expect(evaluateCell("A1", { A1: "=LT( , 0)" })).toBe(false);
472
+ expect(evaluateCell("A1", { A1: '=LT("", 0)' })).toBe(false);
473
+ expect(evaluateCell("A1", { A1: '=LT(0, "")' })).toBe(true);
474
+
475
+ expect(evaluateCell("A1", { A1: '=LT("", " ")' })).toBe(true);
476
+ expect(evaluateCell("A1", { A1: '=LT(" ", "")' })).toBe(false);
477
+
478
+ expect(evaluateCell("A1", { A1: '=LT("b", "a")' })).toBe(false);
479
+ expect(evaluateCell("A1", { A1: '=LT("a", "b")' })).toBe(true);
480
+ expect(evaluateCell("A1", { A1: '=LT("KIKOU", "kikou")' })).toBe(false);
481
+ expect(evaluateCell("A1", { A1: '=LT("kikou", "KIKOU")' })).toBe(false);
482
+ expect(evaluateCell("A1", { A1: '=LT("5", "100")' })).toBe(false);
483
+ expect(evaluateCell("A1", { A1: '=LT("100", "5")' })).toBe(true);
484
+
485
+ expect(evaluateCell("A1", { A1: "=LT(TRUE, 0)" })).toBe(false);
486
+ expect(evaluateCell("A1", { A1: "=LT(0, TRUE)" })).toBe(true);
487
+ expect(evaluateCell("A1", { A1: "=LT(FALSE, 1)" })).toBe(false);
488
+ expect(evaluateCell("A1", { A1: "=LT(1, FALSE)" })).toBe(true);
489
+ expect(evaluateCell("A1", { A1: "=LT(TRUE, )" })).toBe(false);
490
+ expect(evaluateCell("A1", { A1: "=LT( , TRUE)" })).toBe(true);
491
+ expect(evaluateCell("A1", { A1: "=LT(FALSE, )" })).toBe(false);
492
+ expect(evaluateCell("A1", { A1: "=LT( , FALSE)" })).toBe(false);
493
+ expect(evaluateCell("A1", { A1: "=LT(TRUE, FALSE)" })).toBe(false);
494
+ expect(evaluateCell("A1", { A1: "=LT(FALSE, TRUE)" })).toBe(true);
495
+
496
+ expect(evaluateCell("A1", { A1: '=LT(32, "32")' })).toBe(true);
497
+ expect(evaluateCell("A1", { A1: '=LT(32, "31")' })).toBe(true);
498
+ expect(evaluateCell("A1", { A1: '=LT("32", 31)' })).toBe(false);
499
+ expect(evaluateCell("A1", { A1: '=LT("32", 99)' })).toBe(false);
500
+ expect(evaluateCell("A1", { A1: '=LT("32", 1)' })).toBe(false);
501
+ expect(evaluateCell("A1", { A1: '=LT("1", 99999)' })).toBe(false);
502
+ expect(evaluateCell("A1", { A1: '=LT("1", "99999")' })).toBe(true);
503
+ });
504
+
505
+ test("LT: functional tests on cell arguments", () => {
506
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)" })).toBe(false);
507
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "1" })).toBe(false);
508
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A3: "1" })).toBe(true);
509
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "42", A3: "42" })).toBe(false);
510
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "42", A3: "24" })).toBe(false);
511
+
512
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: '=""' })).toBe(false);
513
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A3: '=""' })).toBe(false);
514
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "0" })).toBe(false);
515
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A3: "0" })).toBe(false);
516
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: '=""', A3: "0" })).toBe(false);
517
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "0", A3: '=""' })).toBe(true);
518
+
519
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "b", A3: "a" })).toBe(false);
520
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "a", A3: "b" })).toBe(true);
521
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "A", A3: "a" })).toBe(false);
522
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "a", A3: "A" })).toBe(false);
523
+
524
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "TRUE", A3: "0" })).toBe(false);
525
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "0", A3: "TRUE" })).toBe(true);
526
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "FALSE", A3: "1" })).toBe(false);
527
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "1", A3: "FALSE" })).toBe(true);
528
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "TRUE" })).toBe(false);
529
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A3: "TRUE" })).toBe(true);
530
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "FALSE" })).toBe(false);
531
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A3: "FALSE" })).toBe(false);
532
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "TRUE", A3: "FALSE" })).toBe(false);
533
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "FALSE", A3: "TRUE" })).toBe(true);
534
+
535
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: '="1"', A3: "99999" })).toBe(false);
536
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: '="1"', A3: '="99999"' })).toBe(true);
537
+
538
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "03/01/2020", A3: "03/01/2020" })).toBe(
539
+ false
540
+ );
541
+ expect(
542
+ evaluateCell("A1", {
543
+ A1: "=LT(A2, A3)",
544
+ A2: "=A4+1",
545
+ A3: "=A4",
546
+ A4: "03/01/2020",
547
+ A5: "03/01/2020",
548
+ })
549
+ ).toBe(false);
550
+ expect(
551
+ evaluateCell("A1", {
552
+ A1: "=LT(A3, A2)",
553
+ A2: "=A4+1",
554
+ A3: "=A4",
555
+ A4: "03/01/2020",
556
+ A5: "03/01/2020",
557
+ })
558
+ ).toBe(true);
559
+ expect(
560
+ evaluateCell("A1", {
561
+ A1: "=LT(A2, A3)",
562
+ A2: "=A4+0.1",
563
+ A3: "=A4+0.2",
564
+ A4: "03/01/2020",
565
+ A5: "03/01/2020",
566
+ })
567
+ ).toBe(true);
568
+ expect(evaluateCell("A1", { A1: "=LT(A2, A3)", A2: "03/01/2020", A3: "4" })).toBe(false);
569
+ expect(evaluateCell("A1", { A1: "=LT(A3, A2)", A2: "03/01/2020", A3: "4" })).toBe(true);
570
+ });
571
+
572
+ //----------------------------------------------------------------------------
573
+ // LTE
574
+ //----------------------------------------------------------------------------
575
+
576
+ test("LTE: functional tests on simple arguments", () => {
577
+ expect(evaluateCell("A1", { A1: "=LTE()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
578
+ expect(evaluateCell("A1", { A1: "=LTE( , )" })).toBe(true);
579
+ expect(evaluateCell("A1", { A1: "=LTE( , 1)" })).toBe(true);
580
+ expect(evaluateCell("A1", { A1: "=LTE(1, )" })).toBe(false);
581
+ expect(evaluateCell("A1", { A1: "=LTE(42, 42)" })).toBe(true);
582
+ expect(evaluateCell("A1", { A1: "=LTE(42, 24)" })).toBe(false);
583
+ expect(evaluateCell("A1", { A1: "=LTE(24, -22)" })).toBe(false);
584
+ expect(evaluateCell("A1", { A1: "=LTE(42, 42%)" })).toBe(false);
585
+ expect(evaluateCell("A1", { A1: "=LTE(0.42, 0.41)" })).toBe(false);
586
+
587
+ expect(evaluateCell("A1", { A1: '=LTE("", )' })).toBe(true);
588
+ expect(evaluateCell("A1", { A1: '=LTE( , "")' })).toBe(true);
589
+ expect(evaluateCell("A1", { A1: "=LTE(0, )" })).toBe(true);
590
+ expect(evaluateCell("A1", { A1: "=LTE( , 0)" })).toBe(true);
591
+ expect(evaluateCell("A1", { A1: '=LTE("", 0)' })).toBe(false);
592
+ expect(evaluateCell("A1", { A1: '=LTE(0, "")' })).toBe(true);
593
+
594
+ expect(evaluateCell("A1", { A1: '=LTE("", " ")' })).toBe(true);
595
+ expect(evaluateCell("A1", { A1: '=LTE(" ", "")' })).toBe(false);
596
+
597
+ expect(evaluateCell("A1", { A1: '=LTE("b", "a")' })).toBe(false);
598
+ expect(evaluateCell("A1", { A1: '=LTE("a", "b")' })).toBe(true);
599
+ expect(evaluateCell("A1", { A1: '=LTE("KIKOU", "kikou")' })).toBe(true);
600
+ expect(evaluateCell("A1", { A1: '=LTE("kikou", "KIKOU")' })).toBe(true);
601
+ expect(evaluateCell("A1", { A1: '=LTE("5", "100")' })).toBe(false);
602
+ expect(evaluateCell("A1", { A1: '=LTE("100", "5")' })).toBe(true);
603
+
604
+ expect(evaluateCell("A1", { A1: "=LTE(TRUE, 0)" })).toBe(false);
605
+ expect(evaluateCell("A1", { A1: "=LTE(0, TRUE)" })).toBe(true);
606
+ expect(evaluateCell("A1", { A1: "=LTE(FALSE, 1)" })).toBe(false);
607
+ expect(evaluateCell("A1", { A1: "=LTE(1, FALSE)" })).toBe(true);
608
+ expect(evaluateCell("A1", { A1: "=LTE(TRUE, )" })).toBe(false);
609
+ expect(evaluateCell("A1", { A1: "=LTE( , TRUE)" })).toBe(true);
610
+ expect(evaluateCell("A1", { A1: "=LTE(FALSE, )" })).toBe(true);
611
+ expect(evaluateCell("A1", { A1: "=LTE( , FALSE)" })).toBe(true);
612
+ expect(evaluateCell("A1", { A1: "=LTE(TRUE, FALSE)" })).toBe(false);
613
+ expect(evaluateCell("A1", { A1: "=LTE(FALSE, TRUE)" })).toBe(true);
614
+
615
+ expect(evaluateCell("A1", { A1: '=LTE(32, "32")' })).toBe(true);
616
+ expect(evaluateCell("A1", { A1: '=LTE(32, "31")' })).toBe(true);
617
+ expect(evaluateCell("A1", { A1: '=LTE("32", 31)' })).toBe(false);
618
+ expect(evaluateCell("A1", { A1: '=LTE("32", 99)' })).toBe(false);
619
+ expect(evaluateCell("A1", { A1: '=LTE("32", 1)' })).toBe(false);
620
+
621
+ expect(evaluateCell("A1", { A1: '=LTE("1", 99999)' })).toBe(false);
622
+ expect(evaluateCell("A1", { A1: '=LTE("1", "99999")' })).toBe(true);
623
+ });
624
+
625
+ test("LTE: functional tests on cell arguments", () => {
626
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)" })).toBe(true);
627
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "1" })).toBe(false);
628
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A3: "1" })).toBe(true);
629
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "42", A3: "42" })).toBe(true);
630
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "42", A3: "24" })).toBe(false);
631
+
632
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: '=""' })).toBe(true);
633
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A3: '=""' })).toBe(true);
634
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "0" })).toBe(true);
635
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A3: "0" })).toBe(true);
636
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: '=""', A3: "0" })).toBe(false);
637
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "0", A3: '=""' })).toBe(true);
638
+
639
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "b", A3: "a" })).toBe(false);
640
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "a", A3: "b" })).toBe(true);
641
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "A", A3: "a" })).toBe(true);
642
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "a", A3: "A" })).toBe(true);
643
+
644
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "TRUE", A3: "0" })).toBe(false);
645
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "0", A3: "TRUE" })).toBe(true);
646
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "FALSE", A3: "1" })).toBe(false);
647
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "1", A3: "FALSE" })).toBe(true);
648
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "TRUE" })).toBe(false);
649
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A3: "TRUE" })).toBe(true);
650
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "FALSE" })).toBe(true);
651
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A3: "FALSE" })).toBe(true);
652
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "TRUE", A3: "FALSE" })).toBe(false);
653
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "FALSE", A3: "TRUE" })).toBe(true);
654
+
655
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: '="1"', A3: "99999" })).toBe(false);
656
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: '="1"', A3: '="99999"' })).toBe(true);
657
+
658
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "03/01/2020", A3: "03/01/2020" })).toBe(
659
+ true
660
+ );
661
+ expect(
662
+ evaluateCell("A1", {
663
+ A1: "=LTE(A2, A3)",
664
+ A2: "=A4+1",
665
+ A3: "=A4",
666
+ A4: "03/01/2020",
667
+ A5: "03/01/2020",
668
+ })
669
+ ).toBe(false);
670
+ expect(
671
+ evaluateCell("A1", {
672
+ A1: "=LTE(A3, A2)",
673
+ A2: "=A4+1",
674
+ A3: "=A4",
675
+ A4: "03/01/2020",
676
+ A5: "03/01/2020",
677
+ })
678
+ ).toBe(true);
679
+ expect(
680
+ evaluateCell("A1", {
681
+ A1: "=LTE(A2, A3)",
682
+ A2: "=A4+0.1",
683
+ A3: "=A4+0.2",
684
+ A4: "03/01/2020",
685
+ A5: "03/01/2020",
686
+ })
687
+ ).toBe(true);
688
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "03/01/2020", A3: "4" })).toBe(false);
689
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "03/01/2020", A3: "43891" })).toBe(true);
690
+ expect(evaluateCell("A1", { A1: "=LTE(A2, A3)", A2: "03/01/2020", A3: "100000" })).toBe(true);
691
+ });
692
+
693
+ //----------------------------------------------------------------------------
694
+ // MINUS
695
+ //----------------------------------------------------------------------------
696
+
697
+ test("MINUS: functional tests on simple arguments", () => {
698
+ expect(evaluateCell("A1", { A1: "=MINUS()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
699
+ expect(evaluateCell("A1", { A1: "=MINUS( , )" })).toBe(0);
700
+ expect(evaluateCell("A1", { A1: "=MINUS( , 1)" })).toBe(-1);
701
+ expect(evaluateCell("A1", { A1: "=MINUS(42, 24)" })).toBe(18);
702
+ expect(evaluateCell("A1", { A1: "=MINUS(42, -24)" })).toBe(66);
703
+ expect(evaluateCell("A1", { A1: "=MINUS(42, 0.42)" })).toBe(41.58);
704
+ expect(evaluateCell("A1", { A1: "=MINUS(42, 42%)" })).toBe(41.58);
705
+ });
706
+
707
+ test("MINUS: casting tests on simple arguments", () => {
708
+ expect(evaluateCell("A1", { A1: '=MINUS(1, "")' })).toBe(1);
709
+ expect(evaluateCell("A1", { A1: '=MINUS(1, " ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
710
+ expect(evaluateCell("A1", { A1: '=MINUS(1, "3")' })).toBe(-2);
711
+ expect(evaluateCell("A1", { A1: '=MINUS(1, "-3")' })).toBe(4);
712
+ expect(evaluateCell("A1", { A1: "=MINUS(1, TRUE)" })).toBe(0);
713
+ expect(evaluateCell("A1", { A1: "=MINUS(1, FALSE)" })).toBe(1);
714
+ expect(evaluateCell("A1", { A1: '=MINUS(1, "3%")' })).toBe(0.97);
715
+ });
716
+
717
+ test("MINUS: functional tests on cell arguments", () => {
718
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)" })).toBe(0);
719
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "1" })).toBe(1);
720
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A3: "1" })).toBe(-1);
721
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "1", A3: "42" })).toBe(-41);
722
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "-1", A3: "4.2" })).toBe(-5.2);
723
+ });
724
+
725
+ test("MINUS: casting tests on cell arguments", () => {
726
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
727
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
728
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: '"3"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
729
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: "TRUE" })).toBe(41);
730
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: "FALSE" })).toBe(42);
731
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: '=""' })).toBe(42);
732
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: '=" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
733
+ expect(evaluateCell("A1", { A1: "=MINUS(A2, A3)", A2: "42", A3: '="42"' })).toBe(0);
734
+ });
735
+
736
+ //----------------------------------------------------------------------------
737
+ // MULTIPLY
738
+ //----------------------------------------------------------------------------
739
+
740
+ test("MULTIPLY: functional tests on simple arguments", () => {
741
+ expect(evaluateCell("A1", { A1: "=MULTIPLY()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
742
+ expect(evaluateCell("A1", { A1: "=MULTIPLY( , )" })).toBe(0);
743
+ expect(evaluateCell("A1", { A1: "=MULTIPLY( , 2)" })).toBe(0);
744
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(2, 4)" })).toBe(8);
745
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(2, -3)" })).toBe(-6);
746
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(3, 0.5)" })).toBe(1.5);
747
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(2, 5%)" })).toBe(0.1);
748
+ });
749
+
750
+ test("MULTIPLY: casting tests on simple arguments", () => {
751
+ expect(evaluateCell("A1", { A1: '=MULTIPLY("", 1)' })).toBe(0);
752
+ expect(evaluateCell("A1", { A1: '=MULTIPLY(" ", 1)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
753
+ expect(evaluateCell("A1", { A1: '=MULTIPLY("4", 2)' })).toBe(8);
754
+ expect(evaluateCell("A1", { A1: '=MULTIPLY("-3", 2)' })).toBe(-6);
755
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(TRUE, 0.5)" })).toBe(0.5);
756
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(FALSE, 42)" })).toBe(0);
757
+ expect(evaluateCell("A1", { A1: '=MULTIPLY(2, "50%")' })).toBe(1);
758
+ });
759
+
760
+ test("MULTIPLY: functional tests on cell arguments", () => {
761
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)" })).toBe(0);
762
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A3: "42" })).toBe(0);
763
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: "42", A3: "2" })).toBe(84);
764
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: "4.2", A3: "-2" })).toBe(-8.4);
765
+ });
766
+
767
+ test("MULTIPLY: casting tests on cell arguments", () => {
768
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: '""', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
769
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: '" "', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
770
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: '"3"', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
771
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: "TRUE", A3: "2" })).toBe(2);
772
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: '=""', A3: "42" })).toBe(0);
773
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: '=" "', A3: "42" })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
774
+ expect(evaluateCell("A1", { A1: "=MULTIPLY(A2, A3)", A2: "42", A3: '="42"' })).toBe(1764);
775
+ });
776
+
777
+ //----------------------------------------------------------------------------
778
+ // NE
779
+ //----------------------------------------------------------------------------
780
+
781
+ test("NE: functional tests on simple arguments", () => {
782
+ expect(evaluateCell("A1", { A1: "=NE()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
783
+ expect(evaluateCell("A1", { A1: "=NE( , )" })).toBe(false);
784
+ expect(evaluateCell("A1", { A1: "=NE( , 0)" })).toBe(false);
785
+ expect(evaluateCell("A1", { A1: "=NE(42, 42)" })).toBe(false);
786
+ expect(evaluateCell("A1", { A1: "=NE(42, -42)" })).toBe(true);
787
+ expect(evaluateCell("A1", { A1: "=NE(42, 42%)" })).toBe(true);
788
+ expect(evaluateCell("A1", { A1: "=NE(0.42, 42%)" })).toBe(false);
789
+ expect(evaluateCell("A1", { A1: '=NE("", )' })).toBe(false);
790
+ expect(evaluateCell("A1", { A1: '=NE("", 0)' })).toBe(true);
791
+ expect(evaluateCell("A1", { A1: '=NE("", " ")' })).toBe(true);
792
+ expect(evaluateCell("A1", { A1: '=NE("", "kikou")' })).toBe(true);
793
+ expect(evaluateCell("A1", { A1: '=NE("KIKOU", "kikou")' })).toBe(false);
794
+ expect(evaluateCell("A1", { A1: "=NE(TRUE, 1)" })).toBe(true);
795
+ expect(evaluateCell("A1", { A1: "=NE(TRUE, )" })).toBe(true);
796
+ expect(evaluateCell("A1", { A1: "=NE(FALSE, 0)" })).toBe(true);
797
+ expect(evaluateCell("A1", { A1: "=NE(FALSE, )" })).toBe(false);
798
+ });
799
+
800
+ test("NE: functional tests on cell arguments", () => {
801
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)" })).toBe(false);
802
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A3: "0" })).toBe(false);
803
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: "42", A3: "42" })).toBe(false);
804
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: "42", A3: "-42" })).toBe(true);
805
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: "0.42", A3: "42%" })).toBe(false);
806
+
807
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A3: "test" })).toBe(true);
808
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: "TEST", A3: "test" })).toBe(false);
809
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: "TRUE", A3: "1" })).toBe(true);
810
+
811
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: '=""' })).toBe(false);
812
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: '=""', A3: "0" })).toBe(true);
813
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: "=TRUE", A3: "1" })).toBe(true);
814
+ expect(evaluateCell("A1", { A1: "=NE(A2, A3)", A2: '="42"', A3: "42" })).toBe(true);
815
+ });
816
+
817
+ //----------------------------------------------------------------------------
818
+ // POW
819
+ //----------------------------------------------------------------------------
820
+
821
+ test.each([
822
+ ["0", "0", 1],
823
+ ["0", "0.5", 0],
824
+ ["4", "0", 1],
825
+ ["0", "4", 0],
826
+ ["4", "2", 16],
827
+ ["-4", "2", 16],
828
+ ["4", "3", 64],
829
+ ["-4", "3", -64],
830
+ ["4", "0.5", 2],
831
+ ["4", "-0.5", 0.5],
832
+ ["4", "-2", 0.0625],
833
+ ])("POW(%s, %s) - %s: take 2 parameter(s), return a number", (a, b, expected) => {
834
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: a, A3: b })).toBe(expected);
835
+ });
836
+
837
+ test.each([
838
+ ["-4", "0.5"],
839
+ ["-4", "1.5"],
840
+ ["-4", "0.2"],
841
+ ])("POW(%s, %s) - error: take 2 parameter(s), return an error on parameter 2", (a, b) => {
842
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: a, A3: b })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
843
+ });
844
+
845
+ test("POW: special value testing", () => {
846
+ expect(evaluateCell("A1", { A1: "=POW()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
847
+ expect(evaluateCell("A1", { A1: "=POW( , )" })).toBe(1);
848
+ expect(evaluateCell("A1", { A1: "=POW(42, 2)" })).toBe(1764);
849
+ expect(evaluateCell("A1", { A1: "=POW( , 12)" })).toBe(0);
850
+ expect(evaluateCell("A1", { A1: "=POW(42, )" })).toBe(1);
851
+ expect(evaluateCell("A1", { A1: "=POW(42.42, TRUE)" })).toBe(42.42);
852
+ expect(evaluateCell("A1", { A1: "=POW(42.42, FALSE)" })).toBe(1);
853
+ expect(evaluateCell("A1", { A1: "=POW(TRUE, 10)" })).toBe(1);
854
+ expect(evaluateCell("A1", { A1: "=POW(FALSE, 10)" })).toBe(0);
855
+
856
+ expect(evaluateCell("A1", { A1: '=POW("" , "")' })).toBe(1);
857
+ expect(evaluateCell("A1", { A1: '=POW("" , 12)' })).toBe(0);
858
+ expect(evaluateCell("A1", { A1: '=POW(" " , 12)' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
859
+ expect(evaluateCell("A1", { A1: '=POW("42", 2)' })).toBe(1764);
860
+ expect(evaluateCell("A1", { A1: '=POW("42", "2")' })).toBe(1764);
861
+ expect(evaluateCell("A1", { A1: '=POW("42", "")' })).toBe(1);
862
+
863
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "", A3: "" })).toBe(1);
864
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "42", A3: "2" })).toBe(1764);
865
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "", A3: "12" })).toBe(0);
866
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "42", A3: "" })).toBe(1);
867
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "42.42", A3: "TRUE" })).toBe(42.42);
868
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "42.42", A3: "FALSE" })).toBe(1);
869
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "TRUE", A3: "10" })).toBe(1);
870
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: "FALSE", A3: "10" })).toBe(0);
871
+
872
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: '"42"', A3: '"12"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
873
+
874
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: '=""', A3: '="2"' })).toBe(0);
875
+ expect(evaluateCell("A1", { A1: "=POW(A2, A3)", A2: '="42"', A3: '="2"' })).toBe(1764);
876
+ });
877
+
878
+ //----------------------------------------------------------------------------
879
+ // UMINUS
880
+ //----------------------------------------------------------------------------
881
+
882
+ test("UMINUS: functional tests on simple arguments", () => {
883
+ expect(evaluateCell("A1", { A1: "=UMINUS()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
884
+ expect(evaluateCell("A1", { A1: "=UMINUS(0)" })).toBe(-0);
885
+ expect(evaluateCell("A1", { A1: "=UMINUS(2)" })).toBe(-2);
886
+ expect(evaluateCell("A1", { A1: "=UMINUS(-3)" })).toBe(3);
887
+ });
888
+
889
+ test("UMINUS: casting tests on simple arguments", () => {
890
+ expect(evaluateCell("A1", { A1: '=UMINUS("")' })).toBe(-0);
891
+ expect(evaluateCell("A1", { A1: '=UMINUS(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
892
+ expect(evaluateCell("A1", { A1: '=UMINUS("4")' })).toBe(-4);
893
+ expect(evaluateCell("A1", { A1: '=UMINUS("-3")' })).toBe(3);
894
+ expect(evaluateCell("A1", { A1: "=UMINUS(TRUE)" })).toBe(-1);
895
+ expect(evaluateCell("A1", { A1: "=UMINUS(FALSE)" })).toBe(-0);
896
+ expect(evaluateCell("A1", { A1: '=UMINUS("test")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
897
+ });
898
+
899
+ test("UMINUS: functional tests on cell arguments", () => {
900
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)" })).toBe(-0);
901
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: "0" })).toBe(-0);
902
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: "-2" })).toBe(2);
903
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: "3" })).toBe(-3);
904
+ });
905
+
906
+ test("UMINUS: casting tests on cell arguments", () => {
907
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: "TRUE" })).toBe(-1);
908
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: "FALSE" })).toBe(-0);
909
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
910
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
911
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
912
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: '=""' })).toBe(-0);
913
+ expect(evaluateCell("A1", { A1: "=UMINUS(A2)", A2: '="42"' })).toBe(-42);
914
+ });
915
+
916
+ //----------------------------------------------------------------------------
917
+ // UNARY.PERCENT
918
+ //----------------------------------------------------------------------------
919
+
920
+ test("UNARY.PERCENT: functional tests on simple arguments", () => {
921
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT()" })).toBe("#BAD_EXPR"); // @compatibility: on google sheets, return #N/A
922
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(0)" })).toBe(0);
923
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(2)" })).toBe(0.02);
924
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(-3)" })).toBe(-0.03);
925
+ });
926
+
927
+ test("UNARY.PERCENT: casting tests on simple arguments", () => {
928
+ expect(evaluateCell("A1", { A1: '=UNARY.PERCENT("")' })).toBe(0);
929
+ expect(evaluateCell("A1", { A1: '=UNARY.PERCENT(" ")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
930
+ expect(evaluateCell("A1", { A1: '=UNARY.PERCENT("4")' })).toBe(0.04);
931
+ expect(evaluateCell("A1", { A1: '=UNARY.PERCENT("-3")' })).toBe(-0.03);
932
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(3%)" })).toBe(0.0003);
933
+ expect(evaluateCell("A1", { A1: '=UNARY.PERCENT("3%")' })).toBe(0.0003);
934
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(TRUE)" })).toBe(0.01);
935
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(FALSE)" })).toBe(0);
936
+ expect(evaluateCell("A1", { A1: '=UNARY.PERCENT("test")' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
937
+ });
938
+
939
+ test("UNARY.PERCENT: functional tests on cell arguments", () => {
940
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)" })).toBe(0);
941
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: "0" })).toBe(0);
942
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: "-2" })).toBe(-0.02);
943
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: "3" })).toBe(0.03);
944
+ });
945
+
946
+ test("UNARY.PERCENT: casting tests on cell arguments", () => {
947
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: "TRUE" })).toBe(0.01);
948
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: "FALSE" })).toBe(0);
949
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: '""' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
950
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: '" "' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
951
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: '"42"' })).toBe("#ERROR"); // @compatibility: on google sheets, return #VALUE!
952
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: '=""' })).toBe(0);
953
+ expect(evaluateCell("A1", { A1: "=UNARY.PERCENT(A2)", A2: '="42"' })).toBe(0.42);
954
+ });
955
+ });