@odoo/o-spreadsheet 14.0.1 → 14.0.2

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 (204) hide show
  1. package/dist/o_spreadsheet.cjs.js +17836 -0
  2. package/dist/o_spreadsheet.d.ts +4102 -0
  3. package/dist/o_spreadsheet.esm.js +17801 -0
  4. package/dist/o_spreadsheet.iife.js +17838 -0
  5. package/dist/o_spreadsheet.iife.min.js +1440 -0
  6. package/package.json +27 -7
  7. package/readme.md +10 -0
  8. package/.eslintrc.json +0 -20
  9. package/.husky/post-checkout +0 -9
  10. package/.husky/pre-commit +0 -39
  11. package/.prettierignore +0 -1
  12. package/astToFormula.patch +0 -0
  13. package/demo/data.js +0 -255
  14. package/demo/index.html +0 -9
  15. package/demo/libs/Chart.bundle.js +0 -20755
  16. package/demo/main.js +0 -101
  17. package/doc/readme.md +0 -46
  18. package/rollup.config.js +0 -23
  19. package/src/base_plugin.ts +0 -102
  20. package/src/components/autofill.ts +0 -146
  21. package/src/components/bottom_bar.ts +0 -199
  22. package/src/components/color_picker.ts +0 -150
  23. package/src/components/composer/autocomplete_dropdown.ts +0 -135
  24. package/src/components/composer/composer.ts +0 -487
  25. package/src/components/composer/content_editable_helper.ts +0 -146
  26. package/src/components/figures/chart.ts +0 -70
  27. package/src/components/figures/container.ts +0 -268
  28. package/src/components/figures/text_figure.ts +0 -36
  29. package/src/components/grid.ts +0 -635
  30. package/src/components/helpers/dom_helpers.ts +0 -7
  31. package/src/components/helpers/drag_and_drop.ts +0 -17
  32. package/src/components/icons.ts +0 -36
  33. package/src/components/index.ts +0 -1
  34. package/src/components/menu.ts +0 -288
  35. package/src/components/overlay.ts +0 -457
  36. package/src/components/scrollbar.ts +0 -22
  37. package/src/components/selection_input.ts +0 -168
  38. package/src/components/side_panel/cell_is_rule_editor.ts +0 -169
  39. package/src/components/side_panel/chart_panel.ts +0 -104
  40. package/src/components/side_panel/color_scale_rule_editor.ts +0 -145
  41. package/src/components/side_panel/conditional_formatting.ts +0 -396
  42. package/src/components/side_panel/side_panel.ts +0 -127
  43. package/src/components/side_panel/translations_terms.ts +0 -45
  44. package/src/components/spreadsheet.ts +0 -198
  45. package/src/components/top_bar.ts +0 -535
  46. package/src/constants.ts +0 -26
  47. package/src/data.ts +0 -149
  48. package/src/fonts.ts +0 -41
  49. package/src/formulas/compiler.ts +0 -258
  50. package/src/formulas/composer_tokenizer.ts +0 -70
  51. package/src/formulas/index.ts +0 -15
  52. package/src/formulas/normalize.ts +0 -52
  53. package/src/formulas/parser.ts +0 -280
  54. package/src/formulas/range_tokenizer.ts +0 -97
  55. package/src/formulas/tokenizer.ts +0 -242
  56. package/src/functions/arguments.ts +0 -114
  57. package/src/functions/dates.ts +0 -302
  58. package/src/functions/helpers.ts +0 -592
  59. package/src/functions/index.ts +0 -52
  60. package/src/functions/module_database.ts +0 -282
  61. package/src/functions/module_date.ts +0 -743
  62. package/src/functions/module_info.ts +0 -69
  63. package/src/functions/module_logical.ts +0 -208
  64. package/src/functions/module_lookup.ts +0 -185
  65. package/src/functions/module_math.ts +0 -1252
  66. package/src/functions/module_operators.ts +0 -291
  67. package/src/functions/module_statistical.ts +0 -882
  68. package/src/functions/module_text.ts +0 -370
  69. package/src/helpers/color.ts +0 -30
  70. package/src/helpers/coordinates.ts +0 -71
  71. package/src/helpers/grid_manipulation.ts +0 -68
  72. package/src/helpers/index.ts +0 -7
  73. package/src/helpers/misc.ts +0 -76
  74. package/src/helpers/numbers.ts +0 -117
  75. package/src/helpers/uuid.ts +0 -19
  76. package/src/helpers/zones.ts +0 -263
  77. package/src/history.ts +0 -186
  78. package/src/index.ts +0 -84
  79. package/src/model.ts +0 -261
  80. package/src/plugins/autofill.ts +0 -412
  81. package/src/plugins/chart.ts +0 -404
  82. package/src/plugins/clipboard.ts +0 -461
  83. package/src/plugins/conditional_format.ts +0 -445
  84. package/src/plugins/core.ts +0 -1502
  85. package/src/plugins/edition.ts +0 -157
  86. package/src/plugins/evaluation.ts +0 -428
  87. package/src/plugins/figures.ts +0 -123
  88. package/src/plugins/formatting.ts +0 -630
  89. package/src/plugins/highlight.ts +0 -187
  90. package/src/plugins/index.ts +0 -32
  91. package/src/plugins/merge.ts +0 -524
  92. package/src/plugins/renderer.ts +0 -571
  93. package/src/plugins/selection.ts +0 -562
  94. package/src/plugins/selection_inputs.ts +0 -326
  95. package/src/registries/autofill_modifiers.ts +0 -76
  96. package/src/registries/autofill_rules.ts +0 -98
  97. package/src/registries/figure_registry.ts +0 -30
  98. package/src/registries/index.ts +0 -7
  99. package/src/registries/menu_items_registry.ts +0 -110
  100. package/src/registries/menus/cell_menu_registry.ts +0 -79
  101. package/src/registries/menus/col_menu_registry.ts +0 -63
  102. package/src/registries/menus/index.ts +0 -6
  103. package/src/registries/menus/menu_items_actions.ts +0 -425
  104. package/src/registries/menus/row_menu_registry.ts +0 -63
  105. package/src/registries/menus/sheet_menu_registry.ts +0 -75
  106. package/src/registries/menus/topbar_menu_registry.ts +0 -204
  107. package/src/registries/side_panel_registry.ts +0 -26
  108. package/src/registries/topbar_component_registry.ts +0 -12
  109. package/src/registry.ts +0 -51
  110. package/src/translation.ts +0 -44
  111. package/src/types/autofill.ts +0 -48
  112. package/src/types/chart.ts +0 -26
  113. package/src/types/commands.ts +0 -716
  114. package/src/types/conditional_formatting.ts +0 -124
  115. package/src/types/env.ts +0 -13
  116. package/src/types/functions.ts +0 -35
  117. package/src/types/getters.ts +0 -103
  118. package/src/types/index.ts +0 -20
  119. package/src/types/misc.ts +0 -143
  120. package/src/types/rendering.ts +0 -41
  121. package/src/types/workbook_data.ts +0 -62
  122. package/tests/__mocks__/uuid.ts +0 -7
  123. package/tests/canvas.mock.ts +0 -34
  124. package/tests/components/__mocks__/content_editable_helper.ts +0 -79
  125. package/tests/components/__mocks__/scrollbar.ts +0 -18
  126. package/tests/components/__snapshots__/autocomplete_dropdown_test.ts.snap +0 -29
  127. package/tests/components/__snapshots__/bottom_bar_test.ts.snap +0 -75
  128. package/tests/components/__snapshots__/context_menu_test.ts.snap +0 -88
  129. package/tests/components/__snapshots__/grid_test.ts.snap +0 -60
  130. package/tests/components/__snapshots__/spreadsheet_test.ts.snap +0 -455
  131. package/tests/components/__snapshots__/top_bar_test.ts.snap +0 -705
  132. package/tests/components/autocomplete_dropdown_test.ts +0 -315
  133. package/tests/components/autofill_test.ts +0 -167
  134. package/tests/components/bottom_bar_test.ts +0 -262
  135. package/tests/components/chart_side_panel_test.ts +0 -123
  136. package/tests/components/composer_test.ts +0 -400
  137. package/tests/components/context_menu_test.ts +0 -825
  138. package/tests/components/grid_manipulation_test.ts +0 -163
  139. package/tests/components/grid_test.ts +0 -581
  140. package/tests/components/overlay_test.ts +0 -541
  141. package/tests/components/selection_input_test.ts +0 -259
  142. package/tests/components/side_panel_test.ts +0 -148
  143. package/tests/components/spreadsheet_test.ts +0 -194
  144. package/tests/components/top_bar_test.ts +0 -427
  145. package/tests/data_test.ts +0 -175
  146. package/tests/dom_helper.ts +0 -42
  147. package/tests/formulas/__snapshots__/compiler_test.ts.snap +0 -302
  148. package/tests/formulas/compiler_test.ts +0 -266
  149. package/tests/formulas/composer_tokenizer_test.ts +0 -137
  150. package/tests/formulas/expressions_test.ts +0 -57
  151. package/tests/formulas/formulas_test.ts +0 -80
  152. package/tests/formulas/normalize_test.ts +0 -82
  153. package/tests/formulas/parser_test.ts +0 -224
  154. package/tests/formulas/range_tokenizer_test.ts +0 -187
  155. package/tests/formulas/tokenizer_test.ts +0 -164
  156. package/tests/functions/arguments_test.ts +0 -141
  157. package/tests/functions/dates_test.ts +0 -1081
  158. package/tests/functions/functions_test.ts +0 -53
  159. package/tests/functions/helper_test.ts +0 -98
  160. package/tests/functions/module_database_test.ts +0 -311
  161. package/tests/functions/module_date_test.ts +0 -941
  162. package/tests/functions/module_info_test.ts +0 -139
  163. package/tests/functions/module_logical_test.ts +0 -369
  164. package/tests/functions/module_lookup_test.ts +0 -541
  165. package/tests/functions/module_math_test.ts +0 -2482
  166. package/tests/functions/module_operators_test.ts +0 -955
  167. package/tests/functions/module_statistical_test.ts +0 -2014
  168. package/tests/functions/module_text_test.ts +0 -667
  169. package/tests/helpers/coordinates_test.ts +0 -25
  170. package/tests/helpers/misc_test.ts +0 -95
  171. package/tests/helpers/numbers_test.ts +0 -196
  172. package/tests/helpers/zones_test.ts +0 -97
  173. package/tests/helpers.ts +0 -384
  174. package/tests/menu_items_registry_test.ts +0 -540
  175. package/tests/model/plugins/__snapshots__/chart_test.ts.snap +0 -90
  176. package/tests/model/plugins/chart_test.ts +0 -562
  177. package/tests/model_test.ts +0 -82
  178. package/tests/plugins/__snapshots__/conditional_formatting_test.ts.snap +0 -131
  179. package/tests/plugins/__snapshots__/renderer_test.ts.snap +0 -371
  180. package/tests/plugins/autofill_test.ts +0 -457
  181. package/tests/plugins/borders_test.ts +0 -295
  182. package/tests/plugins/clipboard_test.ts +0 -1180
  183. package/tests/plugins/conditional_formatting_test.ts +0 -1253
  184. package/tests/plugins/core_test.ts +0 -614
  185. package/tests/plugins/edition_test.ts +0 -100
  186. package/tests/plugins/evaluation_async_test.ts +0 -332
  187. package/tests/plugins/evaluation_dates_test.ts +0 -79
  188. package/tests/plugins/evaluation_test.ts +0 -901
  189. package/tests/plugins/figures_test.ts +0 -327
  190. package/tests/plugins/formatting_test.ts +0 -391
  191. package/tests/plugins/grid_manipulation_test.ts +0 -1366
  192. package/tests/plugins/highlight_test.ts +0 -413
  193. package/tests/plugins/history_test.ts +0 -142
  194. package/tests/plugins/import_export_test.ts +0 -276
  195. package/tests/plugins/merges_test.ts +0 -490
  196. package/tests/plugins/navigation_test.ts +0 -181
  197. package/tests/plugins/plugins/evaluation_test.ts +0 -111
  198. package/tests/plugins/renderer_test.ts +0 -598
  199. package/tests/plugins/resizing_test.ts +0 -152
  200. package/tests/plugins/selection_input_test.ts +0 -409
  201. package/tests/plugins/selection_test.ts +0 -442
  202. package/tests/plugins/sheets_test.ts +0 -643
  203. package/tests/plugins/style_test.ts +0 -90
  204. package/tsconfig.json +0 -22
