describe('WalkontableTable', function () {
var $table,
$container,
$wrapper,
debug = false;
beforeEach(function () {
$wrapper = $('
').css({ overflow: 'hidden', position: 'relative' });
$wrapper.width(100).height(201);
$container = $('');
$table = $(''); // create a table that is not attached to document
$wrapper.append($container);
$container.append($table);
$wrapper.appendTo('body');
createDataArray();
});
afterEach(function () {
if (!debug) {
$('.wtHolder').remove();
}
$wrapper.remove();
});
it('should create as many rows as fits in height', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
expect($table.find('tbody tr').length).toBe(9);
});
it('should create as many rows as in `totalRows` if it is smaller than `height`', function () {
this.data.splice(5, this.data.length - 5);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
expect($table.find('tbody tr').length).toBe(5);
});
it('first row should have as many columns as in THEAD', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
columnHeaders: [function (col, TH) {
TH.innerHTML = col + 1;
}]
});
wt.draw();
expect($table.find('tbody tr:first td').length).toBe($table.find('thead th').length);
});
it('should put a blank cell in the corner if both rowHeaders and colHeaders are set', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
columnHeaders: [function (col, TH) {
if (col > -1) {
TH.innerHTML = 'Column';
}
}],
rowHeaders: [function (row, TH) {
if (row > -1) {
TH.innerHTML = 'Row';
}
}]
});
wt.draw();
expect($table.find('thead tr:first th').length).toBe(wt.wtTable.getRenderedColumnsCount() + 1); // 4 columns in THEAD + 1 empty cell in the corner
expect($table.find('thead tr:first th:eq(0)')[0].innerHTML.replace(/ /, '')).toBe(''); // corner row is empty (or contains only )
expect($table.find('thead tr:first th:eq(1)')[0].innerHTML).toBe('Column');
expect($table.find('tbody tr:first th:eq(0)')[0].innerHTML).toBe('Row');
});
it('getCell should only return cells from rendered rows', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
expect(wt.wtTable.getCell(new Walkontable.CellCoords(7, 0)) instanceof HTMLElement).toBe(true);
expect($table.find('tr:eq(8) td:first-child').text()).toEqual(this.data[8][0].toString());
expect(wt.wtTable.getCell(new Walkontable.CellCoords(20, 0))).toBe(-2); // exit code
expect(wt.wtTable.getCell(new Walkontable.CellCoords(25, 0))).toBe(-2); // exit code
});
it('getCoords should return coords of TD', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
var $td2 = $table.find('tbody tr:eq(1) td:eq(1)');
expect(wt.wtTable.getCoords($td2[0])).toEqual(new Walkontable.CellCoords(1, 1));
});
it('getCoords should return coords of TD (with row header)', function () {
$wrapper.width(300);
function plusOne(i) {
return i + 1;
}
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
rowHeaders: [function (row, TH) {
TH.innerHTML = plusOne(row);
}]
});
wt.draw();
var $td2 = $table.find('tbody tr:eq(1) td:eq(1)');
expect(wt.wtTable.getCoords($td2[0])).toEqual(new Walkontable.CellCoords(1, 1));
});
it('getStretchedColumnWidth should return valid column width when stretchH is set as \'all\'', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
rowHeaders: [function (row, TH) {
TH.innerHTML = row + 1;
}],
stretchH: 'all'
});
wt.draw();
wt.wtViewport.columnsRenderCalculator.refreshStretching(502);
expect(wt.wtTable.getStretchedColumnWidth(0, 50)).toBe(125);
expect(wt.wtTable.getStretchedColumnWidth(1, 50)).toBe(125);
expect(wt.wtTable.getStretchedColumnWidth(2, 50)).toBe(125);
expect(wt.wtTable.getStretchedColumnWidth(3, 50)).toBe(127);
});
it('getStretchedColumnWidth should return valid column width when stretchH is set as \'last\'', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
rowHeaders: [function (row, TH) {
TH.innerHTML = row + 1;
}],
stretchH: 'last'
});
wt.draw();
wt.wtViewport.columnsRenderCalculator.refreshStretching(502);
expect(wt.wtTable.getStretchedColumnWidth(0, 50)).toBe(50);
expect(wt.wtTable.getStretchedColumnWidth(1, 50)).toBe(50);
expect(wt.wtTable.getStretchedColumnWidth(2, 50)).toBe(50);
expect(wt.wtTable.getStretchedColumnWidth(3, 50)).toBe(352);
});
it('should use custom cell renderer if provided', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
cellRenderer: function cellRenderer(row, column, TD) {
var cellData = getData(row, column);
if (cellData === void 0) {
TD.innerHTML = '';
} else {
TD.innerHTML = cellData;
}
TD.className = '';
TD.style.backgroundColor = 'yellow';
}
});
wt.draw();
expect($table.find('td:first')[0].style.backgroundColor).toBe('yellow');
});
it('should remove rows if they were removed in data source', function () {
this.data.splice(8, this.data.length - 8); // second param is required by IE8
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
expect($table.find('tbody tr').length).toBe(8);
this.data.splice(7, this.data.length - 7); // second param is required by IE8
wt.draw();
expect($table.find('tbody tr').length).toBe(7);
});
it('should render as much columns as the container width allows, if width is null', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
columnHeaders: [function (col, TH) {
TH.innerHTML = col + 1;
}]
});
wt.draw();
expect($table.find('thead tr:first').children().length).toBe(2);
expect($table.find('tbody tr:first').children().length).toBe(2);
$wrapper.width(200);
wt.draw();
expect($table.find('thead tr:first').children().length).toBe(4);
expect($table.find('tbody tr:first').children().length).toBe(4);
});
it('should render as much columns as the container width allows, if width is null (with row header)', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
rowHeaders: [function (row, TH) {
TH.innerHTML = row + 1;
}],
columnHeaders: [function (col, TH) {
TH.innerHTML = col + 1;
}]
});
wt.draw();
expect($table.find('thead tr:first').children().length).toBe(2);
expect($table.find('tbody tr:first').children().length).toBe(2);
$wrapper.width(200);
wt.draw();
expect($table.find('thead tr:first').children().length).toBe(4);
expect($table.find('tbody tr:first').children().length).toBe(4);
});
it('should use column width function to get column width', function () {
$wrapper.width(600);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
rowHeaders: [function (row, TH) {
TH.innerHTML = row + 1;
}],
columnHeaders: [function (col, TH) {
TH.innerHTML = col + 1;
}],
columnWidth: function columnWidth(column) {
return (column + 1) * 50;
}
});
wt.draw();
expect($table.find('tbody tr:first td:eq(0)').outerWidth()).toBe(50);
expect($table.find('tbody tr:first td:eq(1)').outerWidth()).toBe(100);
expect($table.find('tbody tr:first td:eq(2)').outerWidth()).toBe(150);
expect($table.find('tbody tr:first td:eq(3)').outerWidth()).toBe(200);
});
it('should use column width array to get column width', function () {
$wrapper.width(600);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
rowHeaders: [function (row, TH) {
TH.innerHTML = row + 1;
}],
columnHeaders: [function (col, TH) {
TH.innerHTML = col + 1;
}],
columnWidth: [50, 100, 150, 201]
});
wt.draw();
expect($table.find('tbody tr:first td:eq(0)').outerWidth()).toBe(50);
expect($table.find('tbody tr:first td:eq(1)').outerWidth()).toBe(100);
expect($table.find('tbody tr:first td:eq(2)').outerWidth()).toBe(150);
expect($table.find('tbody tr:first td:eq(3)').outerWidth()).toBe(201);
});
it('should use column width integer to get column width', function () {
$wrapper.width(600);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
rowHeaders: [function (row, TH) {
TH.innerHTML = row + 1;
}],
columnHeaders: [function (col, TH) {
TH.innerHTML = col + 1;
}],
columnWidth: 100
});
wt.draw();
expect($table.find('tbody tr:first td:eq(0)').outerWidth()).toBe(100);
expect($table.find('tbody tr:first td:eq(1)').outerWidth()).toBe(100);
expect($table.find('tbody tr:first td:eq(2)').outerWidth()).toBe(100);
expect($table.find('tbody tr:first td:eq(3)').outerWidth()).toBe(100);
});
it('should use column width also when there are no rows', function () {
this.data.length = 0;
$wrapper.width(600);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: 4,
rowHeaders: [function (row, TH) {
TH.innerHTML = row + 1;
}],
columnHeaders: [function (col, TH) {
TH.innerHTML = col + 1;
}],
columnWidth: 100
});
wt.draw();
// start from eq(1) because eq(0) is corner header
expect($table.find('thead tr:first th:eq(1)').outerWidth()).toBe(100);
expect($table.find('thead tr:first th:eq(2)').outerWidth()).toBe(100);
expect($table.find('thead tr:first th:eq(3)').outerWidth()).toBe(100);
expect($table.find('thead tr:first th:eq(4)').outerWidth()).toBe(100);
});
it('should render a cell that is outside of the viewport horizontally', function () {
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
$table.find('tbody td').html('');
wt.draw();
expect($table.find('tbody tr:first td').length).toBe(2);
});
it('should not render a cell when fastDraw == true', function () {
var count = 0,
wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
cellRenderer: function cellRenderer(row, column, TD) {
count++;
return wt.wtSettings.defaults.cellRenderer(row, column, TD);
}
});
wt.draw();
var oldCount = count;
wt.draw(true);
expect(count).toBe(oldCount);
});
it('should not ignore fastDraw == true when grid was scrolled by amount of rows that doesn\'t exceed endRow', function () {
var count = 0,
wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
cellRenderer: function cellRenderer(row, column, TD) {
count++;
return wt.wtSettings.defaults.cellRenderer(row, column, TD);
},
viewportRowCalculatorOverride: function viewportRowCalculatorOverride(calc) {
calc.endRow += 10;
}
});
wt.draw();
var oldCount = count;
wt.scrollVertical(8);
wt.draw(true);
expect(count).not.toBeGreaterThan(oldCount);
});
it('should ignore fastDraw == true when grid was scrolled by amount of rows that exceeds endRow', function () {
var count = 0,
wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
cellRenderer: function cellRenderer(row, column, TD) {
count++;
return wt.wtSettings.defaults.cellRenderer(row, column, TD);
},
viewportRowCalculatorOverride: function viewportRowCalculatorOverride(calc) {
calc.endRow += 10;
}
});
wt.draw();
var oldCount = count;
wt.scrollVertical(10);
wt.draw(true);
expect(count).not.toBeGreaterThan(oldCount);
wt.scrollVertical(11);
wt.draw(true);
expect(count).toBeGreaterThan(oldCount);
});
it('should not ignore fastDraw == true when grid was scrolled by amount of columns that doesn\'t exceed endColumn', function () {
createDataArray(50, 50);
var count = 0,
wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
cellRenderer: function cellRenderer(row, column, TD) {
count++;
return wt.wtSettings.defaults.cellRenderer(row, column, TD);
},
viewportColumnCalculatorOverride: function viewportColumnCalculatorOverride(calc) {
calc.endColumn += 10;
}
});
wt.draw();
var oldCount = count;
wt.scrollHorizontal(8);
wt.draw(true);
expect(count).not.toBeGreaterThan(oldCount);
});
it('should ignore fastDraw == true when grid was scrolled by amount of columns that exceeds endColumn', function () {
createDataArray(50, 50);
var count = 0,
wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
cellRenderer: function cellRenderer(row, column, TD) {
count++;
return wt.wtSettings.defaults.cellRenderer(row, column, TD);
},
viewportColumnCalculatorOverride: function viewportColumnCalculatorOverride(calc) {
calc.endColumn += 10;
}
});
wt.draw();
var oldCount = count;
wt.scrollHorizontal(10);
wt.draw(true);
expect(count).not.toBeGreaterThan(oldCount);
wt.scrollHorizontal(11);
wt.draw(true);
expect(count).toBeGreaterThan(oldCount);
});
describe('cell header border', function () {
it('should be correct visible in fixedColumns and without row header', function () {
createDataArray(50, 50);
$wrapper.width(500).height(400);
var count = 0,
wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns,
columnWidth: 70,
fixedColumnsLeft: 2,
columnHeaders: [function (col, TH) {}]
});
wt.draw();
expect($('.ht_clone_top_left_corner thead tr th').eq(0).css('border-left-width')).toBe('1px');
expect($('.ht_clone_top_left_corner thead tr th').eq(0).css('border-right-width')).toBe('1px');
expect($('.ht_clone_top_left_corner thead tr th').eq(1).css('border-left-width')).toBe('0px');
expect($('.ht_clone_top_left_corner thead tr th').eq(1).css('border-right-width')).toBe('1px');
});
});
describe('isLastRowFullyVisible', function () {
it('should be false because it is only partially visible', function () {
createDataArray(8, 4);
$wrapper.width(185).height(175);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
expect(wt.wtTable.isLastRowFullyVisible()).toEqual(false);
});
it('should be true because it is fully visible', function () {
createDataArray(8, 4);
$wrapper.width(185).height(185);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
wt.scrollVertical(7);
wt.draw();
expect(wt.wtTable.isLastRowFullyVisible()).toEqual(true);
});
});
xdescribe('isLastColumnFullyVisible', function () {
it('should be false because it is only partially visible', function () {
createDataArray(18, 4);
$wrapper.width(209).height(185);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
expect(wt.wtTable.isLastColumnFullyVisible()).toEqual(false); // few pixels are obstacled by scrollbar
});
it('should be true because it is fully visible', function () {
createDataArray(18, 4);
$wrapper.width(180).height(185);
var wt = new Walkontable.Core({
table: $table[0],
data: getData,
totalRows: getTotalRows,
totalColumns: getTotalColumns
});
wt.draw();
wt.scrollHorizontal(1);
expect(wt.wtTable.isLastColumnFullyVisible()).toEqual(true);
});
});
});