@borgar/fx 4.13.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/dist/index-BMr6cTgc.d.cts +1444 -0
  2. package/dist/index-BMr6cTgc.d.ts +1444 -0
  3. package/dist/index.cjs +3054 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +1 -0
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +2984 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/xlsx/index.cjs +3120 -0
  10. package/dist/xlsx/index.cjs.map +1 -0
  11. package/dist/xlsx/index.d.cts +55 -0
  12. package/dist/xlsx/index.d.ts +55 -0
  13. package/dist/xlsx/index.js +3049 -0
  14. package/dist/xlsx/index.js.map +1 -0
  15. package/docs/API.md +2959 -718
  16. package/docs/AST_format.md +2 -2
  17. package/eslint.config.mjs +40 -0
  18. package/lib/a1.spec.ts +32 -0
  19. package/lib/a1.ts +26 -0
  20. package/lib/addA1RangeBounds.ts +50 -0
  21. package/lib/addTokenMeta.spec.ts +166 -0
  22. package/lib/{addTokenMeta.js → addTokenMeta.ts} +53 -33
  23. package/lib/astTypes.ts +211 -0
  24. package/lib/cloneToken.ts +29 -0
  25. package/lib/{constants.js → constants.ts} +6 -3
  26. package/lib/fixRanges.spec.ts +220 -0
  27. package/lib/fixRanges.ts +260 -0
  28. package/lib/fromCol.spec.ts +15 -0
  29. package/lib/{fromCol.js → fromCol.ts} +1 -1
  30. package/lib/index.spec.ts +119 -0
  31. package/lib/index.ts +76 -0
  32. package/lib/isNodeType.ts +151 -0
  33. package/lib/isType.spec.ts +208 -0
  34. package/lib/{isType.js → isType.ts} +26 -25
  35. package/lib/lexers/{advRangeOp.js → advRangeOp.ts} +1 -1
  36. package/lib/lexers/{canEndRange.js → canEndRange.ts} +2 -2
  37. package/lib/lexers/{lexBoolean.js → lexBoolean.ts} +25 -6
  38. package/lib/lexers/{lexContext.js → lexContext.ts} +14 -6
  39. package/lib/lexers/{lexError.js → lexError.ts} +3 -3
  40. package/lib/lexers/{lexFunction.js → lexFunction.ts} +3 -2
  41. package/lib/lexers/lexNameFuncCntx.ts +112 -0
  42. package/lib/lexers/{lexNamed.js → lexNamed.ts} +4 -4
  43. package/lib/lexers/{lexNewLine.js → lexNewLine.ts} +3 -2
  44. package/lib/lexers/{lexNumber.js → lexNumber.ts} +4 -3
  45. package/lib/lexers/{lexOperator.js → lexOperator.ts} +5 -4
  46. package/lib/lexers/lexRange.ts +15 -0
  47. package/lib/lexers/{lexRangeA1.js → lexRangeA1.ts} +11 -7
  48. package/lib/lexers/{lexRangeR1C1.js → lexRangeR1C1.ts} +10 -6
  49. package/lib/lexers/{lexRangeTrim.js → lexRangeTrim.ts} +3 -2
  50. package/lib/lexers/{lexRefOp.js → lexRefOp.ts} +4 -3
  51. package/lib/lexers/{lexString.js → lexString.ts} +3 -3
  52. package/lib/lexers/{lexStructured.js → lexStructured.ts} +5 -5
  53. package/lib/lexers/{lexWhitespace.js → lexWhitespace.ts} +3 -2
  54. package/lib/lexers/sets.ts +51 -0
  55. package/lib/mergeRefTokens.spec.ts +141 -0
  56. package/lib/{mergeRefTokens.js → mergeRefTokens.ts} +14 -9
  57. package/lib/nodeTypes.ts +54 -0
  58. package/lib/parse.spec.ts +1410 -0
  59. package/lib/{parser.js → parse.ts} +81 -63
  60. package/lib/parseA1Range.spec.ts +233 -0
  61. package/lib/parseA1Range.ts +206 -0
  62. package/lib/parseA1Ref.spec.ts +337 -0
  63. package/lib/parseA1Ref.ts +115 -0
  64. package/lib/parseR1C1Range.ts +191 -0
  65. package/lib/parseR1C1Ref.spec.ts +323 -0
  66. package/lib/parseR1C1Ref.ts +127 -0
  67. package/lib/parseRef.spec.ts +90 -0
  68. package/lib/parseRef.ts +240 -0
  69. package/lib/{parseSRange.js → parseSRange.ts} +15 -10
  70. package/lib/parseStructRef.spec.ts +168 -0
  71. package/lib/parseStructRef.ts +76 -0
  72. package/lib/stringifyA1Range.spec.ts +72 -0
  73. package/lib/stringifyA1Range.ts +72 -0
  74. package/lib/stringifyA1Ref.spec.ts +64 -0
  75. package/lib/stringifyA1Ref.ts +59 -0
  76. package/lib/{stringifyPrefix.js → stringifyPrefix.ts} +17 -2
  77. package/lib/stringifyR1C1Range.spec.ts +92 -0
  78. package/lib/stringifyR1C1Range.ts +73 -0
  79. package/lib/stringifyR1C1Ref.spec.ts +63 -0
  80. package/lib/stringifyR1C1Ref.ts +67 -0
  81. package/lib/stringifyStructRef.spec.ts +124 -0
  82. package/lib/stringifyStructRef.ts +113 -0
  83. package/lib/stringifyTokens.ts +15 -0
  84. package/lib/toCol.spec.ts +11 -0
  85. package/lib/{toCol.js → toCol.ts} +4 -4
  86. package/lib/tokenTypes.ts +76 -0
  87. package/lib/tokenize-srefs.spec.ts +429 -0
  88. package/lib/tokenize.spec.ts +2103 -0
  89. package/lib/tokenize.ts +346 -0
  90. package/lib/translate.spec.ts +35 -0
  91. package/lib/translateToA1.spec.ts +247 -0
  92. package/lib/translateToA1.ts +231 -0
  93. package/lib/translateToR1C1.spec.ts +227 -0
  94. package/lib/translateToR1C1.ts +145 -0
  95. package/lib/types.ts +179 -0
  96. package/lib/xlsx/index.spec.ts +27 -0
  97. package/lib/xlsx/index.ts +32 -0
  98. package/package.json +45 -31
  99. package/tsconfig.json +28 -0
  100. package/typedoc-ignore-links.ts +17 -0
  101. package/typedoc.json +41 -0
  102. package/.eslintrc +0 -22
  103. package/benchmark/benchmark.js +0 -48
  104. package/benchmark/formulas.json +0 -15677
  105. package/dist/fx.d.ts +0 -823
  106. package/dist/fx.js +0 -2
  107. package/dist/package.json +0 -1
  108. package/lib/a1.js +0 -348
  109. package/lib/a1.spec.js +0 -458
  110. package/lib/addTokenMeta.spec.js +0 -153
  111. package/lib/astTypes.js +0 -96
  112. package/lib/extraTypes.js +0 -74
  113. package/lib/fixRanges.js +0 -104
  114. package/lib/fixRanges.spec.js +0 -171
  115. package/lib/fromCol.spec.js +0 -11
  116. package/lib/index.js +0 -134
  117. package/lib/index.spec.js +0 -67
  118. package/lib/isType.spec.js +0 -168
  119. package/lib/lexer-srefs.spec.js +0 -324
  120. package/lib/lexer.js +0 -264
  121. package/lib/lexer.spec.js +0 -1953
  122. package/lib/lexers/lexRange.js +0 -8
  123. package/lib/lexers/sets.js +0 -38
  124. package/lib/mergeRefTokens.spec.js +0 -121
  125. package/lib/package.json +0 -1
  126. package/lib/parseRef.js +0 -157
  127. package/lib/parseRef.spec.js +0 -71
  128. package/lib/parseStructRef.js +0 -48
  129. package/lib/parseStructRef.spec.js +0 -164
  130. package/lib/parser.spec.js +0 -1208
  131. package/lib/rc.js +0 -341
  132. package/lib/rc.spec.js +0 -403
  133. package/lib/stringifyStructRef.js +0 -80
  134. package/lib/stringifyStructRef.spec.js +0 -182
  135. package/lib/toCol.spec.js +0 -11
  136. package/lib/translate-toA1.spec.js +0 -214
  137. package/lib/translate-toRC.spec.js +0 -197
  138. package/lib/translate.js +0 -239
  139. package/lib/translate.spec.js +0 -21
  140. package/rollup.config.mjs +0 -22
  141. package/tsd.json +0 -12
