@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/rc.spec.js DELETED
@@ -1,403 +0,0 @@
1
- /* eslint-disable object-property-newline, object-curly-newline */
2
- import { test, Test } from 'tape';
3
- import { MAX_COLS, MAX_ROWS } from './constants.js';
4
- import { parseR1C1Ref, stringifyR1C1Ref, toR1C1 } from './rc.js';
5
-
6
- Test.prototype.isRCEqual = function isTokens (expr, expect, opts) {
7
- if (expect) {
8
- expect = (opts?.xlsx)
9
- ? { workbookName: '', sheetName: '', ...expect }
10
- : { context: [], ...expect };
11
- if (expect.range && typeof expect.range === 'object') {
12
- // mix in some defaults so we don't have to write things out in full
13
- expect.range = {
14
- r0: null, c0: null, r1: null, c1: null,
15
- $r0: false, $c0: false, $r1: false, $c1: false,
16
- ...expect.range
17
- };
18
- }
19
- }
20
- this.deepEqual(parseR1C1Ref(expr, opts), expect, expr);
21
- };
22
-
23
- Test.prototype.isR1C1Rendered = function isTokens (range, expect, d) {
24
- this.is(toR1C1(range, d), expect, expect);
25
- };
26
-
27
- test('parse single R1C1 references', t => {
28
- // current row
29
- t.isRCEqual('R', { range: { r0: 0, r1: 0 } });
30
- t.isRCEqual('R[0]', { range: { r0: 0, r1: 0 } });
31
- // row N (equivalent to 1:1)
32
- t.isRCEqual('R0', { name: 'R0' });
33
- t.isRCEqual('R1', { range: { r0: 0, r1: 0, $r0: true, $r1: true } });
34
- t.isRCEqual('R10', { range: { r0: 9, r1: 9, $r0: true, $r1: true } });
35
- // row following current
36
- t.isRCEqual('R[1]', { range: { r0: 1, r1: 1 } });
37
- // row preceding current
38
- t.isRCEqual('R[-1]', { range: { r0: -1, r1: -1 } });
39
-
40
- // current column
41
- t.isRCEqual('C', { range: { c0: 0, c1: 0 } });
42
- t.isRCEqual('C[0]', { range: { c0: 0, c1: 0 } });
43
- // column N (equivalent to A:A)
44
- t.isRCEqual('C0', { name: 'C0' });
45
- t.isRCEqual('C1', { range: { c0: 0, c1: 0, $c0: true, $c1: true } });
46
- t.isRCEqual('C10', { range: { c0: 9, c1: 9, $c0: true, $c1: true } });
47
- // column following current
48
- t.isRCEqual('C[1]', { range: { c0: 1, c1: 1 } });
49
- // column preceding current
50
- t.isRCEqual('C[-1]', { range: { c0: -1, c1: -1 } });
51
- // current cell
52
- t.isRCEqual('RC', { range: { r0: 0, c0: 0, r1: 0, c1: 0 } });
53
- t.isRCEqual('R0C0', { name: 'R0C0' });
54
- // fixed cell
55
- t.isRCEqual('R1C1', { range: { r0: 0, c0: 0, r1: 0, c1: 0, $c0: true, $c1: true, $r0: true, $r1: true } });
56
- t.isRCEqual('R10C8', { range: { r0: 9, c0: 7, r1: 9, c1: 7, $c0: true, $c1: true, $r0: true, $r1: true } });
57
- t.isRCEqual('R-10C-8', null);
58
-
59
- // relative parts
60
- t.isRCEqual('R[2]C', { range: { r0: 2, c0: 0, r1: 2, c1: 0 } });
61
- t.isRCEqual('R[-2]C', { range: { r0: -2, c0: 0, r1: -2, c1: 0 } });
62
- t.isRCEqual('RC[3]', { range: { r0: 0, c0: 3, r1: 0, c1: 3 } });
63
- t.isRCEqual('RC[-3]', { range: { r0: 0, c0: -3, r1: 0, c1: -3 } });
64
- t.isRCEqual('R[2]C[4]', { range: { r0: 2, c0: 4, r1: 2, c1: 4 } });
65
- t.isRCEqual('R[-2]C[-4]', { range: { r0: -2, c0: -4, r1: -2, c1: -4 } });
66
- // mixed fixed and relative
67
- t.isRCEqual('R[9]C9', { range: { r0: 9, c0: 8, r1: 9, c1: 8, $c0: true, $c1: true } });
68
- t.isRCEqual('R9C[9]', { range: { r0: 8, c0: 9, r1: 8, c1: 9, $r0: true, $r1: true } });
69
-
70
- // out of bounds
71
- t.isRCEqual('R1048577', { name: 'R1048577' });
72
- t.isRCEqual('R[1048576]', null);
73
- t.isRCEqual('C16385', { name: 'C16385' });
74
- t.isRCEqual('C[16384]', null);
75
-
76
- t.end();
77
- });
78
-
79
- test('R1C1 partial ranges', t => {
80
- const opts = { allowTernary: true };
81
- // partials are not allowed by defult
82
- t.isRCEqual('R[-5]C[-2]:C[-2]', null);
83
- t.isRCEqual('R1:R1C1', null);
84
- // beam type partials A1:A @ C6
85
- t.isRCEqual('R[-5]C[-2]:C[-2]', { range: { r0: -5, c0: -2, c1: -2 } }, opts);
86
- t.isRCEqual('C[-2]:R[-5]C[-2]', { range: { r0: -5, c0: -2, c1: -2 } }, opts);
87
- t.isRCEqual('R[-5]C[-3]:R[-5]', { range: { r0: -5, c0: -3, r1: -5 } }, opts);
88
- t.isRCEqual('R[-5]:R[-5]C[-3]', { range: { r0: -5, c0: -3, r1: -5 } }, opts);
89
- t.isRCEqual('R[-6]C1:C1', { range: { r0: -6, c0: 0, c1: 0, $c0: true, $c1: true } }, opts);
90
- t.isRCEqual('C1:R[-6]C1', { range: { r0: -6, c0: 0, c1: 0, $c0: true, $c1: true } }, opts);
91
- t.isRCEqual('R[-6]C1:R[-6]', { range: { r0: -6, c0: 0, r1: -6, $c0: true, $c1: true } }, opts);
92
- t.isRCEqual('R[-6]:R[-6]C1', { range: { r0: -6, c0: 0, r1: -6, $c0: true, $c1: true } }, opts);
93
- t.isRCEqual('R1C[-2]:C[-2]', { range: { r0: 0, c0: -2, c1: -2, $r0: true, $c0: false, $r1: true, $c1: false } }, opts);
94
- t.isRCEqual('C[-2]:R1C[-2]', { range: { r0: 0, c0: -2, c1: -2, $r0: true, $c0: false, $r1: true, $c1: false } }, opts);
95
- t.isRCEqual('R1C[-3]:R1', { range: { r0: 0, c0: -3, r1: 0, $r0: true, $c0: false, $r1: true, $c1: false } }, opts);
96
- t.isRCEqual('R1:R1C[-3]', { range: { r0: 0, c0: -3, r1: 0, $r0: true, $c0: false, $r1: true, $c1: false } }, opts);
97
- t.isRCEqual('R1C1:C1', { range: { r0: 0, c0: 0, c1: 0, $r0: true, $c0: true, $r1: true, $c1: true } }, opts);
98
- t.isRCEqual('C1:R1C1', { range: { r0: 0, c0: 0, c1: 0, $r0: true, $c0: true, $r1: true, $c1: true } }, opts);
99
- t.isRCEqual('R1C1:R1', { range: { r0: 0, c0: 0, r1: 0, $r0: true, $c0: true, $r1: true, $c1: true } }, opts);
100
- t.isRCEqual('R1:R1C1', { range: { r0: 0, c0: 0, r1: 0, $r0: true, $c0: true, $r1: true, $c1: true } }, opts);
101
- // range type partials P1:10 @ F6
102
- t.isRCEqual('R[-5]C[10]:R[4]', { range: { r0: -5, c0: 10, r1: 4 } }, opts);
103
- t.isRCEqual('R[4]:R[-5]C[10]', { range: { r0: -5, c0: 10, r1: 4 } }, opts);
104
- t.isRCEqual('R[-6]C16:R[3]', { range: { r0: -6, c0: 15, r1: 3, $c0: true, $c1: true } }, opts);
105
- t.isRCEqual('R[3]:R[-6]C16', { range: { r0: -6, c0: 15, r1: 3, $c0: true, $c1: true } }, opts);
106
- t.isRCEqual('R1C[10]:R10', { range: { r0: 0, c0: 10, r1: 9, $r0: true, $c0: false, $r1: true, $c1: false } }, opts);
107
- t.isRCEqual('R10:R1C[10]', { range: { r0: 0, c0: 10, r1: 9, $r0: true, $c0: false, $r1: true, $c1: false } }, opts);
108
- t.isRCEqual('R1C16:R10', { range: { r0: 0, c0: 15, r1: 9, $r0: true, $c0: true, $r1: true, $c1: true } }, opts);
109
- t.isRCEqual('R10:R1C16', { range: { r0: 0, c0: 15, r1: 9, $r0: true, $c0: true, $r1: true, $c1: true } }, opts);
110
- t.end();
111
- });
112
-
113
- test('parse joined R1C1 references', t => {
114
- // all "mirrored" refs are equivalent of the non mirrored counterparts...
115
- t.isRCEqual('R:R', { range: { r0: 0, r1: 0 } });
116
- t.isRCEqual('R[0]:R[0]', { range: { r0: 0, r1: 0 } });
117
- t.isRCEqual('R1:R1', { range: { r0: 0, r1: 0, $r0: true, $r1: true } });
118
- t.isRCEqual('R10:R10', { range: { r0: 9, r1: 9, $r0: true, $r1: true } });
119
- t.isRCEqual('R[1]:R[1]', { range: { r0: 1, r1: 1 } });
120
- t.isRCEqual('R[-1]:R[-1]', { range: { r0: -1, r1: -1 } });
121
-
122
- t.isRCEqual('C:C', { range: { c0: 0, c1: 0 } });
123
- t.isRCEqual('C[0]:C[0]', { range: { c0: 0, c1: 0 } });
124
- t.isRCEqual('C1:C1', { range: { c0: 0, c1: 0, $c0: true, $c1: true } });
125
- t.isRCEqual('C10:C10', { range: { c0: 9, c1: 9, $c0: true, $c1: true } });
126
- t.isRCEqual('C[1]:C[1]', { range: { c0: 1, c1: 1 } });
127
- t.isRCEqual('C[-1]:C[-1]', { range: { c0: -1, c1: -1 } });
128
-
129
- t.isRCEqual('R0:R0', null);
130
- t.isRCEqual('C0:C0', null);
131
- t.isRCEqual('R[9]C9:R[9]C9', { range: { r0: 9, c0: 8, r1: 9, c1: 8, $c0: true, $c1: true } });
132
- t.isRCEqual('R9C[9]:R9C[9]', { range: { r0: 8, c0: 9, r1: 8, c1: 9, $r0: true, $r1: true } });
133
- t.isRCEqual('R[1]C[1]:R1C1', { range: { r0: 1, c0: 1, r1: 0, c1: 0, $c1: true, $r1: true } });
134
- t.isRCEqual('R[1]C[1]:R1C1', { range: { r0: 1, c0: 1, r1: 0, c1: 0, $c1: true, $r1: true } });
135
- t.isRCEqual('R1C1:R2C2', { range: { r0: 0, c0: 0, r1: 1, c1: 1, $c0: true, $c1: true, $r0: true, $r1: true } });
136
- t.isRCEqual('R2C2:R1C1', { range: { r0: 0, c0: 0, r1: 1, c1: 1, $c0: true, $c1: true, $r0: true, $r1: true } });
137
- // single thing
138
- t.isRCEqual('C1:C3', { range: { c0: 0, c1: 2, $c0: true, $c1: true } });
139
- t.isRCEqual('R[1]:R3', { range: { r0: 1, r1: 2, $r1: true } });
140
- t.isRCEqual('R[1]C1:R1C[-1]', { range: { r0: 1, c0: 0, r1: 0, c1: -1, $c0: true, $r1: true, $c1: false } });
141
- // many things
142
- t.isRCEqual('R:C', null);
143
- t.isRCEqual('R:RC', null);
144
- t.isRCEqual('RC:R', null);
145
- t.isRCEqual('RC:C', null);
146
- t.isRCEqual('C:R', null);
147
- t.isRCEqual('C:RC', null);
148
- t.end();
149
- });
150
-
151
- test('parse R1C1 ranges in XLSX mode', t => {
152
- const opts = { xlsx: true };
153
- const rcRange = { r0: 0, c0: 0, r1: 0, c1: 0 };
154
- t.isRCEqual('[1]!RC', {
155
- workbookName: '1',
156
- sheetName: '',
157
- range: rcRange
158
- }, opts);
159
-
160
- t.isRCEqual('[Workbook.xlsx]!RC', {
161
- workbookName: 'Workbook.xlsx',
162
- sheetName: '',
163
- range: rcRange
164
- }, opts);
165
-
166
- t.isRCEqual('[1]Sheet1!RC', {
167
- workbookName: '1',
168
- sheetName: 'Sheet1',
169
- range: rcRange
170
- }, opts);
171
-
172
- t.isRCEqual('[Workbook.xlsx]Sheet1!RC', {
173
- workbookName: 'Workbook.xlsx',
174
- sheetName: 'Sheet1',
175
- range: rcRange
176
- }, opts);
177
-
178
- t.isRCEqual('[4]!name', {
179
- workbookName: '4',
180
- sheetName: '',
181
- name: 'name'
182
- }, opts);
183
-
184
- t.isRCEqual('[Workbook.xlsx]!name', {
185
- workbookName: 'Workbook.xlsx',
186
- sheetName: '',
187
- name: 'name'
188
- }, opts);
189
-
190
- t.isRCEqual('[16]Sheet1!name', {
191
- workbookName: '16',
192
- sheetName: 'Sheet1',
193
- name: 'name'
194
- }, opts);
195
-
196
- t.isRCEqual('[Workbook.xlsx]Sheet1!name', {
197
- workbookName: 'Workbook.xlsx',
198
- sheetName: 'Sheet1',
199
- name: 'name'
200
- }, opts);
201
-
202
- t.isRCEqual("='[1]'!RC", {
203
- workbookName: '1',
204
- sheetName: '',
205
- range: rcRange
206
- }, opts);
207
-
208
- t.isRCEqual("='[Workbook.xlsx]'!RC", {
209
- workbookName: 'Workbook.xlsx',
210
- sheetName: '',
211
- range: rcRange
212
- }, opts);
213
-
214
- t.isRCEqual("'[1]Sheet1'!RC", {
215
- workbookName: '1',
216
- sheetName: 'Sheet1',
217
- range: rcRange
218
- }, opts);
219
-
220
- t.isRCEqual("'[Workbook.xlsx]Sheet1'!RC", {
221
- workbookName: 'Workbook.xlsx',
222
- sheetName: 'Sheet1',
223
- range: rcRange
224
- }, opts);
225
-
226
- t.isRCEqual("'[4]'!name", {
227
- workbookName: '4',
228
- sheetName: '',
229
- name: 'name'
230
- }, opts);
231
-
232
- t.isRCEqual("'[Workbook.xlsx]'!name", {
233
- workbookName: 'Workbook.xlsx',
234
- sheetName: '',
235
- name: 'name'
236
- }, opts);
237
-
238
- t.isRCEqual("'[16]Sheet1'!name", {
239
- workbookName: '16',
240
- sheetName: 'Sheet1',
241
- name: 'name'
242
- }, opts);
243
-
244
- t.isRCEqual("'[Workbook.xlsx]Sheet1'!name", {
245
- workbookName: 'Workbook.xlsx',
246
- sheetName: 'Sheet1',
247
- name: 'name'
248
- }, opts);
249
-
250
- t.end();
251
- });
252
-
253
- test('R1C1 trimmed ranges', t => {
254
- const locks = { $r0: true, $r1: true, $c0: true, $c1: true };
255
- const opts = [ {}, { xlsx: true } ];
256
- for (const opt of opts) {
257
- t.isRCEqual('R[1]C[1]:R[2]C[2]', { range: { r0: 1, r1: 2, c0: 1, c1: 2 } }, opt);
258
- t.isRCEqual('R[1]C[1].:R[2]C[2]', { range: { r0: 1, r1: 2, c0: 1, c1: 2, trim: 'head' } }, opt);
259
- t.isRCEqual('R[1]C[1]:.R[2]C[2]', { range: { r0: 1, r1: 2, c0: 1, c1: 2, trim: 'tail' } }, opt);
260
- t.isRCEqual('R[1]C[1].:.R[2]C[2]', { range: { r0: 1, r1: 2, c0: 1, c1: 2, trim: 'both' } }, opt);
261
-
262
- t.isRCEqual('R2C2:R3C3', { range: { r0: 1, r1: 2, c0: 1, c1: 2, ...locks } }, opt);
263
- t.isRCEqual('R2C2.:R3C3', { range: { r0: 1, r1: 2, c0: 1, c1: 2, trim: 'head', ...locks } }, opt);
264
- t.isRCEqual('R2C2:.R3C3', { range: { r0: 1, r1: 2, c0: 1, c1: 2, trim: 'tail', ...locks } }, opt);
265
- t.isRCEqual('R2C2.:.R3C3', { range: { r0: 1, r1: 2, c0: 1, c1: 2, trim: 'both', ...locks } }, opt);
266
-
267
- t.isRCEqual('C[1]:C[2]', { range: { c0: 1, c1: 2 } }, opt);
268
- t.isRCEqual('C[1].:C[2]', { range: { c0: 1, c1: 2, trim: 'head' } }, opt);
269
- t.isRCEqual('C[1]:.C[2]', { range: { c0: 1, c1: 2, trim: 'tail' } }, opt);
270
- t.isRCEqual('C[1].:.C[2]', { range: { c0: 1, c1: 2, trim: 'both' } }, opt);
271
-
272
- t.isRCEqual('R[10]:R[10]', { range: { r0: 10, r1: 10 } }, opt);
273
- t.isRCEqual('R[10].:R[10]', { range: { r0: 10, r1: 10, trim: 'head' } }, opt);
274
- t.isRCEqual('R[10]:.R[10]', { range: { r0: 10, r1: 10, trim: 'tail' } }, opt);
275
- t.isRCEqual('R[10].:.R[10]', { range: { r0: 10, r1: 10, trim: 'both' } }, opt);
276
-
277
- t.isRCEqual('R[2]C[2]:R[4]', null, { ...opt });
278
- t.isRCEqual('R[2]C[2]:C[4]', null, { ...opt });
279
- t.isRCEqual('R[2]C[2].:.R[4]', null, { ...opt });
280
- t.isRCEqual('R[2]C[2].:.C[4]', null, { ...opt });
281
-
282
- t.isRCEqual('R[2]C[2]:R[4]', { range: { r0: 2, r1: 4, c0: 2 } }, { allowTernary: true, ...opt });
283
- t.isRCEqual('R[2]C[2]:C[4]', { range: { r0: 2, c0: 2, c1: 4 } }, { allowTernary: true, ...opt });
284
- t.isRCEqual('R[2]C[2].:.R[4]', { range: { r0: 2, r1: 4, c0: 2, trim: 'both' } }, { allowTernary: true, ...opt });
285
- t.isRCEqual('R[2]C[2].:.C[4]', { range: { r0: 2, c0: 2, c1: 4, trim: 'both' } }, { allowTernary: true, ...opt });
286
- }
287
- t.end();
288
- });
289
-
290
- test('R1C1 serialization', t => {
291
- // ray
292
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: 0, c1: MAX_COLS }, 'R');
293
- t.isR1C1Rendered({ r0: 0, r1: 0 }, 'R');
294
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: 0, c1: MAX_COLS, $r0: true, $r1: true }, 'R1');
295
- t.isR1C1Rendered({ r0: 0, r1: 0, $r0: true, $r1: true }, 'R1');
296
- t.isR1C1Rendered({ r0: 1, c0: 0, r1: 1, c1: MAX_COLS }, 'R[1]');
297
- t.isR1C1Rendered({ r0: 1, r1: 1 }, 'R[1]');
298
- // ray
299
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: MAX_ROWS, c1: 0 }, 'C');
300
- t.isR1C1Rendered({ c0: 0, c1: 0 }, 'C');
301
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: MAX_ROWS, c1: 0, $c0: true, $c1: true }, 'C1');
302
- t.isR1C1Rendered({ c0: 0, c1: 0, $c0: true, $c1: true }, 'C1');
303
- t.isR1C1Rendered({ r0: 0, c0: 1, r1: MAX_ROWS, c1: 1 }, 'C[1]');
304
- t.isR1C1Rendered({ c0: 1, c1: 1 }, 'C[1]');
305
- // rect
306
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: 0, c1: 0 }, 'RC');
307
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: 0, c1: 0, $c0: true, $c1: true, $r0: true, $r1: true }, 'R1C1');
308
- t.isR1C1Rendered({ r0: 9, c0: 7, r1: 9, c1: 7, $c0: true, $c1: true, $r0: true, $r1: true }, 'R10C8');
309
- t.isR1C1Rendered({ r0: 2, c0: 0, r1: 2, c1: 0 }, 'R[2]C');
310
- t.isR1C1Rendered({ r0: -2, c0: 0, r1: -2, c1: 0 }, 'R[-2]C');
311
- t.isR1C1Rendered({ r0: 0, c0: 3, r1: 0, c1: 3 }, 'RC[3]');
312
- t.isR1C1Rendered({ r0: 0, c0: -3, r1: 0, c1: -3 }, 'RC[-3]');
313
- t.isR1C1Rendered({ r0: 2, c0: 4, r1: 2, c1: 4 }, 'R[2]C[4]');
314
- t.isR1C1Rendered({ r0: -2, c0: -4, r1: -2, c1: -4 }, 'R[-2]C[-4]');
315
- t.isR1C1Rendered({ r0: 9, c0: 8, r1: 9, c1: 8, $c0: true, $c1: true }, 'R[9]C9');
316
- t.isR1C1Rendered({ r0: 8, c0: 9, r1: 8, c1: 9, $r0: true, $r1: true }, 'R9C[9]');
317
- t.isR1C1Rendered({ r0: 1, c0: 1, r1: 0, c1: 0, $c1: true, $r1: true }, 'R[1]C[1]:R1C1');
318
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: 1, c1: 1, $c0: true, $c1: true, $r0: true, $r1: true }, 'R1C1:R2C2');
319
- t.isR1C1Rendered({ c0: 0, c1: 2, $c0: true, $c1: true }, 'C1:C3');
320
- t.isR1C1Rendered({ r0: 1, r1: 2, $r1: true }, 'R[1]:R3');
321
- t.isR1C1Rendered({ r0: 1, c0: 0, r1: 0, c1: -1, $c0: true, $r1: true }, 'R[1]C1:R1C[-1]');
322
- // partial
323
- t.isR1C1Rendered({ r0: -5, c0: -2, c1: -2 }, 'R[-5]C[-2]:C[-2]');
324
- t.isR1C1Rendered({ r0: -5, c0: -3, r1: -5 }, 'R[-5]C[-3]:R[-5]');
325
- t.isR1C1Rendered({ r0: -6, c0: 0, c1: 0, $c0: true, $c1: true }, 'R[-6]C1:C1');
326
- t.isR1C1Rendered({ r0: -6, c0: 0, r1: -6, $c0: true, $c1: true }, 'R[-6]C1:R[-6]');
327
- t.isR1C1Rendered({ r0: 0, c0: -2, c1: -2, $r0: true, $r1: true }, 'R1C[-2]:C[-2]');
328
- t.isR1C1Rendered({ r0: 0, c0: -3, r1: 0, $r0: true, $r1: true }, 'R1C[-3]:R1');
329
- t.isR1C1Rendered({ r0: 0, c0: 0, c1: 0, $r0: true, $c0: true, $r1: true, $c1: true }, 'R1C1:C1');
330
- t.isR1C1Rendered({ r0: 0, c0: 0, r1: 0, $r0: true, $c0: true, $r1: true, $c1: true }, 'R1C1:R1');
331
- t.isR1C1Rendered({ r0: -5, c0: 10, r1: 4 }, 'R[-5]C[10]:R[4]');
332
- t.isR1C1Rendered({ r0: -6, c0: 15, r1: 3, $c0: true, $c1: true }, 'R[-6]C16:R[3]');
333
- t.isR1C1Rendered({ r0: 0, c0: 10, r1: 9, $r0: true, $r1: true }, 'R1C[10]:R10');
334
- t.isR1C1Rendered({ r0: 0, c0: 15, r1: 9, $r0: true, $c0: true, $r1: true, $c1: true }, 'R1C16:R10');
335
- // allow skipping right/bottom for cells
336
- t.isR1C1Rendered({ r0: -5, c0: -2 }, 'R[-5]C[-2]');
337
- // clamp the range at min/max dimensions
338
- const abs = { $r0: true, $c0: true, $r1: true, $c1: true };
339
- t.isR1C1Rendered({ r0: 1, c0: -20000, r1: 1, c1: 20000, ...abs }, 'R2');
340
- t.isR1C1Rendered({ r0: -15e5, c0: 1, r1: 15e5, c1: 1, ...abs }, 'C2');
341
- t.isR1C1Rendered({ r0: -5, c0: -2, r1: -8, c1: -7, ...abs }, 'R1C1');
342
- t.isR1C1Rendered({ r0: 0, c0: -20000, r1: 0, c1: 20000 }, 'RC[-16383]:RC[16383]');
343
- t.isR1C1Rendered({ r0: -15e5, c0: 0, r1: 15e5, c1: 0 }, 'R[-1048575]C:R[1048575]C');
344
- t.isR1C1Rendered({ r0: 0.5, c0: 0.5, r1: 0.5, c1: 0.5, ...abs }, 'R1C1');
345
- t.isR1C1Rendered({ r0: 0.5, c0: 0.5, r1: 0.5, c1: 0.5 }, 'RC');
346
- // trimming
347
- t.isR1C1Rendered({ r0: 1, c0: 1, r1: 2, c1: 2 }, 'R[1]C[1]:R[2]C[2]');
348
- t.isR1C1Rendered({ r0: 1, c0: 1, r1: 2, c1: 2, trim: 'head' }, 'R[1]C[1].:R[2]C[2]');
349
- t.isR1C1Rendered({ r0: 1, c0: 1, r1: 2, c1: 2, trim: 'tail' }, 'R[1]C[1]:.R[2]C[2]');
350
- t.isR1C1Rendered({ r0: 1, c0: 1, r1: 2, c1: 2, trim: 'both' }, 'R[1]C[1].:.R[2]C[2]');
351
- t.isR1C1Rendered({ r0: 1, c0: 1, r1: 1, c1: 1, trim: 'both' }, 'R[1]C[1]');
352
- t.isR1C1Rendered({ r0: 1, r1: 1 }, 'R[1]');
353
- t.isR1C1Rendered({ r0: 1, r1: 1, trim: 'head' }, 'R[1].:R[1]');
354
- t.isR1C1Rendered({ r0: 1, r1: 1, trim: 'both' }, 'R[1].:.R[1]');
355
- t.isR1C1Rendered({ c0: 1, c1: 1 }, 'C[1]');
356
- t.isR1C1Rendered({ c0: 1, c1: 1, trim: 'tail' }, 'C[1]:.C[1]');
357
- t.isR1C1Rendered({ c0: 1, c1: 1, trim: 'both' }, 'C[1].:.C[1]');
358
- t.isR1C1Rendered({ r0: -5, c0: -2, c1: -2, trim: 'both' }, 'R[-5]C[-2].:.C[-2]');
359
- t.end();
360
- });
361
-
362
- test('stringifyR1C1Ref', t => {
363
- const rangeA1 = { r0: 2, c0: 4, r1: 2, c1: 4 };
364
- const testRef = (ref, expect) => t.is(stringifyR1C1Ref(ref), expect, expect);
365
- testRef({ range: rangeA1 }, 'R[2]C[4]');
366
- testRef({ context: [ 'Sheet1' ], range: rangeA1 }, 'Sheet1!R[2]C[4]');
367
- testRef({ context: [ 'Sheet 1' ], range: rangeA1 }, "'Sheet 1'!R[2]C[4]");
368
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], range: rangeA1 }, '[MyFile.xlsx]Sheet1!R[2]C[4]');
369
- testRef({ context: [ 'My File.xlsx', 'Sheet1' ], range: rangeA1 }, "'[My File.xlsx]Sheet1'!R[2]C[4]");
370
- testRef({ context: [ 'MyFile.xlsx' ], range: rangeA1 }, 'MyFile.xlsx!R[2]C[4]');
371
- testRef({ context: [ 'My File.xlsx' ], range: rangeA1 }, "'My File.xlsx'!R[2]C[4]");
372
- testRef({ name: 'foo' }, 'foo');
373
- testRef({ context: [ 'Sheet1' ], name: 'foo' }, 'Sheet1!foo');
374
- testRef({ context: [ 'Sheet 1' ], name: 'foo' }, "'Sheet 1'!foo");
375
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], name: 'foo' }, '[MyFile.xlsx]Sheet1!foo');
376
- testRef({ context: [ 'My File.xlsx', 'Sheet1' ], name: 'foo' }, "'[My File.xlsx]Sheet1'!foo");
377
- testRef({ context: [ 'MyFile.xlsx' ], name: 'foo' }, 'MyFile.xlsx!foo');
378
- testRef({ context: [ 'My File.xlsx' ], name: 'foo' }, "'My File.xlsx'!foo");
379
- t.end();
380
- });
381
-
382
- test('stringifyR1C1Ref in XLSX mode', t => {
383
- const rangeA1 = { r0: 2, c0: 4, r1: 2, c1: 4 };
384
- const testRef = (ref, expect) => t.is(stringifyR1C1Ref(ref, { xlsx: true }), expect, expect);
385
- testRef({ range: rangeA1 }, 'R[2]C[4]');
386
- testRef({ sheetName: 'Sheet1', range: rangeA1 }, 'Sheet1!R[2]C[4]');
387
- testRef({ sheetName: 'Sheet 1', range: rangeA1 }, "'Sheet 1'!R[2]C[4]");
388
- testRef({ workbookName: 'MyFile.xlsx', sheetName: 'Sheet1', range: rangeA1 }, '[MyFile.xlsx]Sheet1!R[2]C[4]');
389
- testRef({ workbookName: 'My File.xlsx', sheetName: 'Sheet1', range: rangeA1 }, "'[My File.xlsx]Sheet1'!R[2]C[4]");
390
- testRef({ workbookName: 'MyFile.xlsx', range: rangeA1 }, '[MyFile.xlsx]!R[2]C[4]');
391
- testRef({ workbookName: 'My File.xlsx', range: rangeA1 }, "'[My File.xlsx]'!R[2]C[4]");
392
- testRef({ name: 'foo' }, 'foo');
393
- testRef({ sheetName: 'Sheet1', name: 'foo' }, 'Sheet1!foo');
394
- testRef({ sheetName: 'Sheet 1', name: 'foo' }, "'Sheet 1'!foo");
395
- testRef({ workbookName: 'MyFile.xlsx', sheetName: 'Sheet1', name: 'foo' }, '[MyFile.xlsx]Sheet1!foo');
396
- testRef({ workbookName: 'My File.xlsx', sheetName: 'Sheet1', name: 'foo' }, "'[My File.xlsx]Sheet1'!foo");
397
- testRef({ workbookName: 'MyFile.xlsx', name: 'foo' }, '[MyFile.xlsx]!foo');
398
- testRef({ workbookName: 'My File.xlsx', name: 'foo' }, "'[My File.xlsx]'!foo");
399
- // ignore .context
400
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], range: rangeA1 }, 'R[2]C[4]');
401
- testRef({ context: [ 'MyFile.xlsx', 'Sheet1' ], name: 'foo' }, 'foo');
402
- t.end();
403
- });
@@ -1,80 +0,0 @@
1
- import { stringifyPrefix, stringifyPrefixAlt } from './stringifyPrefix.js';
2
-
3
- function quoteColname (str) {
4
- return str.replace(/([[\]#'@])/g, '\'$1');
5
- }
6
-
7
- function needsBraces (str) {
8
- return !/^[a-zA-Z0-9\u00a1-\uffff]+$/.test(str);
9
- }
10
-
11
- function toSentenceCase (str) {
12
- return str[0].toUpperCase() + str.slice(1).toLowerCase();
13
- }
14
-
15
- /**
16
- * Get a string representation of a structured reference object.
17
- *
18
- * ```js
19
- * stringifyStructRef({
20
- * context: [ 'workbook.xlsx' ],
21
- * sections: [ 'data' ],
22
- * columns: [ 'my column', '@foo' ],
23
- * table: 'tableName',
24
- * });
25
- * // => 'workbook.xlsx!tableName[[#Data],[Column1]:[Column2]]'
26
- * ```
27
- *
28
- * @param {ReferenceStruct} refObject A structured reference object
29
- * @param {object} [options={}] Options
30
- * @param {boolean} [options.xlsx=false] Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md)
31
- * @param {boolean} [options.thisRow=false] Enforces using the `[#This Row]` instead of the `@` shorthand when serializing structured ranges.
32
- * @returns {string} The structured reference in string format
33
- */
34
- export function stringifyStructRef (refObject, options = {}) {
35
- const { xlsx, thisRow } = options;
36
- let s = xlsx
37
- ? stringifyPrefixAlt(refObject)
38
- : stringifyPrefix(refObject);
39
-
40
- if (refObject.table) {
41
- s += refObject.table;
42
- }
43
- const numColumns = refObject.columns?.length ?? 0;
44
- const numSections = refObject.sections?.length ?? 0;
45
- // single section
46
- if (numSections === 1 && !numColumns) {
47
- s += `[#${toSentenceCase(refObject.sections[0])}]`;
48
- }
49
- // single column
50
- else if (!numSections && numColumns === 1) {
51
- s += `[${quoteColname(refObject.columns[0])}]`;
52
- }
53
- else {
54
- s += '[';
55
- // single [#this row] sections get normalized to an @ by default
56
- const singleAt = !thisRow && numSections === 1 && refObject.sections[0].toLowerCase() === 'this row';
57
- if (singleAt) {
58
- s += '@';
59
- }
60
- else if (numSections) {
61
- s += refObject.sections
62
- .map(d => `[#${toSentenceCase(d)}]`)
63
- .join(',');
64
- if (numColumns) {
65
- s += ',';
66
- }
67
- }
68
- // a case of a single alphanumberic column with a [#this row] becomes [@col]
69
- if (singleAt && refObject.columns.length === 1 && !needsBraces(refObject.columns[0])) {
70
- s += quoteColname(refObject.columns[0]);
71
- }
72
- else if (numColumns) {
73
- s += refObject.columns.slice(0, 2)
74
- .map(d => (`[${quoteColname(d)}]`))
75
- .join(':');
76
- }
77
- s += ']';
78
- }
79
- return s;
80
- }
@@ -1,182 +0,0 @@
1
- /* eslint-disable object-property-newline, object-curly-newline */
2
- import { test } from 'tape';
3
- import { stringifyStructRef } from './stringifyStructRef.js';
4
-
5
- test('serialize structured references', t => {
6
- t.is(
7
- stringifyStructRef({
8
- columns: [ 'foo' ]
9
- }),
10
- '[foo]',
11
- '[foo]'
12
- );
13
-
14
- t.is(
15
- stringifyStructRef({
16
- columns: [ 'foo' ],
17
- table: 'tableName'
18
- }),
19
- 'tableName[foo]',
20
- 'tableName[foo]'
21
- );
22
-
23
- t.is(
24
- stringifyStructRef({
25
- columns: [ 'lorem ipsum' ],
26
- table: 'tableName'
27
- }),
28
- 'tableName[lorem ipsum]',
29
- 'tableName[lorem ipsum]'
30
- );
31
-
32
- t.is(
33
- stringifyStructRef({
34
- columns: [ 'foo', 'sævör' ],
35
- table: 'tableName'
36
- }),
37
- 'tableName[[foo]:[sævör]]',
38
- 'tableName[[foo]:[sævör]]'
39
- );
40
-
41
- t.is(
42
- stringifyStructRef({
43
- sections: [ 'data' ],
44
- table: 'tableName'
45
- }),
46
- 'tableName[#Data]',
47
- 'tableName[#Data]'
48
- );
49
-
50
- t.is(
51
- stringifyStructRef({
52
- columns: [ 'lorem ipsum', 'sævör' ],
53
- table: 'tableName'
54
- }),
55
- 'tableName[[lorem ipsum]:[sævör]]',
56
- 'tableName[[lorem ipsum]:[sævör]]'
57
- );
58
-
59
- t.is(
60
- stringifyStructRef({
61
- columns: [ 'my column', 'fo@o' ],
62
- sections: [ 'data' ],
63
- table: 'tableName',
64
- context: [ 'workbook.xlsx' ]
65
- }),
66
- 'workbook.xlsx!tableName[[#Data],[my column]:[fo\'@o]]',
67
- 'workbook.xlsx!tableName[[#Data],[my column]:[fo\'@o]]'
68
- );
69
-
70
- t.is(
71
- stringifyStructRef({
72
- columns: [ 'bar' ],
73
- sections: [ 'this row' ],
74
- table: 'foo'
75
- }),
76
- 'foo[@bar]',
77
- 'foo[@bar]'
78
- );
79
-
80
- t.is(
81
- stringifyStructRef({
82
- columns: [ 'bar', 'baz' ],
83
- sections: [ 'this row' ],
84
- table: 'foo'
85
- }),
86
- 'foo[@[bar]:[baz]]',
87
- 'foo[@[bar]:[baz]]'
88
- );
89
-
90
- t.is(
91
- stringifyStructRef({
92
- columns: [ 'lorem ipsum', 'baz' ],
93
- sections: [ 'this row' ],
94
- table: 'foo'
95
- }),
96
- 'foo[@[lorem ipsum]:[baz]]',
97
- 'foo[@[lorem ipsum]:[baz]]'
98
- );
99
-
100
- t.is(
101
- stringifyStructRef({
102
- sections: [ 'data', 'headers' ],
103
- table: 'table'
104
- }),
105
- 'table[[#Data],[#Headers]]',
106
- 'table[[#Data],[#Headers]]'
107
- );
108
-
109
- t.end();
110
- });
111
-
112
- test('structured references serialize in xlsx mode', t => {
113
- t.is(
114
- stringifyStructRef({
115
- context: [ 'Lorem', 'Ipsum' ],
116
- columns: [ 'foo' ]
117
- }, { xlsx: true }),
118
- '[foo]',
119
- 'context prop is ignored in xlsx mode'
120
- );
121
- t.is(
122
- stringifyStructRef({
123
- workbookName: 'Lorem',
124
- sheetName: 'Ipsum',
125
- columns: [ 'foo' ]
126
- }, { xlsx: false }),
127
- '[foo]',
128
- 'workbookName+sheetName props are ignored in default mode'
129
- );
130
- t.is(
131
- stringifyStructRef({
132
- workbookName: 'Lorem',
133
- sheetName: 'Ipsum',
134
- columns: [ 'foo' ]
135
- }, { xlsx: true }),
136
- '[Lorem]Ipsum![foo]',
137
- 'workbookName+sheetName props are rendered correctly'
138
- );
139
- t.is(
140
- stringifyStructRef({
141
- workbookName: 'Lorem',
142
- columns: [ 'foo' ]
143
- }, { xlsx: true }),
144
- '[Lorem]![foo]',
145
- 'workbookName prop is rendered correctly'
146
- );
147
- t.is(
148
- stringifyStructRef({
149
- sheetName: 'Ipsum',
150
- columns: [ 'foo' ]
151
- }, { xlsx: true }),
152
- 'Ipsum![foo]',
153
- 'sheetName prop is rendered correctly'
154
- );
155
- t.end();
156
- });
157
-
158
- test('longform serialize (in xlsx mode)', t => {
159
- // thisRow should mean we don't see @'s in output
160
- t.is(
161
- stringifyStructRef({
162
- table: 'Table2',
163
- columns: [ 'col1' ],
164
- sections: [ 'this row' ]
165
- }, { xlsx: true, thisRow: true }),
166
- 'Table2[[#This row],[col1]]',
167
- 'Table2[[#This row],[col1]] (xlsx mode)'
168
- );
169
-
170
- t.is(
171
- stringifyStructRef({
172
- table: 'Table2',
173
- columns: [ 'col1' ],
174
- sections: [ 'this row' ]
175
- }, { xlsx: false, thisRow: true }),
176
- 'Table2[[#This row],[col1]]',
177
- 'Table2[[#This row],[col1]] (non xlsx mode)'
178
- );
179
-
180
- t.end();
181
- });
182
-
package/lib/toCol.spec.js DELETED
@@ -1,11 +0,0 @@
1
- import { test } from 'tape';
2
- import { toCol } from './toCol.js';
3
-
4
- // What happens when B2:A1 -> should work!
5
- test('toCol converts integers to column ids', t => {
6
- t.is(toCol(0), 'A');
7
- t.is(toCol(26), 'AA');
8
- t.is(toCol(701), 'ZZ');
9
- t.is(toCol(18277), 'ZZZ');
10
- t.end();
11
- });