@@ -1,1366 +0,0 @@
1
- import { DEFAULT_CELL_HEIGHT, DEFAULT_CELL_WIDTH } from "../../src/constants";
2
- import { Model } from "../../src/model";
3
- import { getSheet, makeTestFixture } from "../helpers";
4
- let model: Model;
5
-
6
- function undo() {
7
- model.dispatch("UNDO");
8
- }
9
-
10
- function redo() {
11
- model.dispatch("REDO");
12
- }
13
-
14
- function clearColumns(indexes: number[]) {
15
- const target = indexes.map((index) => {
16
- return model.getters.getColsZone(index, index);
17
- });
18
- model.dispatch("DELETE_CONTENT", {
19
- target,
20
- sheet: model["workbook"].activeSheet.id,
21
- });
22
- }
23
-
24
- function clearRows(indexes: number[]) {
25
- const target = indexes.map((index) => {
26
- return model.getters.getRowsZone(index, index);
27
- });
28
- model.dispatch("DELETE_CONTENT", {
29
- target,
30
- sheet: model["workbook"].activeSheet.id,
31
- });
32
- }
33
-
34
- function removeColumns(columns: number[]) {
35
- model.dispatch("REMOVE_COLUMNS", { sheet: model.getters.getActiveSheet(), columns });
36
- }
37
-
38
- function removeRows(rows: number[]) {
39
- model.dispatch("REMOVE_ROWS", { sheet: model.getters.getActiveSheet(), rows });
40
- }
41
-
42
- function addColumns(column: number, position: "before" | "after", quantity: number) {
43
- model.dispatch("ADD_COLUMNS", {
44
- sheet: model.getters.getActiveSheet(),
45
- position,
46
- column,
47
- quantity,
48
- });
49
- }
50
-
51
- function addRows(row: number, position: "before" | "after", quantity: number) {
52
- model.dispatch("ADD_ROWS", {
53
- sheet: model.getters.getActiveSheet(),
54
- position,
55
- row,
56
- quantity,
57
- });
58
- }
59
-
60
- const fullData = {
61
- sheets: [
62
- {
63
- colNumber: 4,
64
- rowNumber: 4,
65
- cells: {
66
- A1: { content: "1", style: 1, border: 1 },
67
- A2: { content: "2", style: 1, border: 1 },
68
- A3: { content: "3", style: 1, border: 1 },
69
- A4: { content: "4", style: 1, border: 1 },
70
- B1: { content: "1", style: 1, border: 1 },
71
- B2: { content: "2", style: 1 },
72
- B3: { content: "3", border: 1 },
73
- C1: { content: "1" },
74
- C3: { content: "3" },
75
- },
76
- merges: ["A4:D4", "C1:D2"],
77
- cols: { 1: { size: 42 } },
78
- rows: { 1: { size: 42 } },
79
- },
80
- ],
81
- styles: { 1: { textColor: "#fe0000" } },
82
- borders: { 1: { top: ["thin", "#000"] } },
83
- };
84
-
85
- //------------------------------------------------------------------------------
86
- // Clear
87
- //------------------------------------------------------------------------------
88
-
89
- describe("Clear columns", () => {
90
- test("Can clear multiple column", () => {
91
- model = new Model({
92
- sheets: [
93
- {
94
- colNumber: 3,
95
- rowNumber: 3,
96
- cells: {
97
- A1: { content: "A1" },
98
- A2: { content: "A2" },
99
- A3: { content: "A3" },
100
- B1: { content: "B1", style: 1, border: 1 },
101
- B2: { content: "B2" },
102
- C1: { content: "C1", style: 1 },
103
- C2: { content: "C2", border: 1 },
104
- },
105
- },
106
- ],
107
- styles: { 1: { textColor: "#fe0000" } },
108
- borders: { 1: { right: ["thin", "#000"] } },
109
- merges: ["A3:B3"],
110
- });
111
-
112
- clearColumns([1, 2]);
113
- expect(model["workbook"].activeSheet.cells.B2).toBeUndefined();
114
- expect(model["workbook"].activeSheet.cells).toMatchObject({
115
- A1: { content: "A1" },
116
- A2: { content: "A2" },
117
- A3: { content: "A3" },
118
- B1: { content: "", style: 1, border: 1 },
119
- C1: { content: "", style: 1 },
120
- C2: { content: "", border: 1 },
121
- });
122
- });
123
- });
124
-
125
- describe("Clear rows", () => {
126
- test("Can clear multiple rows", () => {
127
- model = new Model({
128
- sheets: [
129
- {
130
- colNumber: 3,
131
- rowNumber: 3,
132
- cells: {
133
- A1: { content: "A1" },
134
- A2: { content: "A2", style: 1, border: 1 },
135
- A3: { content: "A3", border: 1 },
136
- B1: { content: "B1" },
137
- B2: { content: "B2" },
138
- C1: { content: "C1" },
139
- C2: { content: "C2", style: 1 },
140
- },
141
- },
142
- ],
143
- styles: { 1: { textColor: "#fe0000" } },
144
- borders: { 1: { right: ["thin", "#000"] } },
145
- merges: ["C1:C2"],
146
- });
147
-
148
- clearRows([1, 2]);
149
- expect(model["workbook"].activeSheet.cells.B2).toBeUndefined();
150
- expect(model["workbook"].activeSheet.cells).toMatchObject({
151
- A1: { content: "A1" },
152
- A2: { content: "", style: 1, border: 1 },
153
- A3: { content: "", border: 1 },
154
- B1: { content: "B1" },
155
- C1: { content: "C1" },
156
- C2: { content: "", style: 1 },
157
- });
158
- });
159
- });
160
-
161
- //------------------------------------------------------------------------------
162
- // Columns
163
- //------------------------------------------------------------------------------
164
-
165
- describe("Columns", () => {
166
- beforeAll(() => {
167
- makeTestFixture();
168
- });
169
- describe("Correctly update size, name, order and number", () => {
170
- beforeEach(() => {
171
- model = new Model({
172
- sheets: [
173
- {
174
- colNumber: 4,
175
- rowNumber: 1,
176
- cols: {
177
- 1: { size: 10 },
178
- 2: { size: 20 },
179
- },
180
- },
181
- ],
182
- });
183
- });
184
- test("On deletion", () => {
185
- removeColumns([0, 2]);
186
- expect(model["workbook"].activeSheet.cols).toEqual([
187
- { start: 0, end: 10, size: 10, name: "A" },
188
- { start: 10, end: 10 + DEFAULT_CELL_WIDTH, size: DEFAULT_CELL_WIDTH, name: "B" },
189
- ]);
190
- expect(model["workbook"].activeSheet.colNumber).toBe(2);
191
- });
192
- test("On delete cols in inactive sheet", () => {
193
- model = new Model({
194
- sheets: [
195
- {
196
- colNumber: 3,
197
- rowNumber: 3,
198
- cells: {
199
- B2: { content: "B2 in sheet1" },
200
- },
201
- },
202
- {
203
- colNumber: 3,
204
- rowNumber: 3,
205
- cells: {
206
- B2: { content: "B2 in sheet2" },
207
- },
208
- },
209
- ],
210
- });
211
- const [sheet1, sheet2] = model.getters.getSheets();
212
- expect(sheet2).not.toBe(model.getters.getActiveSheet());
213
- model.dispatch("REMOVE_COLUMNS", {
214
- columns: [0],
215
- sheet: sheet2.id,
216
- });
217
- expect(sheet1.cells.B2.content).toBe("B2 in sheet1");
218
- expect(sheet2.cells.A2.content).toBe("B2 in sheet2");
219
- });
220
- test("On addition before", () => {
221
- addColumns(1, "before", 2);
222
- const size = DEFAULT_CELL_WIDTH;
223
- expect(model["workbook"].activeSheet.cols).toEqual([
224
- { start: 0, end: size, size, name: "A" },
225
- { start: size, end: size + 10, size: 10, name: "B" },
226
- { start: size + 10, end: size + 20, size: 10, name: "C" },
227
- { start: size + 20, end: size + 30, size: 10, name: "D" },
228
- { start: size + 30, end: size + 50, size: 20, name: "E" },
229
- { start: size + 50, end: 2 * size + 50, size, name: "F" },
230
- ]);
231
- expect(model["workbook"].activeSheet.colNumber).toBe(6);
232
- });
233
- test("On addition after", () => {
234
- addColumns(2, "after", 2);
235
- const size = DEFAULT_CELL_WIDTH;
236
- expect(model["workbook"].activeSheet.cols).toEqual([
237
- { start: 0, end: size, size, name: "A" },
238
- { start: size, end: size + 10, size: 10, name: "B" },
239
- { start: size + 10, end: size + 30, size: 20, name: "C" },
240
- { start: size + 30, end: size + 50, size: 20, name: "D" },
241
- { start: size + 50, end: size + 70, size: 20, name: "E" },
242
- { start: size + 70, end: 2 * size + 70, size, name: "F" },
243
- ]);
244
- expect(model["workbook"].activeSheet.colNumber).toBe(6);
245
- });
246
- });
247
-
248
- describe("Correctly update merges", () => {
249
- beforeEach(() => {
250
- model = new Model({
251
- sheets: [
252
- {
253
- colNumber: 5,
254
- rowNumber: 4,
255
- merges: ["A1:E1", "B2:E2", "C3:E3", "B4:D4"],
256
- },
257
- ],
258
- });
259
- });
260
-
261
- test("On deletion", () => {
262
- removeColumns([1, 3]);
263
- expect(model["workbook"].activeSheet.merges).toEqual({
264
- 5: { id: 5, topLeft: "A1", top: 0, bottom: 0, left: 0, right: 2 },
265
- 6: { id: 6, topLeft: "B2", top: 1, bottom: 1, left: 1, right: 2 },
266
- 7: { id: 7, topLeft: "B3", top: 2, bottom: 2, left: 1, right: 2 },
267
- });
268
- expect(model["workbook"].activeSheet.mergeCellMap).toEqual({
269
- A1: 5,
270
- B1: 5,
271
- C1: 5,
272
- B2: 6,
273
- C2: 6,
274
- B3: 7,
275
- C3: 7,
276
- });
277
- });
278
-
279
- test("On addition", () => {
280
- addColumns(1, "before", 1);
281
- addColumns(0, "after", 1);
282
- expect(model["workbook"].activeSheet.merges).toEqual({
283
- 9: { id: 9, topLeft: "A1", top: 0, bottom: 0, left: 0, right: 6 },
284
- 10: { id: 10, topLeft: "D2", top: 1, bottom: 1, left: 3, right: 6 },
285
- 11: { id: 11, topLeft: "E3", top: 2, bottom: 2, left: 4, right: 6 },
286
- 12: { id: 12, topLeft: "D4", top: 3, bottom: 3, left: 3, right: 5 },
287
- });
288
- expect(model["workbook"].activeSheet.mergeCellMap).toEqual({
289
- A1: 9,
290
- B1: 9,
291
- C1: 9,
292
- D1: 9,
293
- E1: 9,
294
- F1: 9,
295
- G1: 9,
296
- D2: 10,
297
- E2: 10,
298
- F2: 10,
299
- G2: 10,
300
- E3: 11,
301
- F3: 11,
302
- G3: 11,
303
- D4: 12,
304
- E4: 12,
305
- F4: 12,
306
- });
307
- });
308
- });
309
-
310
- describe("Correctly update border and style", () => {
311
- beforeEach(() => {
312
- model = new Model({
313
- sheets: [
314
- {
315
- colNumber: 4,
316
- rowNumber: 4,
317
- cells: {
318
- A1: { style: 1 },
319
- A2: { border: 1 },
320
- A3: { style: 1, border: 1 },
321
- B1: { style: 1 },
322
- B2: { border: 1 },
323
- B3: { style: 1, border: 1, format: "0.00%" },
324
- B4: { style: 1, border: 1 },
325
- D1: { style: 1 },
326
- D2: { border: 1 },
327
- D3: { style: 1, border: 1 },
328
- },
329
- merges: ["B4:C4"],
330
- },
331
- ],
332
- styles: { 1: { textColor: "#fe0000" } },
333
- borders: { 1: { top: ["thin", "#000"] } },
334
- });
335
- });
336
- test("On deletion", () => {
337
- removeColumns([1]);
338
- expect(model["workbook"].activeSheet.cells.B1).toBeUndefined();
339
- expect(model["workbook"].activeSheet.cells.B2).toBeUndefined();
340
- expect(model["workbook"].activeSheet.cells.B3).toBeUndefined();
341
- expect(model["workbook"].activeSheet.cells).toMatchObject({
342
- A1: { style: 1 },
343
- A2: { border: 1 },
344
- A3: { style: 1, border: 1 },
345
- B4: { style: 1, border: 1 },
346
- C1: { style: 1 },
347
- C2: { border: 1 },
348
- C3: { style: 1, border: 1 },
349
- });
350
- });
351
- test("On addition", () => {
352
- addColumns(1, "before", 1);
353
- addColumns(2, "after", 2);
354
- expect(model["workbook"].activeSheet.cells).toMatchObject({
355
- A1: { style: 1 },
356
- A2: { border: 1 },
357
- A3: { style: 1, border: 1 },
358
- B1: { style: 1 },
359
- B2: { border: 1 },
360
- B3: { style: 1, border: 1, format: "0.00%" },
361
- B4: { style: 1 },
362
- C1: { style: 1 },
363
- C2: { border: 1 },
364
- C3: { style: 1, border: 1, format: "0.00%" },
365
- C4: { style: 1, border: 1 },
366
- E1: { style: 1 },
367
- });
368
- expect(Object.values(model["workbook"].activeSheet.merges)[0]).toMatchObject({
369
- left: 2,
370
- right: 5,
371
- topLeft: "C4",
372
- });
373
- });
374
- });
375
-
376
- describe("Correctly update references", () => {
377
- beforeEach(() => {
378
- model = new Model({
379
- sheets: [
380
- {
381
- colNumber: 7,
382
- rowNumber: 7,
383
- cells: {
384
- A1: { content: "=B1" },
385
- A2: { content: "=Sheet1!B1" },
386
- A3: { content: "=Sheet2!B1" },
387
- D1: { content: "=A1" },
388
- D2: { content: "=B1" },
389
- D3: { content: "=$E1" },
390
- D4: { content: "=D3" },
391
- A5: { content: "=SUM(A1:D1)" },
392
- A6: { content: "=SUM(C1:D1)" },
393
- A7: { content: "=SUM(B1:B2)" },
394
- },
395
- },
396
- {
397
- colNumber: 1,
398
- rowNumber: 3,
399
- cells: {
400
- A1: { content: "=B1" },
401
- A2: { content: "=Sheet1!B1" },
402
- A3: { content: "=Sheet2!B1" },
403
- },
404
- },
405
- ],
406
- });
407
- });
408
- test("On deletion", () => {
409
- removeColumns([1, 2]);
410
- expect(getSheet(model, 0).cells).toMatchObject({
411
- A1: { content: "=#REF" },
412
- A2: { content: "=#REF" },
413
- A3: { content: "=Sheet2!B1" },
414
- B1: { content: "=A1" },
415
- B2: { content: "=#REF" },
416
- B3: { content: "=$C1" },
417
- B4: { content: "=B3" },
418
- });
419
- expect(getSheet(model, 1).cells).toMatchObject({
420
- A1: { content: "=B1" },
421
- A2: { content: "=#REF" },
422
- A3: { content: "=Sheet2!B1" },
423
- });
424
- });
425
- test("delete col on inactive sheet", () => {
426
- const model = new Model({
427
- sheets: [
428
- {
429
- colNumber: 4,
430
- rowNumber: 7,
431
- cells: {
432
- B2: { content: "=Sheet1!B3" },
433
- C1: { content: "=Sheet2!B3" },
434
- },
435
- },
436
- {
437
- colNumber: 3,
438
- rowNumber: 3,
439
- cells: {
440
- A2: { content: "=B2" },
441
- B2: { content: "=Sheet1!B2" },
442
- C2: { content: "=Sheet2!B2" },
443
- },
444
- },
445
- ],
446
- });
447
- const [sheet1, sheet2] = model.getters.getSheets();
448
- expect(sheet2.id).not.toBe(model.getters.getActiveSheet());
449
- model.dispatch("REMOVE_COLUMNS", {
450
- columns: [0],
451
- sheet: sheet2.id,
452
- });
453
- expect(sheet1.cells).toMatchObject({
454
- B2: { content: "=Sheet1!B3" },
455
- C1: { content: "=Sheet2!A3" },
456
- });
457
- expect(sheet2.cells).toMatchObject({
458
- A2: { content: "=Sheet1!B2" },
459
- B2: { content: "=Sheet2!A2" },
460
- });
461
- });
462
- test("On first col deletion", () => {
463
- model = new Model({
464
- sheets: [
465
- {
466
- colNumber: 3,
467
- rowNumber: 3,
468
- cells: {
469
- B2: { content: "=SUM(A1:C1)" },
470
- },
471
- },
472
- ],
473
- });
474
- removeColumns([0]);
475
- expect(getSheet(model, 0).cells).toMatchObject({
476
- A2: { content: "=SUM(A1:B1)" },
477
- });
478
- });
479
- test("On multiple col deletion including the first one", () => {
480
- model = new Model({
481
- sheets: [
482
- {
483
- colNumber: 3,
484
- rowNumber: 3,
485
- cells: {
486
- C2: { content: "=SUM(A1:D1)" },
487
- },
488
- },
489
- ],
490
- });
491
- removeColumns([0, 1]);
492
- expect(getSheet(model, 0).cells).toMatchObject({
493
- A2: { content: "=SUM(A1:B1)" },
494
- });
495
- });
496
- test("On last col deletion", () => {
497
- model = new Model({
498
- sheets: [
499
- {
500
- colNumber: 3,
501
- rowNumber: 3,
502
- cells: {
503
- A2: { content: "=SUM(A1:C1)" },
504
- },
505
- },
506
- ],
507
- });
508
- removeColumns([2]);
509
- expect(getSheet(model, 0).cells).toMatchObject({
510
- A2: { content: "=SUM(A1:B1)" },
511
- });
512
- });
513
- test("delete all columns of a range", () => {
514
- model = new Model({
515
- sheets: [
516
- {
517
- colNumber: 9,
518
- rowNumber: 5,
519
- cells: {
520
- A1: { content: "=SUM(B2:E5)" },
521
- A2: { content: "=SUM(F1:F2)" }, // single column range
522
- },
523
- },
524
- ],
525
- });
526
-
527
- removeColumns([5]);
528
- expect(getSheet(model, 0).cells.A2.content).toBe("=SUM(#REF)");
529
- removeColumns([1, 2, 3, 4]);
530
- expect(getSheet(model, 0).cells.A1.content).toBe("=SUM(#REF)");
531
- });
532
- test("update cross sheet range on column deletion", () => {
533
- model = new Model({
534
- sheets: [
535
- { name: "Sheet1", colNumber: 5, rowNumber: 5 },
536
- {
537
- name: "Sheet2",
538
- colNumber: 3,
539
- rowNumber: 9,
540
- cells: {
541
- A1: { content: "=SUM(Sheet1!B1:D3)" },
542
- },
543
- },
544
- ],
545
- });
546
- removeColumns([0]);
547
- expect(model.getters.getCell(0, 0, "Sheet2")!.content).toBe("=SUM(Sheet1!A1:C3)");
548
- });
549
- test("update cross sheet range on column deletion in inactive sheet", () => {
550
- model = new Model({
551
- sheets: [
552
- { name: "Sheet0", colNumber: 1, rowNumber: 1 }, // <-- less column than Sheet1
553
- { name: "Sheet1", colNumber: 5, rowNumber: 5 },
554
- {
555
- name: "Sheet2",
556
- colNumber: 5,
557
- rowNumber: 9,
558
- cells: {
559
- A1: { content: "=SUM(Sheet1!B1:D3)" },
560
- },
561
- },
562
- ],
563
- });
564
- const sheet1Id = model.getters.getSheetIdByName("Sheet1");
565
- model.dispatch("REMOVE_COLUMNS", { sheet: sheet1Id!, columns: [0] });
566
- expect(model.getters.getCell(0, 0, "Sheet2")!.content).toBe("=SUM(Sheet1!A1:C3)");
567
- });
568
- test("On multiple col deletion including the last one", () => {
569
- model = new Model({
570
- sheets: [
571
- {
572
- colNumber: 3,
573
- rowNumber: 3,
574
- cells: {
575
- A2: { content: "=SUM(A1:D1)" },
576
- },
577
- },
578
- ],
579
- });
580
- removeColumns([2, 3]);
581
- expect(getSheet(model, 0).cells).toMatchObject({
582
- A2: { content: "=SUM(A1:B1)" },
583
- });
584
- });
585
- test("On addition", () => {
586
- addColumns(1, "before", 1);
587
- addColumns(0, "after", 1);
588
- expect(getSheet(model, 0).cells).toMatchObject({
589
- A1: { content: "=D1" },
590
- A2: { content: "=Sheet1!D1" },
591
- A3: { content: "=Sheet2!B1" },
592
- F1: { content: "=A1" },
593
- F2: { content: "=D1" },
594
- F3: { content: "=$G1" },
595
- F4: { content: "=F3" },
596
- A5: { content: "=SUM(A1:F1)" },
597
- A6: { content: "=SUM(E1:F1)" },
598
- A7: { content: "=SUM(D1:D2)" },
599
- });
600
- expect(getSheet(model, 1).cells).toMatchObject({
601
- A1: { content: "=B1" },
602
- A2: { content: "=Sheet1!D1" },
603
- A3: { content: "=Sheet2!B1" },
604
- });
605
- });
606
- });
607
-
608
- describe("Correctly handle undo/redo", () => {
609
- test("On deletion", () => {
610
- model = new Model(fullData);
611
- const beforeRemove = model.exportData();
612
- removeColumns([0, 2]);
613
- const afterRemove = model.exportData();
614
- undo();
615
- expect(model.exportData()).toEqual(beforeRemove);
616
- redo();
617
- expect(model.exportData()).toEqual(afterRemove);
618
- });
619
- test("On addition", () => {
620
- model = new Model(fullData);
621
- const beforeAdd = model.exportData();
622
- addColumns(1, "before", 4);
623
- const afterAdd1 = model.exportData();
624
- addColumns(4, "after", 4);
625
- const afterAdd2 = model.exportData();
626
- undo();
627
- expect(model.exportData()).toEqual(afterAdd1);
628
- redo();
629
- expect(model.exportData()).toEqual(afterAdd2);
630
- undo();
631
- undo();
632
- expect(model.exportData()).toEqual(beforeAdd);
633
- });
634
- });
635
-
636
- describe("Correctly update selection", () => {
637
- test("On add left 1", () => {
638
- model = new Model(fullData);
639
- const zone = { left: 1, right: 3, top: 0, bottom: 2 };
640
- model.dispatch("SET_SELECTION", {
641
- zones: [zone],
642
- anchor: [zone.left, zone.top],
643
- strict: true,
644
- });
645
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
646
- addColumns(1, "before", 1);
647
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 2, right: 4, top: 0 });
648
- });
649
- test("On add left 3", () => {
650
- model = new Model(fullData);
651
- const zone = { left: 1, right: 3, top: 0, bottom: 2 };
652
- model.dispatch("SET_SELECTION", {
653
- zones: [zone],
654
- anchor: [zone.left, zone.top],
655
- strict: true,
656
- });
657
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
658
- addColumns(1, "before", 3);
659
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 4, right: 6, top: 0 });
660
- });
661
- test("On add right 1", () => {
662
- model = new Model(fullData);
663
- const zone = { left: 1, right: 3, top: 0, bottom: 2 };
664
- model.dispatch("SET_SELECTION", {
665
- zones: [zone],
666
- anchor: [zone.left, zone.top],
667
- strict: true,
668
- });
669
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
670
- addColumns(1, "after", 1);
671
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
672
- });
673
- test("On add right 3", () => {
674
- model = new Model(fullData);
675
- const zone = { left: 1, right: 3, top: 0, bottom: 2 };
676
- model.dispatch("SET_SELECTION", {
677
- zones: [zone],
678
- anchor: [zone.left, zone.top],
679
- strict: true,
680
- });
681
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
682
- addColumns(1, "after", 1);
683
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
684
- });
685
- });
686
- });
687
-
688
- //------------------------------------------------------------------------------
689
- // Rows
690
- //------------------------------------------------------------------------------
691
-
692
- describe("Rows", () => {
693
- beforeAll(() => {
694
- makeTestFixture();
695
- });
696
- describe("Correctly update size, name, order and number", () => {
697
- beforeEach(() => {
698
- model = new Model({
699
- sheets: [
700
- {
701
- colNumber: 1,
702
- rowNumber: 4,
703
- rows: {
704
- 1: { size: 10 },
705
- 2: { size: 20 },
706
- },
707
- },
708
- ],
709
- });
710
- });
711
- test("On deletion", () => {
712
- removeRows([0, 2]);
713
- const size = DEFAULT_CELL_HEIGHT;
714
- expect(model["workbook"].activeSheet.rows).toEqual([
715
- { start: 0, end: 10, size: 10, name: "1", cells: {} },
716
- { start: 10, end: size + 10, size, name: "2", cells: {} },
717
- ]);
718
- expect(model["workbook"].activeSheet.rowNumber).toBe(2);
719
- });
720
- test("On delete row in inactive sheet", () => {
721
- model = new Model({
722
- sheets: [
723
- {
724
- colNumber: 3,
725
- rowNumber: 3,
726
- cells: {
727
- B2: { content: "B2 in sheet1" },
728
- },
729
- },
730
- {
731
- colNumber: 3,
732
- rowNumber: 3,
733
- cells: {
734
- B2: { content: "B2 in sheet2" },
735
- },
736
- },
737
- ],
738
- });
739
- const [sheet1, sheet2] = model.getters.getSheets();
740
- expect(sheet2).not.toBe(model.getters.getActiveSheet());
741
- model.dispatch("REMOVE_ROWS", {
742
- rows: [0],
743
- sheet: sheet2.id,
744
- });
745
- expect(sheet1.cells.B2.content).toBe("B2 in sheet1");
746
- expect(sheet2.cells.B1.content).toBe("B2 in sheet2");
747
- });
748
- test("On deletion batch", () => {
749
- model = new Model({
750
- sheets: [
751
- {
752
- colNumber: 1,
753
- rowNumber: 4,
754
- cells: {
755
- A1: { content: "A1" },
756
- A2: { content: "A2" },
757
- A3: { content: "A3" },
758
- A4: { content: "A4" },
759
- },
760
- },
761
- ],
762
- });
763
- removeRows([0, 2, 3]);
764
- expect(getSheet(model, 0).cells).toMatchObject({
765
- A1: { content: "A2" },
766
- });
767
- });
768
- test("delete all rows of a range", () => {
769
- model = new Model({
770
- sheets: [
771
- {
772
- colNumber: 5,
773
- rowNumber: 9,
774
- cells: {
775
- A1: { content: "=SUM(A2:A5)" },
776
- B1: { content: "=SUM(B6:C6)" }, // single line range
777
- },
778
- },
779
- ],
780
- });
781
- removeRows([5]);
782
- expect(getSheet(model, 0).cells.B1.content).toBe("=SUM(#REF)");
783
- removeRows([1, 2, 3, 4]);
784
- expect(getSheet(model, 0).cells.A1.content).toBe("=SUM(#REF)");
785
- });
786
- test("update cross sheet range on row deletion", () => {
787
- model = new Model({
788
- sheets: [
789
- { name: "Sheet1", colNumber: 5, rowNumber: 5 },
790
- {
791
- name: "Sheet2",
792
- colNumber: 3,
793
- rowNumber: 9,
794
- cells: {
795
- A1: { content: "=SUM(Sheet1!A2:A3)" },
796
- },
797
- },
798
- ],
799
- });
800
- removeRows([0]);
801
- expect(model.getters.getCell(0, 0, "Sheet2")!.content).toBe("=SUM(Sheet1!A1:A2)");
802
- });
803
- test("update cross sheet range on row deletion in inactive sheet", () => {
804
- model = new Model({
805
- sheets: [
806
- { name: "Sheet0", colNumber: 1, rowNumber: 1 }, // <-- less rows than Sheet1
807
- { name: "Sheet1", colNumber: 5, rowNumber: 5 },
808
- {
809
- name: "Sheet2",
810
- colNumber: 5,
811
- rowNumber: 9,
812
- cells: {
813
- A1: { content: "=SUM(Sheet1!A2:A3)" },
814
- },
815
- },
816
- ],
817
- });
818
- const sheet1Id = model.getters.getSheetIdByName("Sheet1");
819
- model.dispatch("REMOVE_ROWS", { sheet: sheet1Id!, rows: [0] });
820
- expect(model.getters.getCell(0, 0, "Sheet2")!.content).toBe("=SUM(Sheet1!A1:A2)");
821
- });
822
- test("On addition before", () => {
823
- addRows(1, "before", 2);
824
- const size = DEFAULT_CELL_HEIGHT;
825
- expect(model["workbook"].activeSheet.rows).toEqual([
826
- { start: 0, end: size, size, name: "1", cells: {} },
827
- { start: size, end: size + 10, size: 10, name: "2", cells: {} },
828
- { start: size + 10, end: size + 20, size: 10, name: "3", cells: {} },
829
- { start: size + 20, end: size + 30, size: 10, name: "4", cells: {} },
830
- { start: size + 30, end: size + 50, size: 20, name: "5", cells: {} },
831
- { start: size + 50, end: 2 * size + 50, size, name: "6", cells: {} },
832
- ]);
833
- const dimensions = model.getters.getGridSize();
834
- expect(dimensions).toEqual([192, 124]);
835
- expect(model["workbook"].activeSheet.rowNumber).toBe(6);
836
- });
837
- test("On addition after", () => {
838
- addRows(2, "after", 2);
839
- const size = DEFAULT_CELL_HEIGHT;
840
- expect(model["workbook"].activeSheet.rows).toEqual([
841
- { start: 0, end: size, size, name: "1", cells: {} },
842
- { start: size, end: size + 10, size: 10, name: "2", cells: {} },
843
- { start: size + 10, end: size + 30, size: 20, name: "3", cells: {} },
844
- { start: size + 30, end: size + 50, size: 20, name: "4", cells: {} },
845
- { start: size + 50, end: size + 70, size: 20, name: "5", cells: {} },
846
- { start: size + 70, end: 2 * size + 70, size, name: "6", cells: {} },
847
- ]);
848
- const dimensions = model.getters.getGridSize();
849
- expect(dimensions).toEqual([192, 144]);
850
- expect(model["workbook"].activeSheet.rowNumber).toBe(6);
851
- });
852
-
853
- test("activate Sheet: same size", () => {
854
- addRows(2, "after", 1);
855
- let dimensions = model.getters.getGridSize();
856
- expect(dimensions).toEqual([192, 124]);
857
- const to = model.getters.getActiveSheet();
858
- model.dispatch("CREATE_SHEET", { activate: true, id: "42" });
859
- const from = model.getters.getActiveSheet();
860
- model.dispatch("ACTIVATE_SHEET", { from, to });
861
- dimensions = model.getters.getGridSize();
862
- expect(dimensions).toEqual([192, 124]);
863
- });
864
- });
865
-
866
- describe("Correctly update merges", () => {
867
- beforeEach(() => {
868
- model = new Model({
869
- sheets: [
870
- {
871
- colNumber: 4,
872
- rowNumber: 5,
873
- merges: ["A1:A5", "B2:B5", "C3:C5", "D2:D4"],
874
- },
875
- ],
876
- });
877
- });
878
- test("On deletion", () => {
879
- removeRows([1, 3]);
880
- expect(model["workbook"].activeSheet.merges).toEqual({
881
- 5: { id: 5, topLeft: "A1", top: 0, bottom: 2, left: 0, right: 0 },
882
- 6: { id: 6, topLeft: "B2", top: 1, bottom: 2, left: 1, right: 1 },
883
- 7: { id: 7, topLeft: "C2", top: 1, bottom: 2, left: 2, right: 2 },
884
- });
885
- expect(model["workbook"].activeSheet.mergeCellMap).toEqual({
886
- A1: 5,
887
- A2: 5,
888
- A3: 5,
889
- B2: 6,
890
- B3: 6,
891
- C2: 7,
892
- C3: 7,
893
- });
894
- });
895
- test("On addition", () => {
896
- addRows(1, "before", 1);
897
- addRows(0, "after", 1);
898
- expect(model["workbook"].activeSheet.merges).toEqual({
899
- 9: { id: 9, topLeft: "A1", top: 0, bottom: 6, left: 0, right: 0 },
900
- 10: { id: 10, topLeft: "B4", top: 3, bottom: 6, left: 1, right: 1 },
901
- 11: { id: 11, topLeft: "C5", top: 4, bottom: 6, left: 2, right: 2 },
902
- 12: { id: 12, topLeft: "D4", top: 3, bottom: 5, left: 3, right: 3 },
903
- });
904
- expect(model["workbook"].activeSheet.mergeCellMap).toEqual({
905
- A1: 9,
906
- A2: 9,
907
- A3: 9,
908
- A4: 9,
909
- A5: 9,
910
- A6: 9,
911
- A7: 9,
912
- B4: 10,
913
- B5: 10,
914
- B6: 10,
915
- B7: 10,
916
- C5: 11,
917
- C6: 11,
918
- C7: 11,
919
- D4: 12,
920
- D5: 12,
921
- D6: 12,
922
- });
923
- });
924
- });
925
-
926
- describe("Correctly update border and style", () => {
927
- beforeEach(() => {
928
- model = new Model({
929
- sheets: [
930
- {
931
- colNumber: 4,
932
- rowNumber: 4,
933
- cells: {
934
- A1: { style: 1 },
935
- A2: { style: 1 },
936
- A4: { style: 1 },
937
- B1: { border: 1 },
938
- B2: { border: 1 },
939
- B4: { border: 1 },
940
- C1: { style: 1, border: 1 },
941
- C2: { style: 1, border: 1, format: "0.00%" },
942
- C4: { style: 1, border: 1 },
943
- D2: { style: 1, border: 1 },
944
- },
945
- merges: ["D2:D3"],
946
- },
947
- ],
948
- styles: { 1: { textColor: "#fe0000" } },
949
- borders: { 1: { top: ["thin", "#000"] } },
950
- });
951
- });
952
- test("On deletion", () => {
953
- removeRows([1]);
954
- expect(model["workbook"].activeSheet.cells.A2).toBeUndefined();
955
- expect(model["workbook"].activeSheet.cells.B2).toBeUndefined();
956
- expect(model["workbook"].activeSheet.cells.C2).toBeUndefined();
957
- expect(model["workbook"].activeSheet.cells).toMatchObject({
958
- A1: { style: 1 },
959
- A3: { style: 1 },
960
- B1: { border: 1 },
961
- B3: { border: 1 },
962
- C1: { style: 1, border: 1 },
963
- C3: { style: 1, border: 1 },
964
- D2: { style: 1, border: 1 },
965
- });
966
- });
967
-
968
- test("On addition", () => {
969
- addRows(1, "before", 1);
970
- addRows(2, "after", 2);
971
- expect(model["workbook"].activeSheet.cells).toMatchObject({
972
- A1: { style: 1 },
973
- B1: { border: 1 },
974
- C1: { style: 1, border: 1 },
975
- A2: { style: 1 },
976
- B2: { border: 1 },
977
- C2: { style: 1, border: 1, format: "0.00%" },
978
- D2: { style: 1 },
979
- A3: { style: 1 },
980
- B3: { border: 1 },
981
- C3: { style: 1, border: 1, format: "0.00%" },
982
- D3: { style: 1, border: 1 },
983
- A5: { style: 1 },
984
- });
985
- expect(Object.values(model["workbook"].activeSheet.merges)[0]).toMatchObject({
986
- top: 2,
987
- bottom: 5,
988
- topLeft: "D3",
989
- });
990
- });
991
- });
992
-
993
- describe("Correctly update references", () => {
994
- beforeEach(() => {
995
- model = new Model({
996
- sheets: [
997
- {
998
- colNumber: 7,
999
- rowNumber: 7,
1000
- cells: {
1001
- A1: { content: "=A2" },
1002
- A4: { content: "=A1" },
1003
- B1: { content: "=Sheet1!A2" },
1004
- B4: { content: "=B1" },
1005
- C1: { content: "=Sheet2!A2" },
1006
- C4: { content: "=A$5" },
1007
- D4: { content: "=C4" },
1008
- E1: { content: "=SUM(A1:A4)" },
1009
- F1: { content: "=SUM(A3:A4)" },
1010
- G1: { content: "=SUM(B2:C2)" },
1011
- },
1012
- },
1013
- {
1014
- colNumber: 3,
1015
- rowNumber: 1,
1016
- cells: {
1017
- A1: { content: "=A2" },
1018
- B1: { content: "=Sheet1!A2" },
1019
- C1: { content: "=Sheet2!A2" },
1020
- },
1021
- },
1022
- ],
1023
- });
1024
- });
1025
-
1026
- test("On deletion", () => {
1027
- removeRows([1, 2]);
1028
- expect(getSheet(model, 0).cells).toMatchObject({
1029
- A1: { content: "=#REF" },
1030
- A2: { content: "=A1" },
1031
- B1: { content: "=#REF" },
1032
- B2: { content: "=B1" },
1033
- C1: { content: "=Sheet2!A2" },
1034
- C2: { content: "=A$3" },
1035
- D2: { content: "=C2" },
1036
- });
1037
- expect(getSheet(model, 1).cells).toMatchObject({
1038
- A1: { content: "=A2" },
1039
- B1: { content: "=#REF" },
1040
- C1: { content: "=Sheet2!A2" },
1041
- });
1042
- });
1043
- test("delete row on inactive sheet", () => {
1044
- const model = new Model({
1045
- sheets: [
1046
- {
1047
- colNumber: 4,
1048
- rowNumber: 7,
1049
- cells: {
1050
- B2: { content: "=Sheet1!A2" },
1051
- C1: { content: "=Sheet2!A2" },
1052
- },
1053
- },
1054
- {
1055
- colNumber: 3,
1056
- rowNumber: 2,
1057
- cells: {
1058
- A2: { content: "=B2" },
1059
- B2: { content: "=Sheet1!A2" },
1060
- C2: { content: "=Sheet2!A2" },
1061
- },
1062
- },
1063
- ],
1064
- });
1065
- const [sheet1, sheet2] = model.getters.getSheets();
1066
- expect(sheet2.id).not.toBe(model.getters.getActiveSheet()),
1067
- model.dispatch("REMOVE_ROWS", {
1068
- rows: [0],
1069
- sheet: sheet2.id,
1070
- });
1071
- expect(sheet1.cells).toMatchObject({
1072
- B2: { content: "=Sheet1!A2" },
1073
- C1: { content: "=Sheet2!A1" },
1074
- });
1075
- expect(sheet2.cells).toMatchObject({
1076
- A1: { content: "=B1" },
1077
- B1: { content: "=Sheet1!A2" },
1078
- C1: { content: "=Sheet2!A1" },
1079
- });
1080
- });
1081
- test("On first row deletion", () => {
1082
- model = new Model({
1083
- sheets: [
1084
- {
1085
- colNumber: 3,
1086
- rowNumber: 3,
1087
- cells: {
1088
- B2: { content: "=SUM(A1:A3)" },
1089
- },
1090
- },
1091
- ],
1092
- });
1093
- removeRows([0]);
1094
- expect(getSheet(model, 0).cells).toMatchObject({
1095
- B1: { content: "=SUM(A1:A2)" },
1096
- });
1097
- });
1098
-
1099
- test("with space in the sheet name", () => {
1100
- model = new Model({
1101
- sheets: [
1102
- {
1103
- id: "sheet1",
1104
- name: "Sheet 1",
1105
- colNumber: 3,
1106
- rowNumber: 3,
1107
- cells: {
1108
- C2: { content: "=SUM('Sheet 1'!B2)" },
1109
- C3: { content: "=SUM('Sheet 1'!B2:B3)" },
1110
- },
1111
- },
1112
- ],
1113
- });
1114
- removeRows([0]);
1115
- expect(getSheet(model, 0).cells).toMatchObject({
1116
- C1: { content: "=SUM('Sheet 1'!B1)" },
1117
- C2: { content: "=SUM('Sheet 1'!B1:B2)" },
1118
- });
1119
- removeColumns([0]);
1120
- expect(getSheet(model, 0).cells).toMatchObject({
1121
- B1: { content: "=SUM('Sheet 1'!A1)" },
1122
- B2: { content: "=SUM('Sheet 1'!A1:A2)" },
1123
- });
1124
- addColumns(0, "before", 1);
1125
- expect(getSheet(model, 0).cells).toMatchObject({
1126
- C1: { content: "=SUM('Sheet 1'!B1)" },
1127
- C2: { content: "=SUM('Sheet 1'!B1:B2)" },
1128
- });
1129
- addRows(0, "before", 1);
1130
- expect(getSheet(model, 0).cells).toMatchObject({
1131
- C2: { content: "=SUM('Sheet 1'!B2)" },
1132
- C3: { content: "=SUM('Sheet 1'!B2:B3)" },
1133
- });
1134
- });
1135
- test("On multiple row deletion including the first one", () => {
1136
- model = new Model({
1137
- sheets: [
1138
- {
1139
- colNumber: 3,
1140
- rowNumber: 6,
1141
- cells: {
1142
- B1: { content: "=SUM(A2:A5)" },
1143
- },
1144
- },
1145
- ],
1146
- });
1147
- removeRows([1, 2]);
1148
- expect(getSheet(model, 0).cells).toMatchObject({
1149
- B1: { content: "=SUM(A2:A3)" },
1150
- });
1151
- });
1152
- test("strange test in Odoo", () => {
1153
- model = new Model({
1154
- sheets: [
1155
- {
1156
- colNumber: 1,
1157
- rowNumber: 1000,
1158
- cells: {
1159
- A5: { content: "=SUM(A6:A255)" },
1160
- A256: { content: "=SUM(A257:A506)" },
1161
- },
1162
- },
1163
- ],
1164
- });
1165
- const rows: number[] = [];
1166
- for (let i = 6; i <= 254; i++) {
1167
- rows.push(i);
1168
- }
1169
- for (let i = 257; i <= 605; i++) {
1170
- rows.push(i);
1171
- }
1172
-
1173
- removeRows(rows);
1174
- expect(getSheet(model, 0).cells).toMatchObject({
1175
- A5: { content: "=SUM(A6)" },
1176
- A7: { content: "=SUM(A8)" },
1177
- });
1178
- });
1179
- test("On last row deletion", () => {
1180
- model = new Model({
1181
- sheets: [
1182
- {
1183
- colNumber: 3,
1184
- rowNumber: 3,
1185
- cells: {
1186
- B1: { content: "=SUM(A1:A3)" },
1187
- },
1188
- },
1189
- ],
1190
- });
1191
- removeRows([2]);
1192
- expect(getSheet(model, 0).cells).toMatchObject({
1193
- B1: { content: "=SUM(A1:A2)" },
1194
- });
1195
- });
1196
- test("On multiple row", () => {
1197
- model = new Model({
1198
- sheets: [
1199
- {
1200
- colNumber: 1,
1201
- rowNumber: 8,
1202
- cells: {
1203
- A1: { content: "=SUM(A2:A5)" },
1204
- },
1205
- },
1206
- ],
1207
- });
1208
- removeRows([2, 3]);
1209
- expect(getSheet(model, 0).cells).toMatchObject({
1210
- A1: { content: "=SUM(A2:A3)" },
1211
- });
1212
- });
1213
- test("On multiple rows (7)", () => {
1214
- model = new Model({
1215
- sheets: [
1216
- {
1217
- colNumber: 1,
1218
- rowNumber: 8,
1219
- cells: {
1220
- A1: { content: "=SUM(A2:A8)" },
1221
- },
1222
- },
1223
- ],
1224
- });
1225
- removeRows([1, 2, 3, 4, 5, 6]);
1226
- expect(getSheet(model, 0).cells).toMatchObject({
1227
- A1: { content: "=SUM(A2)" },
1228
- });
1229
- });
1230
- test("On multiple row deletion including the last one", () => {
1231
- model = new Model({
1232
- sheets: [
1233
- {
1234
- colNumber: 4,
1235
- rowNumber: 4,
1236
- cells: {
1237
- B1: { content: "=SUM(A1:A4)" },
1238
- },
1239
- },
1240
- ],
1241
- });
1242
- removeRows([2, 3]);
1243
- expect(getSheet(model, 0).cells).toMatchObject({
1244
- B1: { content: "=SUM(A1:A2)" },
1245
- });
1246
- });
1247
- test("On multiple row deletion including the last and beyond", () => {
1248
- model = new Model({
1249
- sheets: [
1250
- {
1251
- colNumber: 2,
1252
- rowNumber: 8,
1253
- cells: {
1254
- B2: { content: "=SUM(A1:A4)" },
1255
- },
1256
- },
1257
- ],
1258
- });
1259
- removeRows([3, 4, 5, 6, 7]);
1260
- expect(getSheet(model, 0).cells).toMatchObject({
1261
- B2: { content: "=SUM(A1:A3)" },
1262
- });
1263
- });
1264
- test("On addition", () => {
1265
- addRows(1, "before", 1);
1266
- addRows(0, "after", 1);
1267
- expect(getSheet(model, 0).cells).toMatchObject({
1268
- A1: { content: "=A4" },
1269
- A6: { content: "=A1" },
1270
- B1: { content: "=Sheet1!A4" },
1271
- B6: { content: "=B1" },
1272
- C1: { content: "=Sheet2!A2" },
1273
- C6: { content: "=A$7" },
1274
- D6: { content: "=C6" },
1275
- E1: { content: "=SUM(A1:A6)" },
1276
- F1: { content: "=SUM(A5:A6)" },
1277
- G1: { content: "=SUM(B4:C4)" },
1278
- });
1279
- expect(getSheet(model, 1).cells).toMatchObject({
1280
- A1: { content: "=A2" },
1281
- B1: { content: "=Sheet1!A4" },
1282
- C1: { content: "=Sheet2!A2" },
1283
- });
1284
- });
1285
- });
1286
-
1287
- describe("Correctly handle undo/redo", () => {
1288
- test("On deletion", () => {
1289
- model = new Model(fullData);
1290
- const beforeRemove = model.exportData();
1291
- removeRows([0, 2]);
1292
- const afterRemove = model.exportData();
1293
- undo();
1294
- expect(model.exportData()).toEqual(beforeRemove);
1295
- redo();
1296
- expect(model.exportData()).toEqual(afterRemove);
1297
- });
1298
-
1299
- test("On addition", () => {
1300
- model = new Model(fullData);
1301
- const beforeAdd = model.exportData();
1302
- addRows(2, "before", 2);
1303
- const afterAdd1 = model.exportData();
1304
- addRows(4, "after", 4);
1305
- const afterAdd2 = model.exportData();
1306
- undo();
1307
- expect(model.exportData()).toEqual(afterAdd1);
1308
- redo();
1309
- expect(model.exportData()).toEqual(afterAdd2);
1310
- undo();
1311
- undo();
1312
- expect(model.exportData()).toEqual(beforeAdd);
1313
- });
1314
- });
1315
-
1316
- describe("Correctly update selection", () => {
1317
- test("On add top 1", () => {
1318
- model = new Model(fullData);
1319
- const zone = { left: 2, right: 3, top: 0, bottom: 1 };
1320
- model.dispatch("SET_SELECTION", {
1321
- zones: [zone],
1322
- anchor: [zone.left, zone.top],
1323
- strict: true,
1324
- });
1325
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 1, left: 2, right: 3, top: 0 });
1326
- addRows(0, "before", 1);
1327
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 2, right: 3, top: 1 });
1328
- });
1329
- test("On add top 3", () => {
1330
- model = new Model(fullData);
1331
- const zone = { left: 2, right: 3, top: 0, bottom: 1 };
1332
- model.dispatch("SET_SELECTION", {
1333
- zones: [zone],
1334
- anchor: [zone.left, zone.top],
1335
- strict: true,
1336
- });
1337
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 1, left: 2, right: 3, top: 0 });
1338
- addRows(0, "before", 3);
1339
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 4, left: 2, right: 3, top: 3 });
1340
- });
1341
- test("On add bottom 1", () => {
1342
- model = new Model(fullData);
1343
- const zone = { left: 2, right: 3, top: 0, bottom: 1 };
1344
- model.dispatch("SET_SELECTION", {
1345
- zones: [zone],
1346
- anchor: [zone.left, zone.top],
1347
- strict: true,
1348
- });
1349
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 1, left: 2, right: 3, top: 0 });
1350
- addRows(0, "after", 1);
1351
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 1, left: 2, right: 3, top: 0 });
1352
- });
1353
- test("On add bottom 3", () => {
1354
- model = new Model(fullData);
1355
- const zone = { left: 1, right: 3, top: 0, bottom: 2 };
1356
- model.dispatch("SET_SELECTION", {
1357
- zones: [zone],
1358
- anchor: [zone.left, zone.top],
1359
- strict: true,
1360
- });
1361
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
1362
- addRows(0, "after", 3);
1363
- expect(model.getters.getSelectedZone()).toEqual({ bottom: 2, left: 1, right: 3, top: 0 });
1364
- });
1365
- });
1366
- });