@odoo/o-spreadsheet 1.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 (199) 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 +78 -0
  12. package/readme.md +39 -0
  13. package/rollup.config.js +23 -0
  14. package/src/base_plugin.ts +102 -0
  15. package/src/components/autofill.ts +146 -0
  16. package/src/components/bottom_bar.ts +199 -0
  17. package/src/components/color_picker.ts +150 -0
  18. package/src/components/composer/autocomplete_dropdown.ts +135 -0
  19. package/src/components/composer/composer.ts +487 -0
  20. package/src/components/composer/content_editable_helper.ts +146 -0
  21. package/src/components/figures/chart.ts +70 -0
  22. package/src/components/figures/container.ts +268 -0
  23. package/src/components/figures/text_figure.ts +36 -0
  24. package/src/components/grid.ts +635 -0
  25. package/src/components/helpers/dom_helpers.ts +7 -0
  26. package/src/components/helpers/drag_and_drop.ts +17 -0
  27. package/src/components/icons.ts +36 -0
  28. package/src/components/index.ts +1 -0
  29. package/src/components/menu.ts +288 -0
  30. package/src/components/overlay.ts +457 -0
  31. package/src/components/scrollbar.ts +22 -0
  32. package/src/components/selection_input.ts +168 -0
  33. package/src/components/side_panel/cell_is_rule_editor.ts +169 -0
  34. package/src/components/side_panel/chart_panel.ts +104 -0
  35. package/src/components/side_panel/color_scale_rule_editor.ts +145 -0
  36. package/src/components/side_panel/conditional_formatting.ts +396 -0
  37. package/src/components/side_panel/side_panel.ts +127 -0
  38. package/src/components/side_panel/translations_terms.ts +45 -0
  39. package/src/components/spreadsheet.ts +198 -0
  40. package/src/components/top_bar.ts +535 -0
  41. package/src/constants.ts +26 -0
  42. package/src/data.ts +149 -0
  43. package/src/fonts.ts +41 -0
  44. package/src/formulas/compiler.ts +258 -0
  45. package/src/formulas/composer_tokenizer.ts +70 -0
  46. package/src/formulas/index.ts +15 -0
  47. package/src/formulas/normalize.ts +52 -0
  48. package/src/formulas/parser.ts +280 -0
  49. package/src/formulas/range_tokenizer.ts +97 -0
  50. package/src/formulas/tokenizer.ts +242 -0
  51. package/src/functions/arguments.ts +114 -0
  52. package/src/functions/dates.ts +302 -0
  53. package/src/functions/helpers.ts +592 -0
  54. package/src/functions/index.ts +52 -0
  55. package/src/functions/module_database.ts +282 -0
  56. package/src/functions/module_date.ts +743 -0
  57. package/src/functions/module_info.ts +69 -0
  58. package/src/functions/module_logical.ts +208 -0
  59. package/src/functions/module_lookup.ts +185 -0
  60. package/src/functions/module_math.ts +1252 -0
  61. package/src/functions/module_operators.ts +291 -0
  62. package/src/functions/module_statistical.ts +882 -0
  63. package/src/functions/module_text.ts +370 -0
  64. package/src/helpers/color.ts +30 -0
  65. package/src/helpers/coordinates.ts +71 -0
  66. package/src/helpers/grid_manipulation.ts +68 -0
  67. package/src/helpers/index.ts +7 -0
  68. package/src/helpers/misc.ts +76 -0
  69. package/src/helpers/numbers.ts +117 -0
  70. package/src/helpers/uuid.ts +19 -0
  71. package/src/helpers/zones.ts +263 -0
  72. package/src/history.ts +186 -0
  73. package/src/index.ts +84 -0
  74. package/src/model.ts +261 -0
  75. package/src/plugins/autofill.ts +412 -0
  76. package/src/plugins/chart.ts +404 -0
  77. package/src/plugins/clipboard.ts +461 -0
  78. package/src/plugins/conditional_format.ts +445 -0
  79. package/src/plugins/core.ts +1502 -0
  80. package/src/plugins/edition.ts +157 -0
  81. package/src/plugins/evaluation.ts +428 -0
  82. package/src/plugins/figures.ts +123 -0
  83. package/src/plugins/formatting.ts +630 -0
  84. package/src/plugins/highlight.ts +187 -0
  85. package/src/plugins/index.ts +32 -0
  86. package/src/plugins/merge.ts +524 -0
  87. package/src/plugins/renderer.ts +571 -0
  88. package/src/plugins/selection.ts +562 -0
  89. package/src/plugins/selection_inputs.ts +326 -0
  90. package/src/registries/autofill_modifiers.ts +76 -0
  91. package/src/registries/autofill_rules.ts +98 -0
  92. package/src/registries/figure_registry.ts +30 -0
  93. package/src/registries/index.ts +7 -0
  94. package/src/registries/menu_items_registry.ts +110 -0
  95. package/src/registries/menus/cell_menu_registry.ts +79 -0
  96. package/src/registries/menus/col_menu_registry.ts +63 -0
  97. package/src/registries/menus/index.ts +6 -0
  98. package/src/registries/menus/menu_items_actions.ts +425 -0
  99. package/src/registries/menus/row_menu_registry.ts +63 -0
  100. package/src/registries/menus/sheet_menu_registry.ts +75 -0
  101. package/src/registries/menus/topbar_menu_registry.ts +204 -0
  102. package/src/registries/side_panel_registry.ts +26 -0
  103. package/src/registries/topbar_component_registry.ts +12 -0
  104. package/src/registry.ts +51 -0
  105. package/src/translation.ts +44 -0
  106. package/src/types/autofill.ts +48 -0
  107. package/src/types/chart.ts +26 -0
  108. package/src/types/commands.ts +716 -0
  109. package/src/types/conditional_formatting.ts +124 -0
  110. package/src/types/env.ts +13 -0
  111. package/src/types/functions.ts +35 -0
  112. package/src/types/getters.ts +103 -0
  113. package/src/types/index.ts +20 -0
  114. package/src/types/misc.ts +143 -0
  115. package/src/types/rendering.ts +41 -0
  116. package/src/types/workbook_data.ts +62 -0
  117. package/tests/__mocks__/uuid.ts +7 -0
  118. package/tests/canvas.mock.ts +34 -0
  119. package/tests/components/__mocks__/content_editable_helper.ts +79 -0
  120. package/tests/components/__mocks__/scrollbar.ts +18 -0
  121. package/tests/components/__snapshots__/autocomplete_dropdown_test.ts.snap +29 -0
  122. package/tests/components/__snapshots__/bottom_bar_test.ts.snap +75 -0
  123. package/tests/components/__snapshots__/context_menu_test.ts.snap +88 -0
  124. package/tests/components/__snapshots__/grid_test.ts.snap +60 -0
  125. package/tests/components/__snapshots__/spreadsheet_test.ts.snap +455 -0
  126. package/tests/components/__snapshots__/top_bar_test.ts.snap +705 -0
  127. package/tests/components/autocomplete_dropdown_test.ts +315 -0
  128. package/tests/components/autofill_test.ts +167 -0
  129. package/tests/components/bottom_bar_test.ts +262 -0
  130. package/tests/components/chart_side_panel_test.ts +123 -0
  131. package/tests/components/composer_test.ts +400 -0
  132. package/tests/components/context_menu_test.ts +825 -0
  133. package/tests/components/grid_manipulation_test.ts +163 -0
  134. package/tests/components/grid_test.ts +581 -0
  135. package/tests/components/overlay_test.ts +541 -0
  136. package/tests/components/selection_input_test.ts +259 -0
  137. package/tests/components/side_panel_test.ts +148 -0
  138. package/tests/components/spreadsheet_test.ts +194 -0
  139. package/tests/components/top_bar_test.ts +427 -0
  140. package/tests/data_test.ts +175 -0
  141. package/tests/dom_helper.ts +42 -0
  142. package/tests/formulas/__snapshots__/compiler_test.ts.snap +302 -0
  143. package/tests/formulas/compiler_test.ts +266 -0
  144. package/tests/formulas/composer_tokenizer_test.ts +137 -0
  145. package/tests/formulas/expressions_test.ts +57 -0
  146. package/tests/formulas/formulas_test.ts +80 -0
  147. package/tests/formulas/normalize_test.ts +82 -0
  148. package/tests/formulas/parser_test.ts +224 -0
  149. package/tests/formulas/range_tokenizer_test.ts +187 -0
  150. package/tests/formulas/tokenizer_test.ts +164 -0
  151. package/tests/functions/arguments_test.ts +141 -0
  152. package/tests/functions/dates_test.ts +1081 -0
  153. package/tests/functions/functions_test.ts +53 -0
  154. package/tests/functions/helper_test.ts +98 -0
  155. package/tests/functions/module_database_test.ts +311 -0
  156. package/tests/functions/module_date_test.ts +941 -0
  157. package/tests/functions/module_info_test.ts +139 -0
  158. package/tests/functions/module_logical_test.ts +369 -0
  159. package/tests/functions/module_lookup_test.ts +541 -0
  160. package/tests/functions/module_math_test.ts +2482 -0
  161. package/tests/functions/module_operators_test.ts +955 -0
  162. package/tests/functions/module_statistical_test.ts +2014 -0
  163. package/tests/functions/module_text_test.ts +667 -0
  164. package/tests/helpers/coordinates_test.ts +25 -0
  165. package/tests/helpers/misc_test.ts +95 -0
  166. package/tests/helpers/numbers_test.ts +196 -0
  167. package/tests/helpers/zones_test.ts +97 -0
  168. package/tests/helpers.ts +384 -0
  169. package/tests/menu_items_registry_test.ts +540 -0
  170. package/tests/model/plugins/__snapshots__/chart_test.ts.snap +90 -0
  171. package/tests/model/plugins/chart_test.ts +562 -0
  172. package/tests/model_test.ts +82 -0
  173. package/tests/plugins/__snapshots__/conditional_formatting_test.ts.snap +131 -0
  174. package/tests/plugins/__snapshots__/renderer_test.ts.snap +371 -0
  175. package/tests/plugins/autofill_test.ts +457 -0
  176. package/tests/plugins/borders_test.ts +295 -0
  177. package/tests/plugins/clipboard_test.ts +1180 -0
  178. package/tests/plugins/conditional_formatting_test.ts +1253 -0
  179. package/tests/plugins/core_test.ts +614 -0
  180. package/tests/plugins/edition_test.ts +100 -0
  181. package/tests/plugins/evaluation_async_test.ts +332 -0
  182. package/tests/plugins/evaluation_dates_test.ts +79 -0
  183. package/tests/plugins/evaluation_test.ts +901 -0
  184. package/tests/plugins/figures_test.ts +327 -0
  185. package/tests/plugins/formatting_test.ts +391 -0
  186. package/tests/plugins/grid_manipulation_test.ts +1366 -0
  187. package/tests/plugins/highlight_test.ts +413 -0
  188. package/tests/plugins/history_test.ts +142 -0
  189. package/tests/plugins/import_export_test.ts +276 -0
  190. package/tests/plugins/merges_test.ts +490 -0
  191. package/tests/plugins/navigation_test.ts +181 -0
  192. package/tests/plugins/plugins/evaluation_test.ts +111 -0
  193. package/tests/plugins/renderer_test.ts +598 -0
  194. package/tests/plugins/resizing_test.ts +152 -0
  195. package/tests/plugins/selection_input_test.ts +409 -0
  196. package/tests/plugins/selection_test.ts +442 -0
  197. package/tests/plugins/sheets_test.ts +643 -0
  198. package/tests/plugins/style_test.ts +90 -0
  199. package/tsconfig.json +22 -0
