UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

398 lines (309 loc) 12 kB
import Module from '../../../src/js/core/Module.js'; import FrozenRows from '../../../src/js/modules/FrozenRows/FrozenRows.js'; // Override the Module methods that interact with the table to avoid dependency issues const originalRegisterTableOption = Module.prototype.registerTableOption; Module.prototype.registerTableOption = function() {}; const originalRegisterColumnOption = Module.prototype.registerColumnOption; Module.prototype.registerColumnOption = function() {}; const originalRegisterComponentFunction = Module.prototype.registerComponentFunction; Module.prototype.registerComponentFunction = function() {}; describe('FrozenRows', function(){ // Restore original Module methods after all tests afterAll(() => { Module.prototype.registerTableOption = originalRegisterTableOption; Module.prototype.registerColumnOption = originalRegisterColumnOption; Module.prototype.registerComponentFunction = originalRegisterComponentFunction; }); // Test direct functionality without a complete table instance describe('Functionality tests', function() { test('freezeRow adds row to frozen rows', function(){ // Create mock elements document.createDocumentFragment = jest.fn().mockReturnValue({ appendChild: jest.fn() }); // Create a mock table const mockTable = { rowManager: { adjustTableSize: jest.fn(), styleRow: jest.fn() }, columnManager: { getContentsElement: jest.fn().mockReturnValue({ insertBefore: jest.fn() }), headersElement: { nextSibling: null, offsetWidth: 500 } }, options: {} }; // Create a FrozenRows instance const frozenRows = new FrozenRows(mockTable); // Mock the refreshData method frozenRows.refreshData = jest.fn(); frozenRows.styleRows = jest.fn(); // Create a mock row element const mockElement = document.createElement('div'); // Create a spy for appendChild const appendChildSpy = jest.spyOn(frozenRows.topElement, 'appendChild'); // Create a mock row const mockRow = { modules: {}, getElement: jest.fn().mockReturnValue(mockElement), initialize: jest.fn(), normalizeHeight: jest.fn() }; // Mock console.warn const originalWarn = console.warn; console.warn = jest.fn(); // Freeze the row frozenRows.freezeRow(mockRow); // Check that the row was properly frozen expect(mockRow.modules.frozen).toBe(true); expect(frozenRows.rows).toContain(mockRow); expect(appendChildSpy).toHaveBeenCalledWith(mockElement); expect(mockRow.initialize).toHaveBeenCalled(); expect(mockRow.normalizeHeight).toHaveBeenCalled(); expect(frozenRows.refreshData).toHaveBeenCalledWith(false, "display"); expect(mockTable.rowManager.adjustTableSize).toHaveBeenCalled(); expect(frozenRows.styleRows).toHaveBeenCalled(); // Clean up spy appendChildSpy.mockRestore(); // Try to freeze already frozen row frozenRows.freezeRow(mockRow); // Should show warning expect(console.warn).toHaveBeenCalledWith("Freeze Error - Row is already frozen"); // Restore console.warn console.warn = originalWarn; }); test('unfreezeRow removes row from frozen rows', function(){ // Create mock elements document.createDocumentFragment = jest.fn().mockReturnValue({ appendChild: jest.fn() }); // Create a mock table const mockTable = { rowManager: { adjustTableSize: jest.fn(), styleRow: jest.fn() }, columnManager: { getContentsElement: jest.fn().mockReturnValue({ insertBefore: jest.fn() }), headersElement: { nextSibling: null, offsetWidth: 500 } }, options: {} }; // Create a FrozenRows instance const frozenRows = new FrozenRows(mockTable); // Mock the refreshData method frozenRows.refreshData = jest.fn(); // Create a mock row element with parent node const mockRowElement = document.createElement('div'); const parentNode = document.createElement('div'); parentNode.appendChild(mockRowElement); // Create a mock row that is already frozen const mockRow = { modules: { frozen: true }, getElement: jest.fn().mockReturnValue(mockRowElement) }; // Clear the rows array so we don't have any frozen rows after detaching frozenRows.rows = []; // Mock console.warn const originalWarn = console.warn; console.warn = jest.fn(); // Mock the detachRow method to empty the rows array frozenRows.detachRow = jest.fn().mockImplementation(() => { frozenRows.rows = []; // Simulate row removal }); frozenRows.styleRows = jest.fn(); // Add the row to be unfrozen frozenRows.rows = [mockRow]; // Unfreeze the row frozenRows.unfreezeRow(mockRow); // Check that the row was properly unfrozen expect(mockRow.modules.frozen).toBe(false); expect(frozenRows.detachRow).toHaveBeenCalledWith(mockRow); expect(frozenRows.refreshData).toHaveBeenCalledWith(false, "display"); expect(mockTable.rowManager.adjustTableSize).toHaveBeenCalled(); // Since rows array is empty after detaching, styleRows should not be called expect(frozenRows.styleRows).not.toHaveBeenCalled(); // Try to unfreeze a row that's not frozen const notFrozenRow = { modules: { frozen: false } }; frozenRows.unfreezeRow(notFrozenRow); // Should show warning expect(console.warn).toHaveBeenCalledWith("Freeze Error - Row is already unfrozen"); // Add back a frozen row and test styleRows is called const anotherRow = { modules: { frozen: true }, getElement: jest.fn().mockReturnValue(document.createElement('div')) }; // Mock the rows array to be non-empty after detaching frozenRows.detachRow.mockImplementationOnce(() => { frozenRows.rows = [{ id: "dummy" }]; // Leave a row in the array }); frozenRows.rows.push(anotherRow); frozenRows.styleRows.mockClear(); frozenRows.unfreezeRow(anotherRow); // With remaining frozen rows, styleRows should have been called expect(frozenRows.styleRows).toHaveBeenCalled(); // Restore console.warn console.warn = originalWarn; }); test('detachRow removes row from frozen rows array', function(){ // Create a FrozenRows instance with minimal mock const frozenRows = new FrozenRows({}); // Create a mock row element with parent const mockRowElement = document.createElement('div'); const parentNode = document.createElement('div'); parentNode.appendChild(mockRowElement); // Create a mock row const mockRow = { getElement: jest.fn().mockReturnValue(mockRowElement) }; // Add the row to the frozen rows frozenRows.rows = [mockRow]; // Call detachRow frozenRows.detachRow(mockRow); // Row should be removed from rows array expect(frozenRows.rows).not.toContain(mockRow); expect(frozenRows.rows.length).toBe(0); // Element should be removed from DOM expect(mockRowElement.parentNode).toBeNull(); // Test with row not in array const notIncludedRow = { getElement: jest.fn().mockReturnValue(document.createElement('div')) }; frozenRows.detachRow(notIncludedRow); // Should not throw error, no change to rows array expect(frozenRows.rows.length).toBe(0); }); test('isRowFrozen checks if row is in frozen rows array', function(){ // Create a FrozenRows instance with minimal mock const frozenRows = new FrozenRows({}); // Create mock rows const frozenRow = { id: 1 }; const notFrozenRow = { id: 2 }; // Add one row to the frozen rows frozenRows.rows = [frozenRow]; // Check frozen row expect(frozenRows.isRowFrozen(frozenRow)).toBe(true); // Check non-frozen row expect(frozenRows.isRowFrozen(notFrozenRow)).toBe(false); }); test('isFrozen checks if there are any frozen rows', function(){ // Create a FrozenRows instance with minimal mock const frozenRows = new FrozenRows({}); // No frozen rows frozenRows.rows = []; expect(frozenRows.isFrozen()).toBe(false); // With frozen rows frozenRows.rows = [{ id: 1 }]; expect(frozenRows.isFrozen()).toBe(true); }); test('getRows filters frozen rows from input array', function(){ // Create a FrozenRows instance with minimal mock const frozenRows = new FrozenRows({}); // Create mock rows const row1 = { id: 1 }; const row2 = { id: 2 }; const row3 = { id: 3 }; const row4 = { id: 4 }; // Set frozen rows frozenRows.rows = [row2, row4]; // Test filtering const inputRows = [row1, row2, row3, row4]; const result = frozenRows.getRows(inputRows); // Should contain only non-frozen rows expect(result).toEqual([row1, row3]); // Original array should not be modified expect(inputRows).toEqual([row1, row2, row3, row4]); }); test('visibleRows adds frozen rows to visible rows array', function(){ // Create a FrozenRows instance with minimal mock const frozenRows = new FrozenRows({}); // Create mock rows const frozenRow1 = { id: 1 }; const frozenRow2 = { id: 2 }; const normalRow = { id: 3 }; // Set frozen rows frozenRows.rows = [frozenRow1, frozenRow2]; // Test adding to visible rows const visibleRows = [normalRow]; const result = frozenRows.visibleRows(true, visibleRows); // Should contain both frozen and normal rows expect(result).toEqual([normalRow, frozenRow1, frozenRow2]); // Original array should be modified (this is expected behavior of the method) expect(visibleRows).toEqual([normalRow, frozenRow1, frozenRow2]); }); test('initializeRow correctly handles different frozenRows options', function(){ // Create a mock table const mockTable = { options: { frozenRows: 2 // Number option } }; // Create a FrozenRows instance const frozenRows = new FrozenRows(mockTable); frozenRows.freezeRow = jest.fn(); frozenRows.options = jest.fn().mockReturnValue("id"); // Test with numeric frozenRows option // Row position <= frozenRows value const row1 = { getPosition: jest.fn().mockReturnValue(1), getComponent: jest.fn() }; frozenRows.initializeRow(row1); expect(frozenRows.freezeRow).toHaveBeenCalledWith(row1); frozenRows.freezeRow.mockClear(); // Row position > frozenRows value const row3 = { getPosition: jest.fn().mockReturnValue(3), getComponent: jest.fn() }; frozenRows.initializeRow(row3); expect(frozenRows.freezeRow).not.toHaveBeenCalled(); // Test with function frozenRows option mockTable.options.frozenRows = jest.fn().mockImplementation(row => row.id === 2); const row2 = { id: 2, getComponent: jest.fn().mockReturnValue({ id: 2 }) }; frozenRows.initializeRow(row2); expect(mockTable.options.frozenRows).toHaveBeenCalledWith(row2.getComponent()); expect(frozenRows.freezeRow).toHaveBeenCalledWith(row2); frozenRows.freezeRow.mockClear(); mockTable.options.frozenRows.mockClear(); // Row that doesn't match function condition const row4 = { id: 4, getComponent: jest.fn().mockReturnValue({ id: 4 }) }; frozenRows.initializeRow(row4); expect(mockTable.options.frozenRows).toHaveBeenCalledWith(row4.getComponent()); expect(frozenRows.freezeRow).not.toHaveBeenCalled(); // Test with array frozenRows option mockTable.options.frozenRows = [1, 5, 7]; // Row with matching ID const rowMatch = { data: { id: 5 } }; frozenRows.initializeRow(rowMatch); expect(frozenRows.freezeRow).toHaveBeenCalledWith(rowMatch); frozenRows.freezeRow.mockClear(); // Row with non-matching ID const rowNoMatch = { data: { id: 2 } }; frozenRows.initializeRow(rowNoMatch); expect(frozenRows.freezeRow).not.toHaveBeenCalled(); }); }); });