package/lib/a1.spec.js DELETED
@@ -1,458 +0,0 @@
1
- /* eslint-disable object-property-newline, object-curly-newline */
2
- import { test, Test } from 'tape';
3
- import {
4
- fromRow,
5
- toRow,
6
- toRelative,
7
- toAbsolute,
8
- parseA1Ref,
9
- stringifyA1Ref,
10
- toA1
11
- } from './a1.js';
12
- import { MAX_COLS, MAX_ROWS } from './constants.js';
13
-
14
- Test.prototype.isA1Equal = function isA1Equal (expr, expect, opts) {
15
- if (expect) {
16
- expect = opts?.xlsx
17
- ? { workbookName: '', sheetName: '', ...expect }
18
- : { context: [], ...expect };
19
- Object.assign(expect, expect);
20
- if (expect.range && typeof expect.range === 'object') {
21
- // mix in some defaults so we don't have to write things out in full
22
- expect.range = {
23
- top: null, left: null, bottom: null, right: null,
24
- $top: false, $left: false, $bottom: false, $right: false,
25
- ...expect.range
26
- };
27
- }
28
- }
29
- this.deepEqual(parseA1Ref(expr, opts), expect, expr);
30
- };
31
-
32
- // What happens when B2:A1 -> should work!
33
- test('convert to and from column and row ids', t => {
34
- t.is(fromRow('11'), 10);
35
- t.is(fromRow('1'), 0);
36
- t.is(toRow(12), '13');
37
- t.is(toRow(77), '78');
38
- t.end();
39
- });
40
-
41
- test('parse A1 references', t => {
42
- t.isA1Equal('A1', { range: { top: 0, left: 0, bottom: 0, right: 0 } });
43
- t.isA1Equal('A1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1 } });
44
-
45
- t.isA1Equal('$A1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1, $left: true } });
46
- t.isA1Equal('A$1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1, $top: true } });
47
- t.isA1Equal('A1:$B2', { range: { top: 0, left: 0, bottom: 1, right: 1, $right: true } });
48
- t.isA1Equal('A1:B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, $bottom: true } });
49
-
50
- t.isA1Equal('A:A', { range: { left: 0, right: 0 } });
51
- t.isA1Equal('C:C', { range: { left: 2, right: 2 } });
52
- t.isA1Equal('C:$C', { range: { left: 2, right: 2, $right: true } });
53
- t.isA1Equal('$C:C', { range: { left: 2, right: 2, $left: true } });
54
- t.isA1Equal('$C:$C', { range: { left: 2, right: 2, $left: true, $right: true } });
55
-
56
- t.isA1Equal('1:1', { range: { top: 0, bottom: 0 } });
57
- t.isA1Equal('10:10', { range: { top: 9, bottom: 9 } });
58
- t.isA1Equal('10:$10', { range: { top: 9, bottom: 9, $bottom: true } });
59
- t.isA1Equal('$10:10', { range: { top: 9, bottom: 9, $top: true } });
60
- t.isA1Equal('$10:$10', { range: { top: 9, bottom: 9, $top: true, $bottom: true } });
61
-
62
- t.isA1Equal('XFD1048576', { range: { top: 1048575, left: 16383, bottom: 1048575, right: 16383 } });
63
-
64
- t.isA1Equal('Sheet1!A1', {
65
- context: [ 'Sheet1' ],
66
- range: { top: 0, left: 0, bottom: 0, right: 0 }
67
- });
68
-
69
- t.isA1Equal('\'Sheet1\'!A1', {
70
- context: [ 'Sheet1' ],
71
- range: { top: 0, left: 0, bottom: 0, right: 0 }
72
- });
73
-
74
- t.isA1Equal('\'Sheet1\'\'s\'!A1', {
75
- context: [ 'Sheet1\'s' ],
76
- range: { top: 0, left: 0, bottom: 0, right: 0 }
77
- });
78
-
79
- t.isA1Equal('[Workbook.xlsx]Sheet1!A1', {
80
- context: [ 'Workbook.xlsx', 'Sheet1' ],
81
- range: { top: 0, left: 0, bottom: 0, right: 0 }
82
- });
83
-
84
- t.isA1Equal("'[Workbook.xlsx]Sheet1'!A1", {
85
- context: [ 'Workbook.xlsx', 'Sheet1' ],
86
- range: { top: 0, left: 0, bottom: 0, right: 0 }
87
- });
88
-
89
- t.isA1Equal("'[Workbook.xlsx]Sheet1'!A1", {
90
- context: [ 'Workbook.xlsx', 'Sheet1' ],
91
- range: { top: 0, left: 0, bottom: 0, right: 0 }
92
- });
93
-
94
- t.isA1Equal("='[Workbook.xlsx]Sheet1'!A1", {
95
- context: [ 'Workbook.xlsx', 'Sheet1' ],
96
- range: { top: 0, left: 0, bottom: 0, right: 0 }
97
- });
98
-
99
- t.isA1Equal('[foo bar]Sheet1!A1', {
100
- context: [ 'foo bar', 'Sheet1' ],
101
- range: { top: 0, left: 0, bottom: 0, right: 0 }
102
- });
103
-
104
- t.isA1Equal('[a "b" c]d!A1', {
105
- context: [ 'a "b" c', 'd' ],
106
- range: { top: 0, left: 0, bottom: 0, right: 0 }
107
- });
108
-
109
- // unless we know the contexts available, we don't know that this is a sheet
110
- // or a filename, so we can't reject it:
111
- t.isA1Equal('0123456789abcdefghijklmnopqrstuvwxyz!A1', {
112
- context: [ '0123456789abcdefghijklmnopqrstuvwxyz' ],
113
- range: { top: 0, left: 0, bottom: 0, right: 0 }
114
- });
115
-
116
- t.isA1Equal('[Workbook.xlsx]!A1', null);
117
- t.isA1Equal('[Workbook.xlsx]!A1:B2', null);
118
- t.isA1Equal('[Workbook.xlsx]!A:A', null);
119
- t.isA1Equal('[Workbook.xlsx]!1:1', null);
120
- t.isA1Equal('[]Sheet1!A1', null);
121
- t.isA1Equal('namedrange', { name: 'namedrange' });
122
-
123
- t.isA1Equal('Workbook.xlsx!namedrange', {
124
- context: [ 'Workbook.xlsx' ],
125
- name: 'namedrange'
126
- });
127
-
128
- t.isA1Equal("'Workbook.xlsx'!namedrange", {
129
- context: [ 'Workbook.xlsx' ],
130
- name: 'namedrange'
131
- });
132
-
133
- t.isA1Equal('[Workbook.xlsx]!namedrange', null);
134
- t.isA1Equal('pensioneligibilitypartner1', { name: 'pensioneligibilitypartner1' });
135
- t.isA1Equal('XFE1048577', { name: 'XFE1048577' });
136
-
137
- // with named ranges disallowed
138
- t.isA1Equal('namedrange', null, { allowNamed: false });
139
- t.isA1Equal('Workbook.xlsx!namedrange', null, { allowNamed: false });
140
- t.isA1Equal('pensioneligibilitypartner1', null, { allowNamed: false });
141
- t.isA1Equal('XFE1048577', null, { allowNamed: false });
142
-
143
- t.end();
144
- });
145
-
146
- test('parse A1 ranges in XLSX mode', t => {
147
- const opts = { xlsx: true };
148
-
149
- t.isA1Equal('[1]!A1', {
150
- workbookName: '1',
151
- sheetName: '',
152
- range: { top: 0, left: 0, bottom: 0, right: 0 }
153
- }, opts);
154
-
155
- t.isA1Equal('[Workbook.xlsx]!A1', {
156
- workbookName: 'Workbook.xlsx',
157
- sheetName: '',
158
- range: { top: 0, left: 0, bottom: 0, right: 0 }
159
- }, opts);
160
-
161
- t.isA1Equal('[1]Sheet1!A1', {
162
- workbookName: '1',
163
- sheetName: 'Sheet1',
164
- range: { top: 0, left: 0, bottom: 0, right: 0 }
165
- }, opts);
166
-
167
- t.isA1Equal('[Workbook.xlsx]Sheet1!A1', {
168
- workbookName: 'Workbook.xlsx',
169
- sheetName: 'Sheet1',
170
- range: { top: 0, left: 0, bottom: 0, right: 0 }
171
- }, opts);
172
-
173
- t.isA1Equal('[4]!name', {
174
- workbookName: '4',
175
- sheetName: '',
176
- name: 'name'
177
- }, opts);
178
-
179
- t.isA1Equal('[Workbook.xlsx]!name', {
180
- workbookName: 'Workbook.xlsx',
181
- sheetName: '',
182
- name: 'name'
183
- }, opts);
184
-
185
- t.isA1Equal('[16]Sheet1!name', {
186
- workbookName: '16',
187
- sheetName: 'Sheet1',
188
- name: 'name'
189
- }, opts);
190
-
191
- t.isA1Equal('[Workbook.xlsx]Sheet1!name', {
192
- workbookName: 'Workbook.xlsx',
193
- sheetName: 'Sheet1',
194
- name: 'name'
195
- }, opts);
196
-
197
- t.isA1Equal("='[1]'!A1", {
198
- workbookName: '1',
199
- sheetName: '',
200
- range: { top: 0, left: 0, bottom: 0, right: 0 }
201
- }, opts);
202
-
203
- t.isA1Equal("='[Workbook.xlsx]'!A1", {
204
- workbookName: 'Workbook.xlsx',
205
- sheetName: '',
206
- range: { top: 0, left: 0, bottom: 0, right: 0 }
207
- }, opts);
208
-
209
- t.isA1Equal("'[1]Sheet1'!A1", {
210
- workbookName: '1',
211
- sheetName: 'Sheet1',
212
- range: { top: 0, left: 0, bottom: 0, right: 0 }
213
- }, opts);
214
-
215
- t.isA1Equal("'[Workbook.xlsx]Sheet1'!A1", {
216
- workbookName: 'Workbook.xlsx',
217
- sheetName: 'Sheet1',
218
- range: { top: 0, left: 0, bottom: 0, right: 0 }
219
- }, opts);
220
-
221
- t.isA1Equal("'[4]'!name", {
222
- workbookName: '4',
223
- sheetName: '',
224
- name: 'name'
225
- }, opts);
226
-
227
- t.isA1Equal("'[Workbook.xlsx]'!name", {
228
- workbookName: 'Workbook.xlsx',
229
- sheetName: '',
230
- name: 'name'
231
- }, opts);
232
-
233
- t.isA1Equal("'[16]Sheet1'!name", {
234
- workbookName: '16',
235
- sheetName: 'Sheet1',
236
- name: 'name'
237
- }, opts);
238
-
239
- t.isA1Equal("'[Workbook.xlsx]Sheet1'!name", {
240
- workbookName: 'Workbook.xlsx',
241
- sheetName: 'Sheet1',
242
- name: 'name'
243
- }, opts);
244
-
245
- t.end();
246
- });
247
-
248
- test('A1 partial ranges', t => {
249
- const opt = { allowTernary: true };
250
- // partials are not allowed by defult
251
- t.isA1Equal('A10:A', null);
252
- t.isA1Equal('B3:2', null);
253
- // unbounded bottom:
254
- t.isA1Equal('A10:A', { range: { top: 9, left: 0, right: 0 } }, opt);
255
- t.isA1Equal('A:A10', { range: { top: 9, left: 0, right: 0 } }, opt);
256
- t.isA1Equal('A$5:A', { range: { top: 4, left: 0, right: 0, $top: true } }, opt);
257
- t.isA1Equal('A:A$5', { range: { top: 4, left: 0, right: 0, $top: true } }, opt);
258
- t.isA1Equal('A$5:A', { range: { top: 4, left: 0, right: 0, $top: true } }, opt);
259
- t.isA1Equal('A:$B5', { range: { top: 4, left: 0, right: 1, $right: true } }, opt);
260
- t.isA1Equal('$B:B3', { range: { top: 2, left: 1, right: 1, $left: true } }, opt);
261
- t.isA1Equal('$B:C5', { range: { top: 4, left: 1, right: 2, $left: true } }, opt);
262
- t.isA1Equal('C2:B', { range: { top: 1, left: 1, right: 2 } }, opt);
263
- t.isA1Equal('C:B2', { range: { top: 1, left: 1, right: 2 } }, opt);
264
- // unbounded right:
265
- t.isA1Equal('D1:1', { range: { top: 0, left: 3, bottom: 0 } }, opt);
266
- t.isA1Equal('1:D2', { range: { top: 0, left: 3, bottom: 1 } }, opt);
267
- t.isA1Equal('2:$D3', { range: { top: 1, left: 3, bottom: 2, $left: true } }, opt);
268
- t.isA1Equal('$D2:3', { range: { top: 1, left: 3, bottom: 2, $left: true } }, opt);
269
- t.isA1Equal('1:D$1', { range: { top: 0, left: 3, bottom: 0, $bottom: true } }, opt);
270
- t.isA1Equal('$1:D1', { range: { top: 0, left: 3, bottom: 0, $top: true } }, opt);
271
- t.isA1Equal('AA$3:4', { range: { top: 2, left: 26, bottom: 3, $top: true } }, opt);
272
- t.isA1Equal('B3:2', { range: { top: 1, bottom: 2, left: 1 } }, opt);
273
- t.isA1Equal('3:B2', { range: { top: 1, bottom: 2, left: 1 } }, opt);
274
- t.end();
275
- });
276
-
277
- test('A1 trimmed ranges', t => {
278
- const locks = { $top: true, $left: true, $bottom: true, $right: true };
279
- const opts = [ {}, { xlsx: true } ];
280
- for (const opt of opts) {
281
- t.isA1Equal('A1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1 } }, opt);
282
- t.isA1Equal('A1.:B2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'head' } }, opt);
283
- t.isA1Equal('A1:.B2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'tail' } }, opt);
284
- t.isA1Equal('A1.:.B2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'both' } }, opt);
285
-
286
- t.isA1Equal('$A$1:$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, ...locks } }, opt);
287
- t.isA1Equal('$A$1.:$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'head', ...locks } }, opt);
288
- t.isA1Equal('$A$1:.$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'tail', ...locks } }, opt);
289
- t.isA1Equal('$A$1.:.$B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, trim: 'both', ...locks } }, opt);
290
-
291
- t.isA1Equal('J:J', { range: { top: null, left: 9, bottom: null, right: 9 } }, opt);
292
- t.isA1Equal('J.:J', { range: { top: null, left: 9, bottom: null, right: 9, trim: 'head' } }, opt);
293
- t.isA1Equal('J:.J', { range: { top: null, left: 9, bottom: null, right: 9, trim: 'tail' } }, opt);
294
- t.isA1Equal('J.:.J', { range: { top: null, left: 9, bottom: null, right: 9, trim: 'both' } }, opt);
295
-
296
- t.isA1Equal('10:10', { range: { top: 9, left: null, bottom: 9, right: null } }, opt);
297
- t.isA1Equal('10.:10', { range: { top: 9, left: null, bottom: 9, right: null, trim: 'head' } }, opt);
298
- t.isA1Equal('10:.10', { range: { top: 9, left: null, bottom: 9, right: null, trim: 'tail' } }, opt);
299
- t.isA1Equal('10.:.10', { range: { top: 9, left: null, bottom: 9, right: null, trim: 'both' } }, opt);
300
-
301
- t.isA1Equal('J10:J', null, { ...opt });
302
- t.isA1Equal('J10:10', null, { ...opt });
303
- t.isA1Equal('J10.:.J', null, { ...opt });
304
- t.isA1Equal('J10.:.10', null, { ...opt });
305
- t.isA1Equal('J10:J', { range: { top: 9, left: 9, bottom: null, right: 9 } }, { allowTernary: true, ...opt });
306
- t.isA1Equal('J10:10', { range: { top: 9, left: 9, bottom: 9, right: null } }, { allowTernary: true, ...opt });
307
- t.isA1Equal('J10.:.J', { range: { top: 9, left: 9, bottom: null, right: 9, trim: 'both' } }, { allowTernary: true, ...opt });
308
- t.isA1Equal('J10.:.10', { range: { top: 9, left: 9, bottom: 9, right: null, trim: 'both' } }, { allowTernary: true, ...opt });
309
- }
310
- t.end();
311
- });
312
-
313
- test('A1 trimmed ranges vs named ranges', t => {
314
- // named ranges cannot be trimmed
315
- t.isA1Equal('name1.:.name1', null);
316
- t.isA1Equal('name1.:.foo', null);
317
- t.isA1Equal('foo.:.name1', null);
318
- // prior to the intruduction of trimed ranges, the following would have
319
- // been an expression: NAME:`foo.` OP:`:`, COLUMN:`bar`
320
- t.isA1Equal('foo.:bar', { range: { left: 1395, right: 4460, trim: 'head' } });
321
- // prior to the intruduction of trimed ranges, the following would have
322
- // been an expression: NAME:`foo.` OP:`:`, CELL:`B2`
323
- t.isA1Equal('foo.:B2', { range: { top: 1, left: 1, right: 4460, trim: 'head' } }, { allowTernary: true });
324
- t.end();
325
- });
326
-
327
- test('A1 serialization', t => {
328
- // cell: A1
329
- t.is(toA1({ top: 9, bottom: 9, left: 2, right: 2 }), 'C10', 'C10');
330
- t.is(toA1({ top: 9, bottom: 9, left: 2, right: 2, $top: true, $bottom: true }), 'C$10', 'C$10');
331
- t.is(toA1({ top: 9, bottom: 9, left: 2, right: 2, $left: true, $right: true }), '$C10', '$C10');
332
- t.is(toA1({ top: 9, bottom: 9, left: 2, right: 2, $top: true, $bottom: true, $left: true, $right: true }), '$C$10', '$C$10');
333
- // rect: A1:A1
334
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4 }), 'E3', 'E3');
335
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4, $right: true }), 'E3:$E3', 'E3:$E3');
336
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4, $top: true }), 'E$3:E3', 'E$3:E3');
337
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4, $left: true }), '$E3:E3', '$E3:E3');
338
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4, $bottom: true }), 'E3:E$3', 'E3:E$3');
339
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4, $bottom: true, $right: true }), 'E3:$E$3', 'E3:$E$3');
340
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 5 }), 'E3:F3', 'E3:F3');
341
- t.is(toA1({ top: 2, bottom: 3, left: 4, right: 4 }), 'E3:E4', 'E3:E4');
342
- t.is(toA1({ top: 2, bottom: 3, left: 4, right: 5 }), 'E3:F4', 'E3:F4');
343
- // ray: A:A, 1:1
344
- t.is(toA1({ left: 0, right: 0 }), 'A:A', '1:A');
345
- t.is(toA1({ top: 0, bottom: MAX_ROWS, left: 0, right: 0 }), 'A:A', 'A:A (2)');
346
- t.is(toA1({ left: 10, right: 15 }), 'K:P', 'K:P');
347
- t.is(toA1({ left: 10, right: 15, $left: true }), '$K:P', '$K:P');
348
- t.is(toA1({ left: 10, right: 15, $right: true }), 'K:$P', 'K:$P');
349
- t.is(toA1({ left: 10, right: 15, $left: true, $right: true }), '$K:$P', '$K:$P');
350
- t.is(toA1({ top: 0, bottom: 0 }), '1:1', '1:1');
351
- t.is(toA1({ top: 0, bottom: 0, left: 0, right: MAX_COLS }), '1:1', '1:1 (2)');
352
- t.is(toA1({ top: 10, bottom: 15 }), '11:16', '11:16');
353
- t.is(toA1({ top: 10, bottom: 15, $top: true }), '$11:16', '$11:16');
354
- t.is(toA1({ top: 10, bottom: 15, $bottom: true }), '11:$16', '11:$16');
355
- t.is(toA1({ top: 10, bottom: 15, $top: true, $bottom: true }), '$11:$16', '$11:$16');
356
- // partial: A1:A, A1:1, A:A1, 1:A1
357
- t.is(toA1({ top: 9, left: 0, right: 0 }), 'A10:A', 'A10:A');
358
- t.is(toA1({ bottom: 9, left: 0, right: 0 }), 'A10:A', 'A:A10 → A10:A');
359
- t.is(toA1({ top: 9, left: 0, right: 0, $top: true }), 'A$10:A', 'A$10:A');
360
- t.is(toA1({ top: 9, left: 0, right: 0, $left: true }), '$A10:A', '$A10:A');
361
- t.is(toA1({ top: 9, left: 0, right: 0, $right: true }), 'A10:$A', 'A10:$A');
362
- t.is(toA1({ top: 0, left: 3, bottom: 0 }), 'D1:1', 'D1:1');
363
- t.is(toA1({ top: 0, right: 3, bottom: 0 }), 'D1:1', '1:D1 → D1:1');
364
- t.is(toA1({ top: 0, left: 3, bottom: 0, $top: true }), 'D$1:1', 'D$1:1');
365
- t.is(toA1({ top: 0, left: 3, bottom: 0, $left: true }), '$D1:1', '$D1:1');
366
- t.is(toA1({ top: 0, left: 3, bottom: 0, $left: true }), '$D1:1', '$D1:1');
367
- // allow skipping right/bottom for cells
368
- t.is(toA1({ top: 0, left: 0 }), 'A1', 'A1');
369
- // clamp the range at min/max dimensions
370
- t.is(toA1({ top: -10, bottom: -5, left: -10, right: -5 }), 'A1', 'A1');
371
- t.is(toA1({ top: 15e5, bottom: 15e5, left: 20000, right: 20000 }), 'XFD1048576', 'XFD1048576');
372
- t.is(toA1({ top: 2, bottom: 2, left: 2.5, right: 2.5 }), 'C3', 'C3');
373
- t.is(toA1({ top: 1.5, bottom: 2.5, left: 4.5, right: 8.5 }), 'E2:I3', 'E2:I3');
374
- // triming
375
- t.is(toA1({ top: 2, bottom: 2, left: 4, right: 4, trim: 'both' }), 'E3', 'E3');
376
- t.is(toA1({ top: 2, bottom: 3, left: 4, right: 6, trim: 'both' }), 'E3.:.G4', 'E3.:.G4');
377
- t.is(toA1({ top: 2, bottom: 3, trim: 'both' }), '3.:.4', '3.:.4');
378
- t.is(toA1({ left: 4, right: 6, trim: 'both' }), 'E.:.G', 'E.:.G');
379
- t.is(toA1({ top: 9, left: 0, right: 0, trim: 'tail' }), 'A10:.A', 'A10:.A');
380
- t.is(toA1({ top: 9, left: 0, right: 0, trim: 'head' }), 'A10.:A', 'A10.:A');
381
- t.is(toA1({ top: 9, left: 0, right: 0, trim: 'both' }), 'A10.:.A', 'A10.:.A');
382
-
383
- t.end();
384
- });
385
-
386
- test('stringifyA1Ref', t => {
387
- const rangeA1 = { top: 0, bottom: 0, left: 0, right: 0 };
388
- const testRef = (ref, expect) => t.is(stringifyA1Ref(ref), expect, expect);
389
- testRef({ range: rangeA1 }, 'A1');
390
- testRef({ context: [ 'Sheet1' ], range: rangeA1 }, 'Sheet1!A1');
391
- testRef({ context: [ 'Sheet 1' ], range: rangeA1 }, "'Sheet 1'!A1");
392
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], range: rangeA1 }, '[MyFile.xlsx]Sheet1!A1');
393
- testRef({ context: [ 'My File.xlsx', 'Sheet1' ], range: rangeA1 }, "'[My File.xlsx]Sheet1'!A1");
394
- testRef({ context: [ 'MyFile.xlsx' ], range: rangeA1 }, 'MyFile.xlsx!A1');
395
- testRef({ context: [ 'My File.xlsx' ], range: rangeA1 }, "'My File.xlsx'!A1");
396
- testRef({ name: 'foo' }, 'foo');
397
- testRef({ context: [ 'Sheet1' ], name: 'foo' }, 'Sheet1!foo');
398
- testRef({ context: [ 'Sheet 1' ], name: 'foo' }, "'Sheet 1'!foo");
399
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], name: 'foo' }, '[MyFile.xlsx]Sheet1!foo');
400
- testRef({ context: [ 'My File.xlsx', 'Sheet1' ], name: 'foo' }, "'[My File.xlsx]Sheet1'!foo");
401
- testRef({ context: [ 'MyFile.xlsx' ], name: 'foo' }, 'MyFile.xlsx!foo');
402
- testRef({ context: [ 'My File.xlsx' ], name: 'foo' }, "'My File.xlsx'!foo");
403
- // ignore .workbookName/.sheetName
404
- testRef({ workbookName: 'MyFile.xlsx', sheetName: 'Sheet1', range: rangeA1 }, 'A1');
405
- testRef({ workbookName: 'MyFile.xlsx', sheetName: 'Sheet1', name: 'foo' }, 'foo');
406
- t.end();
407
- });
408
-
409
- test('stringifyA1Ref in XLSX mode', t => {
410
- const rangeA1 = { top: 0, bottom: 0, left: 0, right: 0 };
411
- const testRef = (ref, expect) => t.is(stringifyA1Ref(ref, { xlsx: true }), expect, expect);
412
- testRef({ range: rangeA1 }, 'A1');
413
- testRef({ sheetName: 'Sheet1', range: rangeA1 }, 'Sheet1!A1');
414
- testRef({ sheetName: 'Sheet 1', range: rangeA1 }, "'Sheet 1'!A1");
415
- testRef({ workbookName: 'MyFile.xlsx', sheetName: 'Sheet1', range: rangeA1 }, '[MyFile.xlsx]Sheet1!A1');
416
- testRef({ workbookName: 'My File.xlsx', sheetName: 'Sheet1', range: rangeA1 }, "'[My File.xlsx]Sheet1'!A1");
417
- testRef({ workbookName: 'MyFile.xlsx', range: rangeA1 }, '[MyFile.xlsx]!A1');
418
- testRef({ workbookName: 'My File.xlsx', range: rangeA1 }, "'[My File.xlsx]'!A1");
419
- testRef({ name: 'foo' }, 'foo');
420
- testRef({ sheetName: 'Sheet1', name: 'foo' }, 'Sheet1!foo');
421
- testRef({ sheetName: 'Sheet 1', name: 'foo' }, "'Sheet 1'!foo");
422
- testRef({ workbookName: 'MyFile.xlsx', sheetName: 'Sheet1', name: 'foo' }, '[MyFile.xlsx]Sheet1!foo');
423
- testRef({ workbookName: 'My File.xlsx', sheetName: 'Sheet1', name: 'foo' }, "'[My File.xlsx]Sheet1'!foo");
424
- testRef({ workbookName: 'MyFile.xlsx', name: 'foo' }, '[MyFile.xlsx]!foo');
425
- testRef({ workbookName: 'My File.xlsx', name: 'foo' }, "'[My File.xlsx]'!foo");
426
- // ignore .context
427
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], range: rangeA1 }, 'A1');
428
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], name: 'foo' }, 'foo');
429
- t.end();
430
- });
431
-
432
- test('A1 utilities', t => {
433
- const relA1Range = {
434
- top: 0, left: 0, bottom: 0, right: 0,
435
- $top: false, $left: false, $bottom: false, $right: false
436
- };
437
- const absA1Range = {
438
- top: 0, left: 0, bottom: 0, right: 0,
439
- $top: true, $left: true, $bottom: true, $right: true
440
- };
441
- t.deepEqual(toAbsolute(relA1Range), absA1Range, 'toAbsolute');
442
- t.deepEqual(toRelative(absA1Range), relA1Range, 'toRelative');
443
-
444
- const relA1RangeT = {
445
- top: 0, left: 0, bottom: 0, right: 0,
446
- $top: false, $left: false, $bottom: false, $right: false,
447
- trim: 'both'
448
- };
449
- const absA1RangeT = {
450
- top: 0, left: 0, bottom: 0, right: 0,
451
- $top: true, $left: true, $bottom: true, $right: true,
452
- trim: 'both'
453
- };
454
- t.deepEqual(toAbsolute(relA1RangeT), absA1RangeT, 'toAbsolute');
455
- t.deepEqual(toRelative(absA1RangeT), relA1RangeT, 'toRelative');
456
-
457
- t.end();
458
- });
@@ -1,153 +0,0 @@
1
- import { test, Test } from 'tape';
2
- import { FX_PREFIX, OPERATOR, NUMBER, REF_RANGE, REF_BEAM, FUNCTION, WHITESPACE, REF_STRUCT } from './constants.js';
3
- import { addTokenMeta } from './addTokenMeta.js';
4
- import { tokenize } from './lexer.js';
5
-
6
- Test.prototype.isMetaTokens = function isTokens (expr, expect, context, opts) {
7
- const actual = addTokenMeta(tokenize(expr, opts), context);
8
- if (actual.length === expect.length) {
9
- actual.forEach((d, i) => {
10
- const keys = Object.keys(d).concat(Object.keys(expect[i]));
11
- keys.forEach(key => {
12
- if (actual[i][key] === expect[i][key]) {
13
- delete actual[i][key];
14
- delete expect[i][key];
15
- }
16
- });
17
- });
18
- }
19
- this.deepEqual(actual, expect, expr);
20
- };
21
-
22
- test('add extra meta to operators', t => {
23
- // parens should be grouped and tagged with depth
24
- t.isMetaTokens('=((1)+(1))', [
25
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
26
- { index: 1, depth: 1, type: OPERATOR, value: '(', groupId: 'fxg3' },
27
- { index: 2, depth: 2, type: OPERATOR, value: '(', groupId: 'fxg1' },
28
- { index: 3, depth: 2, type: NUMBER, value: '1' },
29
- { index: 4, depth: 2, type: OPERATOR, value: ')', groupId: 'fxg1' },
30
- { index: 5, depth: 1, type: OPERATOR, value: '+' },
31
- { index: 6, depth: 2, type: OPERATOR, value: '(', groupId: 'fxg2' },
32
- { index: 7, depth: 2, type: NUMBER, value: '1' },
33
- { index: 8, depth: 2, type: OPERATOR, value: ')', groupId: 'fxg2' },
34
- { index: 9, depth: 1, type: OPERATOR, value: ')', groupId: 'fxg3' }
35
- ]);
36
-
37
- // don't be fooled by imbalanced parens
38
- t.isMetaTokens('=)())', [
39
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
40
- { index: 1, depth: 0, type: OPERATOR, value: ')', error: true },
41
- { index: 2, depth: 1, type: OPERATOR, value: '(', groupId: 'fxg1' },
42
- { index: 3, depth: 1, type: OPERATOR, value: ')', groupId: 'fxg1' },
43
- { index: 4, depth: 0, type: OPERATOR, value: ')', error: true }
44
- ]);
45
-
46
- // don't be fooled by nested curlys
47
- t.isMetaTokens('={{}}', [
48
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
49
- { index: 1, depth: 1, type: OPERATOR, value: '{', groupId: 'fxg1' },
50
- { index: 2, depth: 1, type: OPERATOR, value: '{', error: true },
51
- { index: 3, depth: 1, type: OPERATOR, value: '}', groupId: 'fxg1' },
52
- { index: 4, depth: 0, type: OPERATOR, value: '}', error: true }
53
- ]);
54
-
55
- // group ranges if they are equivalent
56
- t.isMetaTokens("=B11,B11:B12,'Sheet11'!B11,SHEET1!$B11,sheet1!$b$11,A1:B11,[foo]Sheet1!B11,'[foo]Sheet1'!B11", [
57
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
58
- { index: 1, depth: 0, type: REF_RANGE, value: 'B11', groupId: 'fxg1' },
59
- { index: 2, depth: 0, type: OPERATOR, value: ',' },
60
- { index: 3, depth: 0, type: REF_RANGE, value: 'B11:B12', groupId: 'fxg2' },
61
- { index: 4, depth: 0, type: OPERATOR, value: ',' },
62
- { index: 5, depth: 0, type: REF_RANGE, value: "'Sheet11'!B11", groupId: 'fxg3' },
63
- { index: 6, depth: 0, type: OPERATOR, value: ',' },
64
- { index: 7, depth: 0, type: REF_RANGE, value: 'SHEET1!$B11', groupId: 'fxg1' },
65
- { index: 8, depth: 0, type: OPERATOR, value: ',' },
66
- { index: 9, depth: 0, type: REF_RANGE, value: 'sheet1!$b$11', groupId: 'fxg1' },
67
- { index: 10, depth: 0, type: OPERATOR, value: ',' },
68
- { index: 11, depth: 0, type: REF_RANGE, value: 'A1:B11', groupId: 'fxg4' },
69
- { index: 12, depth: 0, type: OPERATOR, value: ',' },
70
- { index: 13, depth: 0, type: REF_RANGE, value: '[foo]Sheet1!B11', groupId: 'fxg1' },
71
- { index: 14, depth: 0, type: OPERATOR, value: ',' },
72
- { index: 15, depth: 0, type: REF_RANGE, value: "'[foo]Sheet1'!B11", groupId: 'fxg1' }
73
- ], { sheetName: 'Sheet1', workbookName: 'foo' });
74
-
75
- t.isMetaTokens('=A:A,1:1,Sheet1!A:A:1:1,[foo]Sheet1!1:1', [
76
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
77
- { index: 1, depth: 0, type: REF_BEAM, value: 'A:A', groupId: 'fxg1' },
78
- { index: 2, depth: 0, type: OPERATOR, value: ',' },
79
- { index: 3, depth: 0, type: REF_BEAM, value: '1:1', groupId: 'fxg2' },
80
- { index: 4, depth: 0, type: OPERATOR, value: ',' },
81
- { index: 5, depth: 0, type: REF_BEAM, value: 'Sheet1!A:A', groupId: 'fxg1' },
82
- { index: 6, depth: 0, type: OPERATOR, value: ':' },
83
- { index: 7, depth: 0, type: REF_BEAM, value: '1:1', groupId: 'fxg2' },
84
- { index: 8, depth: 0, type: OPERATOR, value: ',' },
85
- { index: 9, depth: 0, type: REF_BEAM, value: '[foo]Sheet1!1:1', groupId: 'fxg2' }
86
- ], { sheetName: 'Sheet1', workbookName: 'foo' });
87
-
88
- t.isMetaTokens('=SUM((1, 2), {3, 4})', [
89
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
90
- { index: 1, depth: 0, type: FUNCTION, value: 'SUM' },
91
- { index: 2, depth: 1, type: OPERATOR, value: '(', groupId: 'fxg3' },
92
- { index: 3, depth: 2, type: OPERATOR, value: '(', groupId: 'fxg1' },
93
- { index: 4, depth: 2, type: NUMBER, value: '1' },
94
- { index: 5, depth: 2, type: OPERATOR, value: ',' },
95
- { index: 6, depth: 2, type: WHITESPACE, value: ' ' },
96
- { index: 7, depth: 2, type: NUMBER, value: '2' },
97
- { index: 8, depth: 2, type: OPERATOR, value: ')', groupId: 'fxg1' },
98
- { index: 9, depth: 1, type: OPERATOR, value: ',' },
99
- { index: 10, depth: 1, type: WHITESPACE, value: ' ' },
100
- { index: 11, depth: 2, type: OPERATOR, value: '{', groupId: 'fxg2' },
101
- { index: 12, depth: 2, type: NUMBER, value: '3' },
102
- { index: 13, depth: 2, type: OPERATOR, value: ',' },
103
- { index: 14, depth: 2, type: WHITESPACE, value: ' ' },
104
- { index: 15, depth: 2, type: NUMBER, value: '4' },
105
- { index: 16, depth: 2, type: OPERATOR, value: '}', groupId: 'fxg2' },
106
- { index: 17, depth: 1, type: OPERATOR, value: ')', groupId: 'fxg3' }
107
- ], { sheetName: 'Sheet1', workbookName: 'foo' });
108
-
109
- t.isMetaTokens('=table[#all]+table[foobar]+table[[#All]]', [
110
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
111
- { index: 1, depth: 0, type: REF_STRUCT, value: 'table[#all]', groupId: 'fxg1' },
112
- { index: 2, depth: 0, type: OPERATOR, value: '+' },
113
- { index: 3, depth: 0, type: REF_STRUCT, value: 'table[foobar]', groupId: 'fxg2' },
114
- { index: 4, depth: 0, type: OPERATOR, value: '+' },
115
- { index: 5, depth: 0, type: REF_STRUCT, value: 'table[[#All]]', groupId: 'fxg1' }
116
- ], { sheetName: 'Sheet1', workbookName: 'foo' });
117
-
118
- t.isMetaTokens('=[foo]!A1+[foo]Sheet1!A1+Sheet1!A1+A1', [
119
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
120
- { index: 1, depth: 0, type: REF_RANGE, value: '[foo]!A1', groupId: 'fxg1' },
121
- { index: 2, depth: 0, type: OPERATOR, value: '+' },
122
- { index: 3, depth: 0, type: REF_RANGE, value: '[foo]Sheet1!A1', groupId: 'fxg1' },
123
- { index: 4, depth: 0, type: OPERATOR, value: '+' },
124
- { index: 5, depth: 0, type: REF_RANGE, value: 'Sheet1!A1', groupId: 'fxg1' },
125
- { index: 6, depth: 0, type: OPERATOR, value: '+' },
126
- { index: 7, depth: 0, type: REF_RANGE, value: 'A1', groupId: 'fxg1' }
127
- ], { sheetName: 'Sheet1', workbookName: 'foo' }, { xlsx: true });
128
-
129
- t.isMetaTokens('=[foo]!table[#data]+[foo]Sheet1!table[#data]+Sheet1!table[#data]+table[#data]', [
130
- { index: 0, depth: 0, type: FX_PREFIX, value: '=' },
131
- { index: 1, depth: 0, type: REF_STRUCT, value: '[foo]!table[#data]', groupId: 'fxg1' },
132
- { index: 2, depth: 0, type: OPERATOR, value: '+' },
133
- { index: 3, depth: 0, type: REF_STRUCT, value: '[foo]Sheet1!table[#data]', groupId: 'fxg1' },
134
- { index: 4, depth: 0, type: OPERATOR, value: '+' },
135
- { index: 5, depth: 0, type: REF_STRUCT, value: 'Sheet1!table[#data]', groupId: 'fxg1' },
136
- { index: 6, depth: 0, type: OPERATOR, value: '+' },
137
- { index: 7, depth: 0, type: REF_STRUCT, value: 'table[#data]', groupId: 'fxg1' }
138
- ], { sheetName: 'Sheet1', workbookName: 'foo' }, { xlsx: true });
139
-
140
- // trimmin should not affect range equivalency
141
- t.isMetaTokens('=A1:B2*A1.:B2*A1:.B2*A1.:.B2', [
142
- { type: FX_PREFIX, value: '=', index: 0, depth: 0 },
143
- { type: REF_RANGE, value: 'A1:B2', index: 1, depth: 0, groupId: 'fxg1' },
144
- { type: OPERATOR, value: '*', index: 2, depth: 0 },
145
- { type: REF_RANGE, value: 'A1.:B2', index: 3, depth: 0, groupId: 'fxg1' },
146
- { type: OPERATOR, value: '*', index: 4, depth: 0 },
147
- { type: REF_RANGE, value: 'A1:.B2', index: 5, depth: 0, groupId: 'fxg1' },
148
- { type: OPERATOR, value: '*', index: 6, depth: 0 },
149
- { type: REF_RANGE, value: 'A1.:.B2', index: 7, depth: 0, groupId: 'fxg1' }
150
- ], { sheetName: 'Sheet1', workbookName: 'foo' }, { xlsx: true });
151
-
152
- t.end();
153
- });