@borgar/fx 2.1.1 → 3.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.
package/lib/translate.js CHANGED
@@ -1,48 +1,36 @@
1
- import { RANGE, RANGE_BEAM, MAX_ROWS, MAX_COLS } from './constants.js';
1
+ import { MAX_ROWS, MAX_COLS } from './constants.js';
2
2
  import { fromA1, toA1 } from './a1.js';
3
3
  import { fromRC, toRC } from './rc.js';
4
4
  import { tokenize } from './lexer.js';
5
+ import { isRange } from './isType.js';
6
+
7
+ const calc = (abs, vX, aX) => {
8
+ if (vX == null) {
9
+ return null;
10
+ }
11
+ return abs ? vX : vX - aX;
12
+ };
5
13
 
6
14
  export function translateToRC (fx, anchorCell) {
7
15
  const { top, left } = fromA1(anchorCell);
8
16
  const isString = typeof fx === 'string';
9
17
 
10
18
  const tokens = isString
11
- ? tokenize(fx, { emitRanges: false, mergeRanges: false, r1c2: false })
19
+ ? tokenize(fx, { emitRanges: false, mergeRanges: false, allowTernary: true, r1c2: false })
12
20
  : fx;
13
21
 
14
22
  tokens.forEach(token => {
15
- if (token.type === RANGE) {
16
- const range = {};
17
- const d = fromA1(token.value);
18
-
19
- range.r0 = d.$top ? d.top : d.top - top;
20
- range.$r0 = d.$top;
21
- range.r1 = d.$bottom ? d.bottom : d.bottom - top;
22
- range.$r1 = d.$bottom;
23
-
24
- range.c0 = d.$left ? d.left : d.left - left;
25
- range.$c0 = d.$left;
26
- range.c1 = d.$right ? d.right : d.right - left;
27
- range.$c1 = d.$right;
28
-
29
- // console.error(token.value, d, range, [ top, left ]);
30
- token.value = toRC(range);
31
- }
32
- else if (token.type === RANGE_BEAM) {
23
+ if (isRange(token)) {
33
24
  const range = {};
34
25
  const d = fromA1(token.value);
35
-
36
- range.r0 = d.$top ? d.top : d.top - top;
26
+ range.r0 = calc(d.$top, d.top, top);
37
27
  range.$r0 = d.$top;
38
- range.r1 = d.$bottom ? d.bottom : d.bottom - top;
28
+ range.r1 = calc(d.$bottom, d.bottom, top);
39
29
  range.$r1 = d.$bottom;
40
-
41
- range.c0 = d.$left ? d.left : d.left - left;
30
+ range.c0 = calc(d.$left, d.left, left);
42
31
  range.$c0 = d.$left;
43
- range.c1 = d.$right ? d.right : d.right - left;
32
+ range.c1 = calc(d.$right, d.right, left);
44
33
  range.$c1 = d.$right;
45
-
46
34
  token.value = toRC(range);
47
35
  }
48
36
  });
@@ -54,11 +42,11 @@ export function translateToRC (fx, anchorCell) {
54
42
 
55
43
  function toFixed (val, abs, base, max) {
56
44
  let v = val;
57
- if (!abs) {
45
+ if (v != null && !abs) {
58
46
  v = base + val;
59
47
  // Excel "wraps around" when value goes out of lower bounds.
60
- // It's a bit quirky on entry as Excel wants to re-rewite the
61
- // references but behaviour is consistent with INDIRECT:
48
+ // It's a bit quirky on entry as Excel _really wants_ to re-rewite the
49
+ // references but the behaviour is consistent with INDIRECT:
62
50
  // ... In A1: RC[-1] => R1C[16383].
63
51
  if (v < 0) {
64
52
  v = max + v + 1;
@@ -76,11 +64,11 @@ export function translateToA1 (fx, anchorCell) {
76
64
  const isString = typeof fx === 'string';
77
65
 
78
66
  const tokens = isString
79
- ? tokenize(fx, { emitRanges: false, mergeRanges: false, r1c1: true })
67
+ ? tokenize(fx, { emitRanges: false, mergeRanges: false, allowTernary: true, r1c1: true })
80
68
  : fx;
81
69
 
82
70
  tokens.forEach(token => {
83
- if (token.type === RANGE || token.type === RANGE_BEAM) {
71
+ if (isRange(token)) {
84
72
  const range = {};
85
73
  const d = fromRC(token.value);
86
74
  const r0 = toFixed(d.r0, d.$r0, anchor.top, MAX_ROWS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@borgar/fx",
3
- "version": "2.1.1",
3
+ "version": "3.0.0",
4
4
  "description": "Utilities for working with Excel formulas",
5
5
  "main": "dist/fx.js",
6
6
  "module": "lib/index.js",
@@ -11,8 +11,10 @@
11
11
  }
12
12
  },
13
13
  "scripts": {
14
- "lint": "eslint index.js lib/*.js",
15
- "test": "tape lib/*-test.js | tap-min",
14
+ "preversion": "npm test && npm run lint",
15
+ "version": "npm run build",
16
+ "lint": "eslint lib/*.js",
17
+ "test": "tape lib/*.spec.js | tap-min",
16
18
  "build": "NODE_ENV=production rollup -c"
17
19
  },
18
20
  "repository": {
@@ -36,16 +38,16 @@
36
38
  "author": "Borgar Þorsteinsson <borgar@borgar.net> (http://borgar.net/)",
37
39
  "license": "MIT",
38
40
  "devDependencies": {
39
- "@babel/core": "~7.19.6",
41
+ "@babel/core": "~7.21.0",
40
42
  "@babel/eslint-parser": "~7.19.1",
41
- "@babel/preset-env": "~7.19.4",
42
- "@borgar/eslint-config": "~2.2.1",
43
- "@rollup/plugin-babel": "~6.0.2",
43
+ "@babel/preset-env": "~7.20.2",
44
+ "@borgar/eslint-config": "~3.0.0",
45
+ "@rollup/plugin-babel": "~6.0.3",
44
46
  "babel-eslint": "~10.1.0",
45
- "eslint": "~8.26.0",
46
- "rollup": "~3.2.3",
47
+ "eslint": "~8.34.0",
48
+ "rollup": "~3.17.2",
47
49
  "rollup-plugin-minification": "~0.2.0",
48
50
  "tap-min": "~2.0.0",
49
- "tape": "~5.6.1"
51
+ "tape": "~5.6.3"
50
52
  }
51
53
  }
package/lib/a1-test.js DELETED
@@ -1,158 +0,0 @@
1
- /* eslint-disable object-property-newline, object-curly-newline */
2
- import { test, Test } from 'tape';
3
- import {
4
- fromCol,
5
- toCol,
6
- fromRow,
7
- toRow,
8
- toRelative,
9
- toAbsolute,
10
- parseA1Ref
11
- } from './a1.js';
12
-
13
- Test.prototype.isA1Equal = function isTokens (expr, result, opts) {
14
- if (result) {
15
- result = {
16
- sheetName: '',
17
- workbookName: '',
18
- range: null,
19
- name: '',
20
- ...result
21
- };
22
- if (result.range && typeof result.range === 'object') {
23
- // mix in some defaults so we don't have to write things out in full
24
- result.range = {
25
- top: null, left: null, bottom: null, right: null,
26
- $top: false, $left: false, $bottom: false, $right: false,
27
- ...result.range
28
- };
29
- }
30
- }
31
- this.deepEqual(parseA1Ref(expr, opts), result, expr);
32
- };
33
-
34
- // What happens when B2:A1 -> should work!
35
- test('convert to and from column and row ids', t => {
36
- t.is(fromCol('a'), 0);
37
- t.is(fromCol('A'), 0);
38
- t.is(fromCol('AA'), 26);
39
- t.is(fromCol('zz'), 701);
40
- t.is(fromCol('ZZZ'), 18277);
41
- t.is(toCol(0), 'A');
42
- t.is(toCol(26), 'AA');
43
- t.is(toCol(701), 'ZZ');
44
- t.is(toCol(18277), 'ZZZ');
45
- t.is(fromRow('11'), 10);
46
- t.is(fromRow('1'), 0);
47
- t.is(toRow(12), '13');
48
- t.is(toRow(77), '78');
49
- t.end();
50
- });
51
-
52
- test('parse A1 references', t => {
53
- t.isA1Equal('A1', { range: { top: 0, left: 0, bottom: 0, right: 0 } });
54
- t.isA1Equal('A1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1 } });
55
-
56
- t.isA1Equal('$A1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1, $left: true } });
57
- t.isA1Equal('A$1:B2', { range: { top: 0, left: 0, bottom: 1, right: 1, $top: true } });
58
- t.isA1Equal('A1:$B2', { range: { top: 0, left: 0, bottom: 1, right: 1, $right: true } });
59
- t.isA1Equal('A1:B$2', { range: { top: 0, left: 0, bottom: 1, right: 1, $bottom: true } });
60
-
61
- t.isA1Equal('A:A', { range: { top: 0, left: 0, bottom: 1048575, right: 0, $top: true, $bottom: true } });
62
- t.isA1Equal('C:C', { range: { top: 0, left: 2, bottom: 1048575, right: 2, $top: true, $bottom: true } });
63
- t.isA1Equal('C:$C', { range: { top: 0, left: 2, bottom: 1048575, right: 2, $right: true, $top: true, $bottom: true } });
64
- t.isA1Equal('$C:C', { range: { top: 0, left: 2, bottom: 1048575, right: 2, $left: true, $top: true, $bottom: true } });
65
- t.isA1Equal('$C:$C', { range: { top: 0, left: 2, bottom: 1048575, right: 2, $left: true, $right: true, $top: true, $bottom: true } });
66
-
67
- t.isA1Equal('1:1', { range: { top: 0, left: 0, bottom: 0, right: 16383, $left: true, $right: true } });
68
- t.isA1Equal('10:10', { range: { top: 9, left: 0, bottom: 9, right: 16383, $left: true, $right: true } });
69
- t.isA1Equal('10:$10', { range: { top: 9, left: 0, bottom: 9, right: 16383, $bottom: true, $left: true, $right: true } });
70
- t.isA1Equal('$10:10', { range: { top: 9, left: 0, bottom: 9, right: 16383, $top: true, $left: true, $right: true } });
71
- t.isA1Equal('$10:$10', { range: { top: 9, left: 0, bottom: 9, right: 16383, $top: true, $bottom: true, $left: true, $right: true } });
72
-
73
- t.isA1Equal('XFD1048576', { range: { top: 1048575, left: 16383, bottom: 1048575, right: 16383 } });
74
-
75
- t.isA1Equal('Sheet1!A1', {
76
- sheetName: 'Sheet1',
77
- range: { top: 0, left: 0, bottom: 0, right: 0 }
78
- });
79
-
80
- t.isA1Equal('\'Sheet1\'!A1', {
81
- sheetName: 'Sheet1',
82
- range: { top: 0, left: 0, bottom: 0, right: 0 }
83
- });
84
-
85
- t.isA1Equal('\'Sheet1\'\'s\'!A1', {
86
- sheetName: 'Sheet1\'s',
87
- range: { top: 0, left: 0, bottom: 0, right: 0 }
88
- });
89
-
90
- t.isA1Equal('[Workbook.xlsx]Sheet1!A1', {
91
- sheetName: 'Sheet1',
92
- workbookName: 'Workbook.xlsx',
93
- range: { top: 0, left: 0, bottom: 0, right: 0 }
94
- });
95
-
96
- t.isA1Equal("'[Workbook.xlsx]Sheet1'!A1", {
97
- sheetName: 'Sheet1',
98
- workbookName: 'Workbook.xlsx',
99
- range: { top: 0, left: 0, bottom: 0, right: 0 }
100
- });
101
-
102
- t.isA1Equal("'[Workbook.xlsx]Sheet1'!A1", {
103
- sheetName: 'Sheet1',
104
- workbookName: 'Workbook.xlsx',
105
- range: { top: 0, left: 0, bottom: 0, right: 0 }
106
- });
107
-
108
- t.isA1Equal("='[Workbook.xlsx]Sheet1'!A1", {
109
- sheetName: 'Sheet1',
110
- workbookName: 'Workbook.xlsx',
111
- range: { top: 0, left: 0, bottom: 0, right: 0 }
112
- });
113
- t.isA1Equal('0123456789abcdefghijklmnopqrstuvwxyz!A1', null);
114
-
115
- t.isA1Equal('[Workbook.xlsx]!A1', null);
116
- t.isA1Equal('[Workbook.xlsx]!A1:B2', null);
117
- t.isA1Equal('[Workbook.xlsx]!A:A', null);
118
- t.isA1Equal('[Workbook.xlsx]!1:1', null);
119
- t.isA1Equal('[]Sheet1!A1', null);
120
- t.isA1Equal('namedrange', { name: 'namedrange' });
121
-
122
- t.isA1Equal('Workbook.xlsx!namedrange', {
123
- workbookName: 'Workbook.xlsx',
124
- name: 'namedrange'
125
- });
126
-
127
- t.isA1Equal("'Workbook.xlsx'!namedrange", {
128
- workbookName: 'Workbook.xlsx',
129
- name: 'namedrange'
130
- });
131
-
132
- t.isA1Equal('[Workbook.xlsx]!namedrange', null);
133
- t.isA1Equal('pensioneligibilitypartner1', { name: 'pensioneligibilitypartner1' });
134
- t.isA1Equal('XFE1048577', { name: 'XFE1048577' });
135
-
136
- // with named ranges disallowed
137
- t.isA1Equal('namedrange', null, false);
138
- t.isA1Equal('Workbook.xlsx!namedrange', null, false);
139
- t.isA1Equal('pensioneligibilitypartner1', null, false);
140
- t.isA1Equal('XFE1048577', null, false);
141
-
142
- t.end();
143
- });
144
-
145
- test('A1 utilities', t => {
146
- const relA1Range = {
147
- top: 0, left: 0, bottom: 0, right: 0,
148
- $top: false, $left: false, $bottom: false, $right: false
149
- };
150
- const absA1Range = {
151
- top: 0, left: 0, bottom: 0, right: 0,
152
- $top: true, $left: true, $bottom: true, $right: true
153
- };
154
- t.deepEqual(toAbsolute(relA1Range), absA1Range);
155
- t.deepEqual(toRelative(absA1Range), relA1Range);
156
- t.end();
157
- });
158
-
@@ -1,35 +0,0 @@
1
- export function quickVerifyRangeA1 (tokenValue) {
2
- // Quickly determine if range valus are out of bounds: Split the string into
3
- // numeric, alphabetical, and "other" chunks and parse them as base 36 numbers.
4
- // Both rows and cols can be represented in base 36 and we can decide which we
5
- // hold by checking if the chunk was already a finite number. So we can simply
6
- // compare against the base 36 parsed versions of XFD and 1048576.
7
- return tokenValue.split(/(\d+|[a-zA-Z]+)/).every(d => {
8
- const n = parseInt(d, 36);
9
- if (!isNaN(n)) {
10
- return isFinite(d)
11
- ? n <= 2183880786 // max rows
12
- : n <= 43321; // max cols
13
- }
14
- return true;
15
- });
16
- }
17
-
18
- const bounds = {
19
- 'R': 1048577,
20
- 'R[': 1048576,
21
- 'C': 16385,
22
- 'C[': 16384
23
- };
24
- export function quickVerifyRangeRC (tokenValue) {
25
- const reNums = /([RC]\[?)(-?\d+)/gi;
26
- let m;
27
- while ((m = reNums.exec(tokenValue)) !== null) {
28
- const x = bounds[m[1]];
29
- const val = parseInt(m[2], 10);
30
- if (val >= x || val <= -x) {
31
- return false;
32
- }
33
- }
34
- return true;
35
- }
package/lib/rc-test.js DELETED
@@ -1,111 +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 { parseRCRef } from './rc.js';
5
-
6
- Test.prototype.isRCEqual = function isTokens (expr, result, opts) {
7
- if (result) {
8
- result = {
9
- sheetName: '',
10
- workbookName: '',
11
- name: '',
12
- range: null,
13
- ...result
14
- };
15
- if (result.range && typeof result.range === 'object') {
16
- // mix in some defaults so we don't have to write things out in full
17
- result.range = {
18
- r0: null, c0: null, r1: null, c1: null,
19
- $r0: false, $c0: false, $r1: false, $c1: false,
20
- ...result.range
21
- };
22
- }
23
- }
24
- this.deepEqual(parseRCRef(expr, opts), result, expr);
25
- };
26
-
27
- test('parse single R1C1 references', t => {
28
- // current row
29
- t.isRCEqual('R', { range: { r0: 0, c0: 0, r1: 0, c1: MAX_COLS, $c0: true, $c1: true } });
30
- t.isRCEqual('R[0]', { range: { r0: 0, c0: 0, r1: 0, c1: MAX_COLS, $c0: true, $c1: true } });
31
- // row N (equivalent to 1:1)
32
- t.isRCEqual('R0', { name: 'R0' });
33
- t.isRCEqual('R1', { range: { r0: 0, c0: 0, r1: 0, c1: MAX_COLS, $r0: true, $r1: true, $c0: true, $c1: true } });
34
- t.isRCEqual('R10', { range: { r0: 9, c0: 0, r1: 9, c1: MAX_COLS, $r0: true, $r1: true, $c0: true, $c1: true } });
35
- // row following current
36
- t.isRCEqual('R[1]', { range: { r0: 1, c0: 0, r1: 1, c1: MAX_COLS, $c0: true, $c1: true } });
37
- // row preceding current
38
- t.isRCEqual('R[-1]', { range: { r0: -1, c0: 0, r1: -1, c1: MAX_COLS, $c0: true, $c1: true } });
39
- // current column
40
- t.isRCEqual('C', { range: { r0: 0, c0: 0, r1: MAX_ROWS, c1: 0, $r0: true, $r1: true } });
41
- t.isRCEqual('C[0]', { range: { r0: 0, c0: 0, r1: MAX_ROWS, c1: 0, $r0: true, $r1: true } });
42
- // column N (equivalent to A:A)
43
- t.isRCEqual('C0', { name: 'C0' });
44
- t.isRCEqual('C1', { range: { r0: 0, c0: 0, r1: MAX_ROWS, c1: 0, $c0: true, $c1: true, $r0: true, $r1: true } });
45
- t.isRCEqual('C10', { range: { r0: 0, c0: 9, r1: MAX_ROWS, c1: 9, $c0: true, $c1: true, $r0: true, $r1: true } });
46
- // column following current
47
- t.isRCEqual('C[1]', { range: { r0: 0, c0: 1, r1: MAX_ROWS, c1: 1, $r0: true, $r1: true } });
48
- // column preceding current
49
- t.isRCEqual('C[-1]', { range: { r0: 0, c0: -1, r1: MAX_ROWS, c1: -1, $r0: true, $r1: true } });
50
- // current cell
51
- t.isRCEqual('RC', { range: { r0: 0, c0: 0, r1: 0, c1: 0 } });
52
- t.isRCEqual('R0C0', { name: 'R0C0' });
53
- // fixed cell
54
- t.isRCEqual('R1C1', { range: { r0: 0, c0: 0, r1: 0, c1: 0, $c0: true, $c1: true, $r0: true, $r1: true } });
55
- t.isRCEqual('R10C8', { range: { r0: 9, c0: 7, r1: 9, c1: 7, $c0: true, $c1: true, $r0: true, $r1: true } });
56
- t.isRCEqual('R-10C-8', null);
57
- // relative parts
58
- t.isRCEqual('R[2]C', { range: { r0: 2, c0: 0, r1: 2, c1: 0 } });
59
- t.isRCEqual('R[-2]C', { range: { r0: -2, c0: 0, r1: -2, c1: 0 } });
60
- t.isRCEqual('RC[3]', { range: { r0: 0, c0: 3, r1: 0, c1: 3 } });
61
- t.isRCEqual('RC[-3]', { range: { r0: 0, c0: -3, r1: 0, c1: -3 } });
62
- t.isRCEqual('R[2]C[4]', { range: { r0: 2, c0: 4, r1: 2, c1: 4 } });
63
- t.isRCEqual('R[-2]C[-4]', { range: { r0: -2, c0: -4, r1: -2, c1: -4 } });
64
- // mixed fixed and relative
65
- t.isRCEqual('R[9]C9', { range: { r0: 9, c0: 8, r1: 9, c1: 8, $c0: true, $c1: true } });
66
- t.isRCEqual('R9C[9]', { range: { r0: 8, c0: 9, r1: 8, c1: 9, $r0: true, $r1: true } });
67
-
68
- // out of bounds
69
- t.isRCEqual('R1048577', { name: 'R1048577' });
70
- t.isRCEqual('R[1048576]', null);
71
- t.isRCEqual('C16385', { name: 'C16385' });
72
- t.isRCEqual('C[16384]', null);
73
-
74
- t.end();
75
- });
76
-
77
- test('parse joined R1C1 references', t => {
78
- // all "mirrored" refs are equivalent of the non mirrored counterparts...
79
- t.isRCEqual('R:R', { range: { r0: 0, c0: 0, r1: 0, c1: MAX_COLS, $c0: true, $c1: true } });
80
- t.isRCEqual('R[0]:R[0]', { range: { r0: 0, c0: 0, r1: 0, c1: MAX_COLS, $c0: true, $c1: true } });
81
- t.isRCEqual('R1:R1', { range: { r0: 0, c0: 0, r1: 0, c1: MAX_COLS, $r0: true, $r1: true, $c0: true, $c1: true } });
82
- t.isRCEqual('R10:R10', { range: { r0: 9, c0: 0, r1: 9, c1: MAX_COLS, $r0: true, $r1: true, $c0: true, $c1: true } });
83
- t.isRCEqual('R[1]:R[1]', { range: { r0: 1, c0: 0, r1: 1, c1: MAX_COLS, $c0: true, $c1: true } });
84
- t.isRCEqual('R[-1]:R[-1]', { range: { r0: -1, c0: 0, r1: -1, c1: MAX_COLS, $c0: true, $c1: true } });
85
- t.isRCEqual('C:C', { range: { r0: 0, c0: 0, r1: MAX_ROWS, c1: 0, $r0: true, $r1: true } });
86
- t.isRCEqual('C[0]:C[0]', { range: { r0: 0, c0: 0, r1: MAX_ROWS, c1: 0, $r0: true, $r1: true } });
87
- t.isRCEqual('C1:C1', { range: { r0: 0, c0: 0, r1: MAX_ROWS, c1: 0, $c0: true, $c1: true, $r0: true, $r1: true } });
88
- t.isRCEqual('C10:C10', { range: { r0: 0, c0: 9, r1: MAX_ROWS, c1: 9, $c0: true, $c1: true, $r0: true, $r1: true } });
89
- t.isRCEqual('C[1]:C[1]', { range: { r0: 0, c0: 1, r1: MAX_ROWS, c1: 1, $r0: true, $r1: true } });
90
- t.isRCEqual('C[-1]:C[-1]', { range: { r0: 0, c0: -1, r1: MAX_ROWS, c1: -1, $r0: true, $r1: true } });
91
- t.isRCEqual('R0:R0', null);
92
- t.isRCEqual('C0:C0', null);
93
- t.isRCEqual('R[9]C9:R[9]C9', { range: { r0: 9, c0: 8, r1: 9, c1: 8, $c0: true, $c1: true } });
94
- t.isRCEqual('R9C[9]:R9C[9]', { range: { r0: 8, c0: 9, r1: 8, c1: 9, $r0: true, $r1: true } });
95
- t.isRCEqual('R[1]C[1]:R1C1', { range: { r0: 1, c0: 1, r1: 0, c1: 0, $c1: true, $r1: true } });
96
- t.isRCEqual('R[1]C[1]:R1C1', { range: { r0: 1, c0: 1, r1: 0, c1: 0, $c1: true, $r1: true } });
97
- t.isRCEqual('R1C1:R2C2', { range: { r0: 0, c0: 0, r1: 1, c1: 1, $c0: true, $c1: true, $r0: true, $r1: true } });
98
- t.isRCEqual('R2C2:R1C1', { range: { r0: 1, c0: 1, r1: 0, c1: 0, $c0: true, $c1: true, $r0: true, $r1: true } });
99
- // single thing
100
- t.isRCEqual('C1:C3', { range: { r0: 0, c0: 0, r1: MAX_ROWS, c1: 2, $c0: true, $c1: true, $r0: true, $r1: true } });
101
- t.isRCEqual('R[1]:R3', { range: { r0: 1, c0: 0, r1: 2, c1: MAX_COLS, $c0: true, $c1: true, $r0: false, $r1: true } });
102
- t.isRCEqual('R[1]C1:R1C[-1]', { range: { r0: 1, c0: 0, r1: 0, c1: -1, $r0: false, $c0: true, $r1: true, $c1: false } });
103
- // many things
104
- t.isRCEqual('R:C', null);
105
- t.isRCEqual('R:RC', null);
106
- t.isRCEqual('RC:R', null);
107
- t.isRCEqual('RC:C', null);
108
- t.isRCEqual('C:R', null);
109
- t.isRCEqual('C:RC', null);
110
- t.end();
111
- });