mirror of
https://github.com/nodejs/node.git
synced 2025-05-16 04:04:17 +00:00

Closes: https://github.com/nodejs/node/pull/16280 PR-URL: https://github.com/nodejs/node/pull/16509 Fixes: https://github.com/nodejs/node/issues/14161 Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com>
466 lines
13 KiB
JavaScript
466 lines
13 KiB
JavaScript
describe('tableLayout', function () {
|
|
var Cell = require('../src/cell');
|
|
var layoutManager = require('../src/layout-manager');
|
|
var layoutTable = layoutManager.layoutTable;
|
|
var makeTableLayout = layoutManager.makeTableLayout;
|
|
var addRowSpanCells = layoutManager.addRowSpanCells;
|
|
var maxWidth = layoutManager.maxWidth;
|
|
var fillInTable = layoutManager.fillInTable;
|
|
var computeWidths = layoutManager.computeWidths;
|
|
var computeHeights = layoutManager.computeHeights;
|
|
var chai = require('chai');
|
|
var expect = chai.expect;
|
|
var _ = require('lodash');
|
|
|
|
it('simple 2x2 layout',function(){
|
|
var actual = makeTableLayout([
|
|
['hello','goodbye'],
|
|
['hola','adios']
|
|
]);
|
|
|
|
var expected = [
|
|
['hello','goodbye'],
|
|
['hola','adios']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('cross table',function(){
|
|
var actual = makeTableLayout([
|
|
{'1.0':['yes','no']},
|
|
{'2.0':['hello','goodbye']}
|
|
]);
|
|
|
|
var expected = [
|
|
['1.0','yes','no'],
|
|
['2.0','hello','goodbye']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('vertical table',function(){
|
|
var actual = makeTableLayout([
|
|
{'1.0':'yes'},
|
|
{'2.0':'hello'}
|
|
]);
|
|
|
|
var expected = [
|
|
['1.0','yes'],
|
|
['2.0','hello']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('colSpan adds RowSpanCells to the right',function(){
|
|
var actual = makeTableLayout([
|
|
[{content:'hello',colSpan:2}],
|
|
['hola','adios']
|
|
]);
|
|
|
|
var expected = [
|
|
[{content:'hello',colSpan:2},null],
|
|
['hola','adios']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('rowSpan adds RowSpanCell below',function(){
|
|
var actual = makeTableLayout([
|
|
[{content:'hello',rowSpan:2},'goodbye'],
|
|
['adios']
|
|
]);
|
|
|
|
var expected = [
|
|
['hello' , 'goodbye'],
|
|
[{spannerFor:[0,0]} , 'adios']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('rowSpan and cellSpan together',function(){
|
|
var actual = makeTableLayout([
|
|
[{content:'hello',rowSpan:2,colSpan:2},'goodbye'],
|
|
['adios']
|
|
]);
|
|
|
|
var expected = [
|
|
['hello' , null, 'goodbye'],
|
|
[{spannerFor:[0,0]} , null, 'adios']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('complex layout',function(){
|
|
var actual = makeTableLayout([
|
|
[{content:'hello',rowSpan:2,colSpan:2},{content:'yo',rowSpan:2,colSpan:2},'goodbye'],
|
|
['adios']
|
|
]);
|
|
|
|
var expected = [
|
|
['hello' , null, 'yo' , null, 'goodbye'],
|
|
[{spannerFor:[0,0]} , null, {spannerFor:[0,2]} , null, 'adios']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('complex layout2',function(){
|
|
var actual = makeTableLayout([
|
|
['a','b', {content:'c',rowSpan:3,colSpan:2},'d'],
|
|
[{content:'e',rowSpan:2,colSpan:2}, 'f'],
|
|
['g']
|
|
]);
|
|
|
|
var expected = [
|
|
['a', 'b', 'c', null, 'd'],
|
|
['e', null, {spannerFor:[0,2]}, null, 'f'],
|
|
[{spannerFor:[1,0]}, null, {spannerFor:[0,2]}, null, 'g']
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
it('stairstep spans',function(){
|
|
var actual = makeTableLayout([
|
|
[{content:'',rowSpan:2},''],
|
|
[{content:'',rowSpan:2}],
|
|
['']
|
|
]);
|
|
|
|
var expected = [
|
|
[{content:'',rowSpan:2}, ''],
|
|
[{spannerFor:[0,0]},{content:'',rowSpan:2}],
|
|
['',{spannerFor:[1,1]}]
|
|
];
|
|
|
|
checkLayout(actual,expected);
|
|
});
|
|
|
|
describe('fillInTable',function(){
|
|
function mc(opts,y,x){
|
|
var cell = new Cell(opts);
|
|
cell.x = x;
|
|
cell.y = y;
|
|
return cell;
|
|
}
|
|
|
|
it('will blank out individual cells',function(){
|
|
var cells = [
|
|
[mc('a',0,1)],
|
|
[mc('b',1,0)]
|
|
];
|
|
fillInTable(cells);
|
|
|
|
checkLayout(cells,[
|
|
['', 'a'],
|
|
['b', '']
|
|
]);
|
|
});
|
|
|
|
it('will autospan to the right',function(){
|
|
var cells = [
|
|
[],
|
|
[mc('a',1,1)]
|
|
];
|
|
fillInTable(cells);
|
|
|
|
checkLayout(cells,[
|
|
[{content:'',colSpan:2}, null],
|
|
['', 'a']
|
|
]);
|
|
});
|
|
|
|
it('will autospan down',function(){
|
|
var cells = [
|
|
[ mc('a',0,1)],
|
|
[]
|
|
];
|
|
fillInTable(cells);
|
|
addRowSpanCells(cells);
|
|
|
|
checkLayout(cells,[
|
|
[{content:'',rowSpan:2}, 'a'],
|
|
[{spannerFor:[0,0]}, '']
|
|
]);
|
|
});
|
|
|
|
it('will autospan right and down',function(){
|
|
var cells = [
|
|
[ mc('a',0,2)],
|
|
[],
|
|
[ mc('b',2,1)]
|
|
];
|
|
fillInTable(cells);
|
|
addRowSpanCells(cells);
|
|
|
|
checkLayout(cells,[
|
|
[{content:'',colSpan:2, rowSpan:2}, null, 'a'],
|
|
[{spannerFor:[0,0]}, null, {content:'', colSpan:1, rowSpan:2}],
|
|
['','b',{spannerFor:[1,2]}]
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('computeWidths',function() {
|
|
function mc(y,x,desiredWidth, colSpan) {
|
|
return {x:x,y:y,desiredWidth:desiredWidth,colSpan:colSpan};
|
|
}
|
|
|
|
it('finds the maximum desired width of each column', function () {
|
|
var widths = [];
|
|
var cells = [
|
|
[mc(0,0,7), mc(0,1,3), mc(0,2,5)],
|
|
[mc(1,0,8), mc(1,1,5), mc(1,2,2)],
|
|
[mc(2,0,6), mc(2,1,9), mc(2,2,1)]
|
|
];
|
|
|
|
computeWidths(widths, cells);
|
|
|
|
expect(widths).to.eql([8, 9, 5]);
|
|
});
|
|
|
|
it('won\'t touch hard coded values', function () {
|
|
var widths = [null, 3];
|
|
var cells = [
|
|
[mc(0,0,7), mc(0,1,3), mc(0,2,5)],
|
|
[mc(1,0,8), mc(1,1,5), mc(1,2,2)],
|
|
[mc(2,0,6), mc(2,1,9), mc(2,2,1)]
|
|
];
|
|
|
|
computeWidths(widths, cells);
|
|
|
|
expect(widths).to.eql([8, 3, 5]);
|
|
});
|
|
|
|
it('assumes undefined desiredWidth is 1', function () {
|
|
var widths = [];
|
|
var cells = [[{x:0,y:0}], [{x:0,y:1}], [{x:0,y:2}]];
|
|
computeWidths(widths, cells);
|
|
expect(widths).to.eql([1])
|
|
});
|
|
|
|
it('takes into account colSpan and wont over expand', function () {
|
|
var widths = [];
|
|
var cells = [
|
|
[mc(0,0,10, 2), mc(0,2,5)],
|
|
[mc(1,0,5), mc(1,1,5), mc(1,2,2)],
|
|
[mc(2,0,4), mc(2,1,2), mc(2,2,1)]
|
|
];
|
|
computeWidths(widths, cells);
|
|
expect(widths).to.eql([5, 5, 5]);
|
|
});
|
|
|
|
it('will expand rows involved in colSpan in a balanced way', function () {
|
|
var widths = [];
|
|
var cells = [
|
|
[mc(0,0,13,2), mc(0,2,5)],
|
|
[mc(1,0,5), mc(1,1,5), mc(1,2,2)],
|
|
[mc(2,0,4), mc(2,1,2), mc(2,2,1)]
|
|
];
|
|
computeWidths(widths, cells);
|
|
expect(widths).to.eql([6, 6, 5]);
|
|
});
|
|
|
|
it('expands across 3 cols', function () {
|
|
var widths = [];
|
|
var cells = [
|
|
[mc(0,0,25,3) ],
|
|
[mc(1,0,5), mc(1,1,5), mc(1,2,2) ],
|
|
[mc(2,0,4), mc(2,1,2), mc(2,2,1) ]
|
|
];
|
|
computeWidths(widths, cells);
|
|
expect(widths).to.eql([9, 9, 5]);
|
|
});
|
|
|
|
it('multiple spans in same table', function () {
|
|
var widths = [];
|
|
var cells = [
|
|
[mc(0,0,25,3) ],
|
|
[mc(1,0,30,3) ],
|
|
[mc(2,0,4), mc(2,1,2), mc(2,2,1) ]
|
|
];
|
|
computeWidths(widths, cells);
|
|
expect(widths).to.eql([11, 9, 8]);
|
|
});
|
|
|
|
it('spans will only edit uneditable tables',function(){
|
|
var widths = [null, 3];
|
|
var cells = [
|
|
[mc(0,0,20,3) ],
|
|
[mc(1,0,4), mc(1,1,20), mc(1,2,5) ]
|
|
];
|
|
computeWidths(widths, cells);
|
|
expect(widths).to.eql([7,3,8])
|
|
});
|
|
|
|
it('spans will only edit uneditable tables - first column uneditable',function(){
|
|
var widths = [3];
|
|
var cells = [
|
|
[mc(0,0,20,3) ],
|
|
[mc(1,0,4), mc(1,1,3), mc(1,2,5) ]
|
|
];
|
|
computeWidths(widths, cells);
|
|
expect(widths).to.eql([3,7,8])
|
|
});
|
|
});
|
|
|
|
describe('computeHeights',function(){
|
|
function mc(y,x,desiredHeight,colSpan){
|
|
return {x:x,y:y,desiredHeight:desiredHeight,rowSpan:colSpan};
|
|
}
|
|
|
|
it('finds the maximum desired height of each row',function(){
|
|
var heights = [];
|
|
var cells = [
|
|
[mc(0,0,7), mc(0,1,3), mc(0,2,5) ],
|
|
[mc(1,0,8), mc(1,1,5), mc(1,2,2) ],
|
|
[mc(2,0,6), mc(2,1,9), mc(2,2,1) ]
|
|
];
|
|
|
|
computeHeights(heights,cells);
|
|
|
|
expect(heights).to.eql([7,8,9]);
|
|
});
|
|
|
|
it('won\'t touch hard coded values',function(){
|
|
var heights = [null,3];
|
|
var cells = [
|
|
[mc(0,0,7), mc(0,1,3), mc(0,2,5)],
|
|
[mc(1,0,8), mc(1,1,5), mc(1,2,2)],
|
|
[mc(2,0,6), mc(2,1,9), mc(2,2,1)]
|
|
];
|
|
|
|
computeHeights(heights,cells);
|
|
|
|
expect(heights).to.eql([7,3,9]);
|
|
});
|
|
|
|
it('assumes undefined desiredHeight is 1',function(){
|
|
var heights = [];
|
|
var cells = [[{x:0,y:0},{x:1,y:0},{x:2,y:0}]];
|
|
computeHeights(heights,cells);
|
|
expect(heights).to.eql([1])
|
|
});
|
|
|
|
it('takes into account rowSpan and wont over expand',function(){
|
|
var heights = [];
|
|
var cells = [
|
|
[mc(0,0,10,2), mc(0,1,5), mc(0,2,2)],
|
|
[ mc(1,1,5), mc(1,2,2)],
|
|
[mc(2,0,4), mc(2,1,2), mc(2,2,1)]
|
|
];
|
|
computeHeights(heights,cells);
|
|
expect(heights).to.eql([5,5,4]);
|
|
});
|
|
|
|
it('will expand rows involved in rowSpan in a balanced way',function(){
|
|
var heights = [];
|
|
var cells = [
|
|
[mc(0,0,13,2), mc(0,1,5), mc(0,2,5)],
|
|
[ mc(1,1,5), mc(1,2,2)],
|
|
[mc(2,0,4), mc(2,1,2), mc(2,2,1)]
|
|
];
|
|
computeHeights(heights,cells);
|
|
expect(heights).to.eql([6,6,4]);
|
|
});
|
|
|
|
it('expands across 3 rows',function(){
|
|
var heights = [];
|
|
var cells = [
|
|
[mc(0,0,25,3), mc(0,1,5), mc(0,2,4)],
|
|
[ mc(1,1,5), mc(1,2,2)],
|
|
[ mc(2,1,2), mc(2,2,1)]
|
|
];
|
|
computeHeights(heights,cells);
|
|
expect(heights).to.eql([9,9,5]);
|
|
});
|
|
|
|
it('multiple spans in same table',function(){
|
|
var heights = [];
|
|
var cells = [
|
|
[mc(0,0,25,3), mc(0,1,30,3), mc(0,2,4)],
|
|
[ mc(1,2,2)],
|
|
[ mc(2,2,1)]
|
|
];
|
|
computeHeights(heights,cells);
|
|
expect(heights).to.eql([11,9,8]);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Provides a shorthand for validating a table of cells.
|
|
* To pass, both arrays must have the same dimensions, and each cell in `actualRows` must
|
|
* satisfy the shorthand assertion of the corresponding location in `expectedRows`.
|
|
*
|
|
* Available Expectations Can Be:
|
|
*
|
|
* * A `String` - Must be a normal cell with contents equal to the String value.
|
|
* * `null` - Must be a RowSpanCell
|
|
*
|
|
* Or an `Object` with any of the following properties (multiple properties allowed):
|
|
* * rowSpan:Number - Must be a normal cell with the given rowSpan.
|
|
* * colSpan:Number - Must be a normal cell with the given colSpan.
|
|
* * content:String - Must be a normal cell with the given content.
|
|
* * spannerFor:[row,col] - Must be a RowSpanCell delegating to the cell at the given coordinates.
|
|
*
|
|
* @param actualRows - the table of cells under test.
|
|
* @param expectedRows - a table of shorthand assertions.
|
|
*/
|
|
|
|
function checkLayout(actualTable,expectedTable){
|
|
_.forEach(expectedTable,function(expectedRow,y){
|
|
_.forEach(expectedRow,function(expectedCell,x){
|
|
if(expectedCell !== null){
|
|
var actualCell = findCell(actualTable,x,y);
|
|
checkExpectation(actualCell,expectedCell,x,y,actualTable);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function findCell(table,x,y){
|
|
for(var i = 0; i < table.length; i++){
|
|
var row = table[i];
|
|
for(var j = 0; j < row.length; j++){
|
|
var cell = row[j];
|
|
if(cell.x === x && cell.y === y){
|
|
return cell;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function checkExpectation(actualCell,expectedCell,x,y,actualTable){
|
|
if(_.isString(expectedCell)){
|
|
expectedCell = {content:expectedCell};
|
|
}
|
|
var address = '(' + y + ',' + x + ')';
|
|
if(expectedCell.hasOwnProperty('content')){
|
|
expect(actualCell, address).to.be.instanceOf(Cell);
|
|
expect(actualCell.content,'content of ' + address).to.equal(expectedCell.content);
|
|
}
|
|
if(expectedCell.hasOwnProperty('rowSpan')){
|
|
expect(actualCell, address).to.be.instanceOf(Cell);
|
|
expect(actualCell.rowSpan, 'rowSpan of ' + address).to.equal(expectedCell.rowSpan);
|
|
}
|
|
if(expectedCell.hasOwnProperty('colSpan')){
|
|
expect(actualCell, address).to.be.instanceOf(Cell);
|
|
expect(actualCell.colSpan, 'colSpan of ' + address).to.equal(expectedCell.colSpan);
|
|
}
|
|
if(expectedCell.hasOwnProperty('spannerFor')){
|
|
expect(actualCell, address).to.be.instanceOf(Cell.RowSpanCell);
|
|
expect(actualCell.originalCell,address + 'originalCell should be a cell').to.be.instanceOf(Cell);
|
|
expect(actualCell.originalCell,address + 'originalCell not right').to.equal(findCell(actualTable,
|
|
expectedCell.spannerFor[1],
|
|
expectedCell.spannerFor[0]
|
|
));
|
|
//TODO: retest here x,y coords
|
|
}
|
|
}
|
|
}); |