@@ -0,0 +1,541 @@
1
+ import { ColResizer, RowResizer } from "../../src/components/overlay";
2
+ import {
3
+ DEFAULT_CELL_HEIGHT,
4
+ DEFAULT_CELL_WIDTH,
5
+ MIN_COL_WIDTH,
6
+ MIN_ROW_HEIGHT,
7
+ } from "../../src/constants";
8
+ import { lettersToNumber, toXC } from "../../src/helpers/index";
9
+ import { Model } from "../../src/model";
10
+ import { SelectionMode } from "../../src/plugins/selection";
11
+ import "../canvas.mock";
12
+ import { triggerMouseEvent } from "../dom_helper";
13
+ import { getActiveXc, GridParent, makeTestFixture, nextTick } from "../helpers";
14
+
15
+ let fixture: HTMLElement;
16
+ let model: Model;
17
+
18
+ ColResizer.prototype._getMaxSize = () => 1000;
19
+ RowResizer.prototype._getMaxSize = () => 1000;
20
+
21
+ function fillData() {
22
+ for (let i = 0; i < 8; i++) {
23
+ model.dispatch("SET_VALUE", { xc: toXC(i, i), text: "i" });
24
+ }
25
+ }
26
+
27
+ beforeEach(async () => {
28
+ fixture = makeTestFixture();
29
+ model = new Model({
30
+ sheets: [
31
+ {
32
+ colNumber: 10,
33
+ rowNumber: 10,
34
+ },
35
+ ],
36
+ });
37
+ const parent = new GridParent(model);
38
+ await parent.mount(fixture);
39
+ });
40
+
41
+ afterEach(() => {
42
+ fixture.remove();
43
+ });
44
+
45
+ /**
46
+ * Select a column
47
+ * @param letter Name of the column to click on (Starts at 'A')
48
+ * @param extra shiftKey, ctrlKey
49
+ */
50
+ function selectColumn(letter: string, extra: any = {}) {
51
+ const index = lettersToNumber(letter);
52
+ const x = model["workbook"].activeSheet.cols[index].start + 1;
53
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousedown", x, 10, extra);
54
+ triggerMouseEvent(window, "mouseup", x, 10);
55
+ }
56
+ /**
57
+ * Resize a column
58
+ * @param letter Name of the column to resize (Starts at 'A')
59
+ * @param delta Size to add (or remove if delta < 0)
60
+ */
61
+ async function resizeColumn(letter: string, delta: number) {
62
+ const index = lettersToNumber(letter);
63
+ const x = model["workbook"].activeSheet.cols[index].start + 1;
64
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousemove", x, 10);
65
+ await nextTick();
66
+ triggerMouseEvent(".o-overlay .o-col-resizer .o-handle", "mousedown", x, 10);
67
+ triggerMouseEvent(window, "mousemove", x + delta, 10);
68
+ triggerMouseEvent(window, "mouseup", x + delta, 10);
69
+ await nextTick();
70
+ }
71
+ /**
72
+ * Trigger a double click on a column
73
+ * @param letter Name of the column to double click on (Starts at 'A')
74
+ */
75
+ async function dblClickColumn(letter: string) {
76
+ const index = lettersToNumber(letter);
77
+ const x = model["workbook"].activeSheet.cols[index].end;
78
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousemove", x, 10);
79
+ await nextTick();
80
+ triggerMouseEvent(".o-overlay .o-col-resizer .o-handle", "dblclick", x, 10);
81
+ }
82
+ /**
83
+ * Select a row
84
+ * @param index Number of the row to click on (Starts at 0)
85
+ * @param extra shiftKey, ctrlKey
86
+ */
87
+ function selectRow(index: number, extra: any = {}) {
88
+ const y = model["workbook"].activeSheet.rows[index].start + 1;
89
+ triggerMouseEvent(".o-overlay .o-row-resizer", "mousedown", 10, y, extra);
90
+ triggerMouseEvent(window, "mouseup", 10, y);
91
+ }
92
+ /**
93
+ * Resize a row
94
+ * @param index Number of the row to resize (Starts at 0)
95
+ * @param delta Size to add (or remove if delta < 0)
96
+ */
97
+ async function resizeRow(index: number, delta: number) {
98
+ const y = model["workbook"].activeSheet.rows[index].start + 1;
99
+ triggerMouseEvent(".o-overlay .o-row-resizer", "mousemove", 10, y);
100
+ await nextTick();
101
+ triggerMouseEvent(".o-overlay .o-row-resizer .o-handle", "mousedown", 10, y);
102
+ triggerMouseEvent(window, "mousemove", 10, y + delta);
103
+ triggerMouseEvent(window, "mouseup", 10, y + delta);
104
+ await nextTick();
105
+ }
106
+ /**
107
+ * Trigger a double click on a row
108
+ * @param letter Number of the row to double click on (Starts at 0)
109
+ */
110
+ async function dblClickRow(index: number) {
111
+ const y = model["workbook"].activeSheet.rows[index].end;
112
+ triggerMouseEvent(".o-overlay .o-row-resizer", "mousemove", 10, y);
113
+ await nextTick();
114
+
115
+ triggerMouseEvent(".o-overlay .o-row-resizer .o-handle", "dblclick", 10, y);
116
+ }
117
+
118
+ describe("Resizer component", () => {
119
+ test("can click on a header to select a column", async () => {
120
+ selectColumn("C");
121
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 2, top: 0, right: 2, bottom: 9 });
122
+ expect(getActiveXc(model)).toBe("C1");
123
+ });
124
+
125
+ test("click on a header to select a column changes the selection mode", async () => {
126
+ const index = lettersToNumber("C");
127
+ const x = model["workbook"].activeSheet.cols[index].start + 1;
128
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.idle);
129
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousedown", x, 10);
130
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.selecting);
131
+ triggerMouseEvent(window, "mouseup", x, 10);
132
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.idle);
133
+ });
134
+
135
+ test("click on a header with CTRL to select a column changes the selection mode", async () => {
136
+ const index = lettersToNumber("C");
137
+ const x = model["workbook"].activeSheet.cols[index].start + 1;
138
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.idle);
139
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousedown", x, 10, { ctrlKey: true });
140
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.expanding);
141
+ triggerMouseEvent(window, "mouseup", x, 10, { ctrlKey: true });
142
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.readyToExpand);
143
+ });
144
+
145
+ test("resizing a column does not change the selection mode", async () => {
146
+ const index = lettersToNumber("C");
147
+ const x = model["workbook"].activeSheet.cols[index].start + 1;
148
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousemove", x, 10);
149
+ await nextTick();
150
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.idle);
151
+ triggerMouseEvent(".o-overlay .o-col-resizer .o-handle", "mousedown", x, 10);
152
+ triggerMouseEvent(window, "mousemove", x + 50, 10);
153
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.idle);
154
+ triggerMouseEvent(window, "mouseup", x + 50, 10);
155
+ await nextTick();
156
+ expect(model.getters.getSelectionMode()).toBe(SelectionMode.idle);
157
+ });
158
+
159
+ test("can click on a row-header to select a row", async () => {
160
+ selectRow(2);
161
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 0, top: 2, right: 9, bottom: 2 });
162
+ expect(getActiveXc(model)).toBe("A3");
163
+ });
164
+
165
+ test("can select multiple rows/cols", async () => {
166
+ selectRow(2);
167
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 0, top: 2, right: 9, bottom: 2 });
168
+
169
+ selectRow(3, { ctrlKey: true });
170
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 0, top: 2, right: 9, bottom: 2 });
171
+ expect(model.getters.getSelectedZones()[1]).toEqual({ left: 0, top: 3, right: 9, bottom: 3 });
172
+ expect(getActiveXc(model)).toBe("A4");
173
+
174
+ selectColumn("C", { ctrlKey: true });
175
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 0, top: 2, right: 9, bottom: 2 });
176
+ expect(model.getters.getSelectedZones()[1]).toEqual({ left: 0, top: 3, right: 9, bottom: 3 });
177
+ expect(model.getters.getSelectedZones()[2]).toEqual({ left: 2, top: 0, right: 2, bottom: 9 });
178
+ expect(getActiveXc(model)).toBe("C1");
179
+
180
+ selectColumn("C");
181
+ expect(model.getters.getSelectedZones().length).toBe(1);
182
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 2, top: 0, right: 2, bottom: 9 });
183
+ expect(getActiveXc(model)).toBe("C1");
184
+ });
185
+
186
+ test("Can resize a column", async () => {
187
+ await resizeColumn("C", 50);
188
+ expect(model["workbook"].activeSheet.cols[1].size).toBe(
189
+ model["workbook"].activeSheet.cols[0].size + 50
190
+ );
191
+ expect(model["workbook"].activeSheet.cols[2].size).toBe(
192
+ model["workbook"].activeSheet.cols[0].size
193
+ );
194
+ });
195
+
196
+ test("Can resize a row", async () => {
197
+ await resizeRow(2, 50);
198
+ expect(model["workbook"].activeSheet.rows[1].size).toBe(
199
+ model["workbook"].activeSheet.rows[0].size + 50
200
+ );
201
+ expect(model["workbook"].activeSheet.rows[2].size).toBe(
202
+ model["workbook"].activeSheet.rows[0].size
203
+ );
204
+ });
205
+
206
+ test("Can resize multiples columns", async () => {
207
+ selectColumn("C");
208
+ selectColumn("D", { ctrlKey: true });
209
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 2, top: 0, right: 2, bottom: 9 });
210
+ expect(model.getters.getSelectedZones()[1]).toEqual({ left: 3, top: 0, right: 3, bottom: 9 });
211
+ expect(getActiveXc(model)).toBe("D1");
212
+
213
+ await resizeColumn("D", 50);
214
+ expect(model["workbook"].activeSheet.cols[1].size).toBe(
215
+ model["workbook"].activeSheet.cols[0].size
216
+ );
217
+ expect(model["workbook"].activeSheet.cols[2].size).toBe(
218
+ model["workbook"].activeSheet.cols[0].size + 50
219
+ );
220
+ expect(model["workbook"].activeSheet.cols[3].size).toBe(
221
+ model["workbook"].activeSheet.cols[0].size + 50
222
+ );
223
+ expect(model["workbook"].activeSheet.cols[4].size).toBe(
224
+ model["workbook"].activeSheet.cols[0].size
225
+ );
226
+ expect(model["workbook"].activeSheet.cols[4].start).toBe(
227
+ model["workbook"].activeSheet.cols[0].size * 4 + 100
228
+ );
229
+ });
230
+
231
+ test("Can resize multiples rows", async () => {
232
+ selectRow(2);
233
+ selectRow(3, { ctrlKey: true });
234
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 0, top: 2, right: 9, bottom: 2 });
235
+ expect(model.getters.getSelectedZones()[1]).toEqual({ left: 0, top: 3, right: 9, bottom: 3 });
236
+ expect(getActiveXc(model)).toBe("A4");
237
+
238
+ await resizeRow(3, 50);
239
+ expect(model["workbook"].activeSheet.rows[1].size).toBe(
240
+ model["workbook"].activeSheet.rows[0].size
241
+ );
242
+ expect(model["workbook"].activeSheet.rows[2].size).toBe(
243
+ model["workbook"].activeSheet.rows[0].size + 50
244
+ );
245
+ expect(model["workbook"].activeSheet.rows[3].size).toBe(
246
+ model["workbook"].activeSheet.rows[0].size + 50
247
+ );
248
+ expect(model["workbook"].activeSheet.rows[4].size).toBe(
249
+ model["workbook"].activeSheet.rows[0].size
250
+ );
251
+ expect(model["workbook"].activeSheet.rows[4].start).toBe(
252
+ model["workbook"].activeSheet.rows[0].size * 4 + 100
253
+ );
254
+ });
255
+
256
+ test("can select the entire sheet", async () => {
257
+ triggerMouseEvent(".o-overlay .all", "mousedown", 5, 5);
258
+ expect(model.getters.getSelectedZones()[0]).toEqual({ left: 0, top: 0, right: 9, bottom: 9 });
259
+ expect(getActiveXc(model)).toBe("A1");
260
+ });
261
+
262
+ test("Mousemove hover something else than a header", async () => {
263
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousemove", -10, 10);
264
+ expect(fixture.querySelector("o-handle")).toBeNull();
265
+
266
+ triggerMouseEvent(".o-overlay .o-row-resizer", "mousemove", 10, -10);
267
+ expect(fixture.querySelector("o-handle")).toBeNull();
268
+
269
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousemove", 20, 10);
270
+ expect(fixture.querySelector("o-handle")).toBeNull();
271
+
272
+ triggerMouseEvent(".o-overlay .o-row-resizer", "mousemove", 10, 12);
273
+ expect(fixture.querySelector("o-handle")).toBeNull();
274
+ });
275
+
276
+ test("Min boundaries resizing columns", async () => {
277
+ await resizeColumn("C", -10000000);
278
+ expect(model["workbook"].activeSheet.cols[1].size).toBe(MIN_COL_WIDTH);
279
+ });
280
+
281
+ test("Min boundaries resizing rows", async () => {
282
+ await resizeRow(2, -10000000);
283
+ expect(model["workbook"].activeSheet.rows[1].size).toBe(MIN_ROW_HEIGHT);
284
+ });
285
+
286
+ test("Max boundaries resizing columns", async () => {
287
+ await resizeColumn("C", 10000000);
288
+ expect(model["workbook"].activeSheet.cols[1].size).toBe(904);
289
+ });
290
+
291
+ test("Max boundaries resizing rows", async () => {
292
+ await resizeRow(2, 10000000);
293
+ expect(model["workbook"].activeSheet.rows[1].size).toBe(977);
294
+ });
295
+
296
+ test("Double click: Modify the size of a column", async () => {
297
+ model.dispatch("SET_VALUE", { xc: "B2", text: "b2" });
298
+ await dblClickColumn("B");
299
+ expect(model["workbook"].activeSheet.cols[1].size).toBe(1006);
300
+ });
301
+
302
+ test("Double click on column then undo, then redo", async () => {
303
+ model.dispatch("SET_VALUE", { xc: "C2", text: "C2" });
304
+ model.dispatch("SET_VALUE", { xc: "D2", text: "D2" });
305
+ selectColumn("C");
306
+ selectColumn("D", { ctrlKey: true });
307
+ await dblClickColumn("D");
308
+ const sheet = model.getters.getActiveSheet();
309
+ const initialSize = model.getters.getCol(sheet, 0).size;
310
+ expect(model.getters.getCol(sheet, 1).size).toBe(initialSize);
311
+ expect(model.getters.getCol(sheet, 2).size).toBe(1006);
312
+ expect(model.getters.getCol(sheet, 3).size).toBe(1006);
313
+ expect(model.getters.getCol(sheet, 4).size).toBe(initialSize);
314
+ expect(model.getters.getCol(sheet, 4).start).toBe(initialSize * 2 + 2012);
315
+ model.dispatch("UNDO");
316
+ expect(model.getters.getCol(sheet, 1).size).toBe(initialSize);
317
+ expect(model.getters.getCol(sheet, 2).size).toBe(initialSize);
318
+ expect(model.getters.getCol(sheet, 3).size).toBe(initialSize);
319
+ expect(model.getters.getCol(sheet, 4).size).toBe(initialSize);
320
+ expect(model.getters.getCol(sheet, 4).start).toBe(initialSize * 4);
321
+ model.dispatch("REDO");
322
+ expect(model.getters.getCol(sheet, 1).size).toBe(initialSize);
323
+ expect(model.getters.getCol(sheet, 2).size).toBe(1006);
324
+ expect(model.getters.getCol(sheet, 3).size).toBe(1006);
325
+ expect(model.getters.getCol(sheet, 4).size).toBe(initialSize);
326
+ expect(model.getters.getCol(sheet, 4).start).toBe(initialSize * 2 + 2012);
327
+ });
328
+
329
+ test("Double click: Modify the size of a row", async () => {
330
+ model.dispatch("SET_VALUE", { xc: "B2", text: "b2" });
331
+ await dblClickRow(1);
332
+ expect(model["workbook"].activeSheet.rows[1].size).toBe(21);
333
+ });
334
+
335
+ test("Double click on rows then undo, then redo", async () => {
336
+ fillData();
337
+ model.dispatch("SET_VALUE", { xc: "C3", text: "C3" });
338
+ model.dispatch("SET_VALUE", { xc: "C4", text: "C4" });
339
+ selectRow(2);
340
+ selectRow(3, { ctrlKey: true });
341
+ await dblClickRow(2);
342
+ const sheet = model.getters.getActiveSheet();
343
+ const initialSize = model.getters.getRow(sheet, 0).size;
344
+ expect(model.getters.getRow(sheet, 1).size).toBe(initialSize);
345
+ expect(model.getters.getRow(sheet, 2).size).toBe(21);
346
+ expect(model.getters.getRow(sheet, 3).size).toBe(21);
347
+ expect(model.getters.getRow(sheet, 4).size).toBe(initialSize);
348
+ expect(model.getters.getRow(sheet, 4).start).toBe(initialSize * 2 + 21 * 2);
349
+ model.dispatch("UNDO");
350
+ expect(model.getters.getRow(sheet, 1).size).toBe(initialSize);
351
+ expect(model.getters.getRow(sheet, 2).size).toBe(initialSize);
352
+ expect(model.getters.getRow(sheet, 3).size).toBe(initialSize);
353
+ expect(model.getters.getRow(sheet, 4).size).toBe(initialSize);
354
+ expect(model.getters.getRow(sheet, 4).start).toBe(initialSize * 4);
355
+ model.dispatch("REDO");
356
+ expect(model.getters.getRow(sheet, 1).size).toBe(initialSize);
357
+ expect(model.getters.getRow(sheet, 2).size).toBe(21);
358
+ expect(model.getters.getRow(sheet, 3).size).toBe(21);
359
+ expect(model.getters.getRow(sheet, 4).size).toBe(initialSize);
360
+ expect(model.getters.getRow(sheet, 4).start).toBe(initialSize * 2 + 21 * 2);
361
+ });
362
+
363
+ test("Select B, shift D then BCD selected", () => {
364
+ selectColumn("B");
365
+ selectColumn("D", { shiftKey: true });
366
+ expect(model.getters.getActiveCols()).toEqual(new Set([1, 2, 3]));
367
+ });
368
+
369
+ test("Select B, ctrl D then BD selected", () => {
370
+ selectColumn("B");
371
+ selectColumn("D", { ctrlKey: true });
372
+ expect(model.getters.getActiveCols()).toEqual(new Set([1, 3]));
373
+ });
374
+
375
+ test("Select 2, shift 4 then 234 selected", () => {
376
+ selectRow(1);
377
+ selectRow(3, { shiftKey: true });
378
+ expect(model.getters.getActiveRows()).toEqual(new Set([1, 2, 3]));
379
+ });
380
+
381
+ test("Select 2, ctrl 4 then 24 selected", () => {
382
+ selectRow(1);
383
+ selectRow(3, { ctrlKey: true });
384
+ expect(model.getters.getActiveRows()).toEqual(new Set([1, 3]));
385
+ });
386
+
387
+ test("Select B, shift D, shift A then AB selected", () => {
388
+ selectColumn("B");
389
+ selectColumn("D", { shiftKey: true });
390
+ selectColumn("A", { shiftKey: true });
391
+ expect(model.getters.getActiveCols()).toEqual(new Set([0, 1]));
392
+ });
393
+
394
+ test("Select 2, shift 4, shift 1 then 12 selected", () => {
395
+ selectRow(1);
396
+ selectRow(3, { shiftKey: true });
397
+ selectRow(0, { shiftKey: true });
398
+ expect(model.getters.getActiveRows()).toEqual(new Set([0, 1]));
399
+ });
400
+
401
+ test("Select A, shift C, ctrl E then ABCE selected", () => {
402
+ selectColumn("A");
403
+ selectColumn("C", { shiftKey: true });
404
+ selectColumn("E", { ctrlKey: true });
405
+ expect(model.getters.getActiveCols()).toEqual(new Set([0, 1, 2, 4]));
406
+ });
407
+
408
+ test("Select 1, shift 3, ctrl 5 then 1235 selected", () => {
409
+ selectRow(0);
410
+ selectRow(2, { shiftKey: true });
411
+ selectRow(4, { ctrlKey: true });
412
+ expect(model.getters.getActiveRows()).toEqual(new Set([0, 1, 2, 4]));
413
+ });
414
+
415
+ test("Select A, shift C, ctrl E, shift G then ABCEFG selected", () => {
416
+ selectColumn("A");
417
+ selectColumn("C", { shiftKey: true });
418
+ selectColumn("E", { ctrlKey: true });
419
+ selectColumn("G", { shiftKey: true });
420
+
421
+ expect(model.getters.getActiveCols()).toEqual(new Set([0, 1, 2, 4, 5, 6]));
422
+ });
423
+
424
+ test("Select 1, shift 3, ctrl 5, shift 7 then 123567 selected", () => {
425
+ selectRow(0);
426
+ selectRow(2, { shiftKey: true });
427
+ selectRow(4, { ctrlKey: true });
428
+ selectRow(6, { shiftKey: true });
429
+ expect(model.getters.getActiveRows()).toEqual(new Set([0, 1, 2, 4, 5, 6]));
430
+ });
431
+
432
+ test("Select A, shift C, ctrl 1, shift 3 then ABC123 selected", () => {
433
+ selectColumn("A");
434
+ selectColumn("C", { shiftKey: true });
435
+ selectRow(0, { ctrlKey: true });
436
+ selectRow(2, { shiftKey: true });
437
+
438
+ expect(model.getters.getActiveCols()).toEqual(new Set([0, 1, 2]));
439
+ expect(model.getters.getActiveRows()).toEqual(new Set([0, 1, 2]));
440
+ });
441
+
442
+ test("Select A, ctrl C, shift E then ACDE selected", () => {
443
+ selectColumn("A");
444
+ selectColumn("C", { ctrlKey: true });
445
+ selectColumn("E", { shiftKey: true });
446
+ expect(model.getters.getActiveCols()).toEqual(new Set([0, 2, 3, 4]));
447
+ });
448
+
449
+ test("Select 1, ctrl 3, shift 5 then 1345 selected", () => {
450
+ selectRow(0);
451
+ selectRow(2, { ctrlKey: true });
452
+ selectRow(4, { shiftKey: true });
453
+ expect(model.getters.getActiveRows()).toEqual(new Set([0, 2, 3, 4]));
454
+ });
455
+
456
+ test("Select ABC E, dblclick E then resize all", async () => {
457
+ fillData();
458
+ selectColumn("A");
459
+ selectColumn("C", { shiftKey: true });
460
+ selectColumn("E", { ctrlKey: true });
461
+ await dblClickColumn("E");
462
+ expect(model["workbook"].activeSheet.cols[0].size).toBe(1006);
463
+ expect(model["workbook"].activeSheet.cols[1].size).toBe(1006);
464
+ expect(model["workbook"].activeSheet.cols[2].size).toBe(1006);
465
+ expect(model["workbook"].activeSheet.cols[3].size).toBe(DEFAULT_CELL_WIDTH);
466
+ expect(model["workbook"].activeSheet.cols[4].size).toBe(1006);
467
+ });
468
+
469
+ test("Select ABC E, dblclick F then resize only F", async () => {
470
+ fillData();
471
+ selectColumn("A");
472
+ selectColumn("C", { shiftKey: true });
473
+ selectColumn("E", { ctrlKey: true });
474
+ await dblClickColumn("F");
475
+ expect(model["workbook"].activeSheet.cols[0].size).toBe(DEFAULT_CELL_WIDTH);
476
+ expect(model["workbook"].activeSheet.cols[1].size).toBe(DEFAULT_CELL_WIDTH);
477
+ expect(model["workbook"].activeSheet.cols[2].size).toBe(DEFAULT_CELL_WIDTH);
478
+ expect(model["workbook"].activeSheet.cols[3].size).toBe(DEFAULT_CELL_WIDTH);
479
+ expect(model["workbook"].activeSheet.cols[4].size).toBe(DEFAULT_CELL_WIDTH);
480
+ expect(model["workbook"].activeSheet.cols[5].size).toBe(1006);
481
+ });
482
+
483
+ test("Select 123 5, dblclick 5 then resize all", async () => {
484
+ fillData();
485
+ selectRow(0);
486
+ selectRow(2, { shiftKey: true });
487
+ selectRow(4, { ctrlKey: true });
488
+ await dblClickRow(4);
489
+ expect(model["workbook"].activeSheet.rows[0].size).toBe(21);
490
+ expect(model["workbook"].activeSheet.rows[1].size).toBe(21);
491
+ expect(model["workbook"].activeSheet.rows[2].size).toBe(21);
492
+ expect(model["workbook"].activeSheet.rows[3].size).toBe(DEFAULT_CELL_HEIGHT);
493
+ expect(model["workbook"].activeSheet.rows[4].size).toBe(21);
494
+ });
495
+
496
+ test("Select 123 5, dblclick 6 then resize only 6", async () => {
497
+ fillData();
498
+ selectRow(0);
499
+ selectRow(2, { shiftKey: true });
500
+ selectRow(4, { ctrlKey: true });
501
+ await dblClickRow(5);
502
+ expect(model["workbook"].activeSheet.rows[0].size).toBe(DEFAULT_CELL_HEIGHT);
503
+ expect(model["workbook"].activeSheet.rows[1].size).toBe(DEFAULT_CELL_HEIGHT);
504
+ expect(model["workbook"].activeSheet.rows[2].size).toBe(DEFAULT_CELL_HEIGHT);
505
+ expect(model["workbook"].activeSheet.rows[3].size).toBe(DEFAULT_CELL_HEIGHT);
506
+ expect(model["workbook"].activeSheet.rows[4].size).toBe(DEFAULT_CELL_HEIGHT);
507
+ expect(model["workbook"].activeSheet.rows[5].size).toBe(21);
508
+ });
509
+
510
+ test("Select A, drag to C then ABC selected", async () => {
511
+ let x = model["workbook"].activeSheet.cols[0].start + 1;
512
+ triggerMouseEvent(".o-overlay .o-col-resizer", "mousedown", x, 10);
513
+ x = model["workbook"].activeSheet.cols[2].start + 1;
514
+ triggerMouseEvent(window, "mousemove", x, 10, { buttons: 1 });
515
+ expect(model.getters.getActiveCols()).toEqual(new Set([0, 1, 2]));
516
+ });
517
+
518
+ test("Select 1, drag to 3 then 123 selected", async () => {
519
+ let y = model["workbook"].activeSheet.rows[0].start + 1;
520
+ triggerMouseEvent(".o-overlay .o-row-resizer", "mousedown", 10, y);
521
+ y = model["workbook"].activeSheet.rows[2].start + 1;
522
+ triggerMouseEvent(window, "mousemove", 10, y, { buttons: 1 });
523
+ expect(model.getters.getActiveRows()).toEqual(new Set([0, 1, 2]));
524
+ });
525
+
526
+ test("right click after last column does not open context menu", async () => {
527
+ const nCols = model["workbook"].activeSheet.cols.length;
528
+ const x = model["workbook"].activeSheet.cols[nCols - 1].end + 1;
529
+ triggerMouseEvent(".o-overlay .o-col-resizer", "contextmenu", x, 10);
530
+ await nextTick();
531
+ expect(fixture.querySelector(".o-context-menu")).toBeFalsy();
532
+ });
533
+
534
+ test("right click after last row does not open context menu", async () => {
535
+ const nRows = model["workbook"].activeSheet.rows.length;
536
+ const y = model["workbook"].activeSheet.rows[nRows - 1].end + 1;
537
+ triggerMouseEvent(".o-overlay .o-row-resizer", "contextmenu", 10, y);
538
+ await nextTick();
539
+ expect(fixture.querySelector(".o-context-menu")).toBeFalsy();
540
+ });
541
+ });