UNPKG

@borgar/fx

Version:

Utilities for working with Excel formulas

331 lines (288 loc) 7.31 kB
/* eslint-disable object-property-newline, object-curly-newline */ import { test, Test } from 'tape'; import { parseStructRef, stringifyStructRef } from './sr.js'; Test.prototype.isSREqual = function isSREqual (expr, expect, opts) { if (expect) { expect = opts?.xlsx ? { workbookName: '', sheetName: '', table: '', columns: [], sections: [], ...expect } : { context: [], table: '', columns: [], sections: [], ...expect }; } this.deepEqual(parseStructRef(expr, opts), expect, expr); }; test('parse structured references', t => { t.isSREqual('table[col]', { table: 'table', columns: [ 'col' ] }); t.isSREqual('[#All]', { sections: [ 'all' ] }); t.isSREqual('[column name]', { columns: [ 'column name' ] }); t.isSREqual('[column name]!foo', null); t.isSREqual('[foo]bar', null); t.isSREqual('[[my column]]', { columns: [ 'my column' ] }); t.isSREqual('[[my column]:otherColumn]', { columns: [ 'my column', 'otherColumn' ] }); t.isSREqual('[ [my column]:otherColumn ]', { columns: [ 'my column', 'otherColumn ' ] }); t.isSREqual('[ [my column]: otherColumn ]', { columns: [ 'my column', ' otherColumn ' ] }); t.isSREqual('[ @[ my column ]: otherColumn ]', { columns: [ ' my column ', ' otherColumn ' ], sections: [ 'this row' ] }); t.isSREqual('[[#Data], [my column]:otherColumn]', { columns: [ 'my column', 'otherColumn' ], sections: [ 'data' ] }); t.isSREqual('[ [#Data], [my column]:[\'@foo] ]', { columns: [ 'my column', '@foo' ], sections: [ 'data' ] }); t.isSREqual('workbook.xlsx!tableName[ [#Data], [my column]:[\'@foo] ]', { columns: [ 'my column', '@foo' ], sections: [ 'data' ], table: 'tableName', context: [ 'workbook.xlsx' ] }); t.isSREqual('[[#Data],[#data],[#Data],[#Data],[#Totals],[#Totals],[#Totals],foo]', { columns: [ 'foo' ], sections: [ 'data', 'totals' ] }); t.isSREqual("'Sheet'!Table[Column]", { columns: [ 'Column' ], table: 'Table', context: [ 'Sheet' ] }); t.isSREqual("Sheet1!Table1[foo '[bar']]", { columns: [ 'foo [bar]' ], table: 'Table1', context: [ 'Sheet1' ] }); t.isSREqual('[myworkbook.xlsx]Sheet1!TMP8w0habhr[#All]', { columns: [], table: 'TMP8w0habhr', context: [ 'myworkbook.xlsx', 'Sheet1' ], sections: [ 'all' ] }); t.end(); }); test('serialize structured references', t => { t.is( stringifyStructRef({ columns: [ 'foo' ] }), '[foo]', '[foo]' ); t.is( stringifyStructRef({ columns: [ 'foo' ], table: 'tableName' }), 'tableName[foo]', 'tableName[foo]' ); t.is( stringifyStructRef({ columns: [ 'lorem ipsum' ], table: 'tableName' }), 'tableName[lorem ipsum]', 'tableName[lorem ipsum]' ); t.is( stringifyStructRef({ columns: [ 'foo', 'sævör' ], table: 'tableName' }), 'tableName[[foo]:[sævör]]', 'tableName[[foo]:[sævör]]' ); t.is( stringifyStructRef({ sections: [ 'data' ], table: 'tableName' }), 'tableName[#Data]', 'tableName[#Data]' ); t.is( stringifyStructRef({ columns: [ 'lorem ipsum', 'sævör' ], table: 'tableName' }), 'tableName[[lorem ipsum]:[sævör]]', 'tableName[[lorem ipsum]:[sævör]]' ); t.is( stringifyStructRef({ columns: [ 'my column', 'fo@o' ], sections: [ 'data' ], table: 'tableName', context: [ 'workbook.xlsx' ] }), 'workbook.xlsx!tableName[[#Data],[my column]:[fo\'@o]]', 'workbook.xlsx!tableName[[#Data],[my column]:[fo\'@o]]' ); t.is( stringifyStructRef({ columns: [ 'bar' ], sections: [ 'this row' ], table: 'foo' }), 'foo[@bar]', 'foo[@bar]' ); t.is( stringifyStructRef({ columns: [ 'bar', 'baz' ], sections: [ 'this row' ], table: 'foo' }), 'foo[@[bar]:[baz]]', 'foo[@[bar]:[baz]]' ); t.is( stringifyStructRef({ columns: [ 'lorem ipsum', 'baz' ], sections: [ 'this row' ], table: 'foo' }), 'foo[@[lorem ipsum]:[baz]]', 'foo[@[lorem ipsum]:[baz]]' ); t.is( stringifyStructRef({ sections: [ 'data', 'headers' ], table: 'table' }), 'table[[#Data],[#Headers]]', 'table[[#Data],[#Headers]]' ); t.end(); }); test('structured references parse and serialize in xlsx mode', t => { t.isSREqual('[Workbook.xlsx]!Table[#Data]', { workbookName: 'Workbook.xlsx', table: 'Table', sections: [ 'data' ] }, { xlsx: true }); t.isSREqual('[Workbook.xlsx]Sheet1!Table[#Data]', { workbookName: 'Workbook.xlsx', sheetName: 'Sheet1', table: 'Table', sections: [ 'data' ] }, { xlsx: true }); t.isSREqual('Sheet1!Table[#Data]', { sheetName: 'Sheet1', table: 'Table', sections: [ 'data' ] }, { xlsx: true }); t.is( stringifyStructRef({ context: [ 'Lorem', 'Ipsum' ], columns: [ 'foo' ] }, { xlsx: true }), '[foo]', 'context prop is ignored in xlsx mode' ); t.is( stringifyStructRef({ workbookName: 'Lorem', sheetName: 'Ipsum', columns: [ 'foo' ] }, { xlsx: false }), '[foo]', 'workbookName+sheetName props are ignored in default mode' ); t.is( stringifyStructRef({ workbookName: 'Lorem', sheetName: 'Ipsum', columns: [ 'foo' ] }, { xlsx: true }), '[Lorem]Ipsum![foo]', 'workbookName+sheetName props are rendered correctly' ); t.is( stringifyStructRef({ workbookName: 'Lorem', columns: [ 'foo' ] }, { xlsx: true }), '[Lorem]![foo]', 'workbookName prop is rendered correctly' ); t.is( stringifyStructRef({ sheetName: 'Ipsum', columns: [ 'foo' ] }, { xlsx: true }), 'Ipsum![foo]', 'sheetName prop is rendered correctly' ); t.end(); }); test('longform serialize (in xlsx mode)', t => { // thisRow should have no effect when parsing t.isSREqual('Table2[[#This Row],[col1]]', { table: 'Table2', columns: [ 'col1' ], sections: [ 'this row' ] }, { xlsx: true, thisRow: true }); t.isSREqual('Table2[[#This Row],[col1]]', { table: 'Table2', columns: [ 'col1' ], sections: [ 'this row' ] }, { xlsx: true, thisRow: false }); t.isSREqual('Table2[[#This Row],[col1]]', { table: 'Table2', columns: [ 'col1' ], sections: [ 'this row' ] }, { xlsx: false, thisRow: true }); t.isSREqual('Table2[[#This Row],[col1]]', { table: 'Table2', columns: [ 'col1' ], sections: [ 'this row' ] }, { xlsx: false, thisRow: false }); // thisRow should mean we don't see @'s in output t.is( stringifyStructRef({ table: 'Table2', columns: [ 'col1' ], sections: [ 'this row' ] }, { xlsx: true, thisRow: true }), 'Table2[[#This row],[col1]]', 'Table2[[#This row],[col1]] (xlsx mode)' ); t.is( stringifyStructRef({ table: 'Table2', columns: [ 'col1' ], sections: [ 'this row' ] }, { xlsx: false, thisRow: true }), 'Table2[[#This row],[col1]]', 'Table2[[#This row],[col1]] (non xlsx mode)' ); t.end(); });