734 lines
20 KiB
TypeScript
734 lines
20 KiB
TypeScript
import HotTable from '../src/HotTable.vue';
|
|
import BaseEditorComponent from '../src/BaseEditorComponent.vue';
|
|
import { HOT_DESTROYED_WARNING } from '../src/helpers';
|
|
import { mount } from '@vue/test-utils';
|
|
import {
|
|
createDomContainer,
|
|
createSampleData,
|
|
mockClientDimensions
|
|
} from './_helpers';
|
|
import { LRUMap } from "../src/lib/lru/lru";
|
|
import Vue from 'vue';
|
|
|
|
describe('hotInit', () => {
|
|
it('should initialize Handsontable and assign it to the `hotInstace` property of the provided object', () => {
|
|
let testWrapper = mount(HotTable, {
|
|
propsData: {
|
|
data: createSampleData(1, 1),
|
|
licenseKey: 'non-commercial-and-evaluation'
|
|
}
|
|
});
|
|
|
|
expect(typeof testWrapper.vm.hotInstance).toEqual('object');
|
|
expect(testWrapper.vm.hotInstance.getDataAtCell(0, 0)).toEqual('0-0');
|
|
});
|
|
});
|
|
|
|
describe('Updating the Handsontable settings', () => {
|
|
it('should update the previously initialized Handsontable instance with a single changed property', async() => {
|
|
let updateSettingsCalls = 0;
|
|
const testWrapper = mount(HotTable, {
|
|
propsData: {
|
|
data: createSampleData(1, 1),
|
|
licenseKey: 'non-commercial-and-evaluation',
|
|
rowHeaders: true,
|
|
afterUpdateSettings: function () {
|
|
updateSettingsCalls++;
|
|
}
|
|
}
|
|
});
|
|
|
|
expect(testWrapper.vm.hotInstance.getSettings().rowHeaders).toEqual(true);
|
|
|
|
testWrapper.setProps({
|
|
rowHeaders: false
|
|
});
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(updateSettingsCalls).toEqual(1);
|
|
expect(testWrapper.vm.hotInstance.getSettings().rowHeaders).toEqual(false);
|
|
});
|
|
|
|
it('should update the previously initialized Handsontable instance only once with multiple changed properties', async() => {
|
|
const initialAfterChangeHook = () => { /* initial hook */ };
|
|
const modifiedAfterChangeHook = () => { /* modified hook */ };
|
|
const App = Vue.extend({
|
|
data: function () {
|
|
return {
|
|
rowHeaders: true,
|
|
colHeaders: true,
|
|
readOnly: true,
|
|
afterChange: initialAfterChangeHook
|
|
}
|
|
},
|
|
methods: {
|
|
updateData: function () {
|
|
this.rowHeaders = false;
|
|
this.colHeaders = false;
|
|
this.readOnly = false;
|
|
this.afterChange = modifiedAfterChangeHook;
|
|
}
|
|
},
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
ref: 'hotInstance',
|
|
props: {
|
|
rowHeaders: this.rowHeaders,
|
|
colHeaders: this.colHeaders,
|
|
readOnly: this.readOnly,
|
|
afterChange: this.afterChange,
|
|
afterUpdateSettings: function () {
|
|
updateSettingsCalls++;
|
|
}
|
|
}
|
|
})
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
sync: false
|
|
});
|
|
|
|
let updateSettingsCalls = 0;
|
|
|
|
const hotTableComponent = testWrapper.vm.$children[0];
|
|
|
|
expect(hotTableComponent.hotInstance.getSettings().rowHeaders).toEqual(true);
|
|
expect(hotTableComponent.hotInstance.getSettings().colHeaders).toEqual(true);
|
|
expect(hotTableComponent.hotInstance.getSettings().readOnly).toEqual(true);
|
|
|
|
const hooks = hotTableComponent.hotInstance.pluginHookBucket.getHooks('afterChange');
|
|
|
|
expect(hooks.filter(hookEntry => hookEntry.callback === initialAfterChangeHook).length).toBe(1);
|
|
expect(hooks.filter(hookEntry => hookEntry.callback === modifiedAfterChangeHook).length).toBe(0);
|
|
|
|
testWrapper.vm.updateData();
|
|
|
|
await Vue.nextTick();
|
|
expect(updateSettingsCalls).toEqual(1);
|
|
expect(hotTableComponent.hotInstance.getSettings().rowHeaders).toEqual(false);
|
|
expect(hotTableComponent.hotInstance.getSettings().colHeaders).toEqual(false);
|
|
expect(hotTableComponent.hotInstance.getSettings().readOnly).toEqual(false);
|
|
expect(hooks.filter(hookEntry => hookEntry.callback === initialAfterChangeHook).length).toBe(0);
|
|
expect(hooks.filter(hookEntry => hookEntry.callback === modifiedAfterChangeHook).length).toBe(1);
|
|
});
|
|
|
|
it('should update the previously initialized Handsontable instance with only the options that are passed to the' +
|
|
' component as props and actually changed', async() => {
|
|
let newHotSettings = null;
|
|
let App = Vue.extend({
|
|
data: function () {
|
|
return {
|
|
rowHeaders: true,
|
|
colHeaders: true,
|
|
readOnly: true,
|
|
}
|
|
},
|
|
methods: {
|
|
updateData: function () {
|
|
this.rowHeaders = false;
|
|
this.colHeaders = false;
|
|
this.readOnly = false;
|
|
}
|
|
},
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
ref: 'hotInstance',
|
|
props: {
|
|
rowHeaders: this.rowHeaders,
|
|
colHeaders: this.colHeaders,
|
|
readOnly: this.readOnly,
|
|
minSpareRows: 4,
|
|
afterUpdateSettings: function (newSettings) {
|
|
newHotSettings = newSettings
|
|
}
|
|
}
|
|
})
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
sync: false
|
|
});
|
|
|
|
testWrapper.vm.updateData();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(Object.keys(newHotSettings).length).toBe(3)
|
|
});
|
|
|
|
it('should not call Handsontable\'s `updateSettings` method, when the table data was changed by reference, and the' +
|
|
' dataset is an array of arrays', async() => {
|
|
let newHotSettings = null;
|
|
let App = Vue.extend({
|
|
data: function () {
|
|
return {
|
|
data: [[1, 2, 3]],
|
|
}
|
|
},
|
|
methods: {
|
|
modifyFirstRow: function () {
|
|
Vue.set(this.data, 0, [22, 32, 42]);
|
|
},
|
|
addRow: function () {
|
|
this.data.push([2, 3, 4]);
|
|
},
|
|
removeRow: function () {
|
|
this.data.pop()
|
|
},
|
|
},
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
ref: 'hotInstance',
|
|
props: {
|
|
data: this.data,
|
|
afterUpdateSettings: function (newSettings) {
|
|
newHotSettings = newSettings
|
|
}
|
|
}
|
|
})
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
sync: false
|
|
});
|
|
|
|
testWrapper.vm.addRow();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([[1, 2, 3], [2, 3, 4]]);
|
|
expect(newHotSettings).toBe(null);
|
|
|
|
testWrapper.vm.removeRow();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([[1, 2, 3]]);
|
|
expect(newHotSettings).toBe(null);
|
|
|
|
testWrapper.vm.modifyFirstRow();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([[22, 32, 42]]);
|
|
expect(newHotSettings).toBe(null);
|
|
|
|
testWrapper.vm.removeRow();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([]);
|
|
expect(newHotSettings).toBe(null);
|
|
});
|
|
|
|
it('should call Handsontable\'s `updateSettings` method, when the table data was changed by reference while the' +
|
|
' dataset is an array of object and property number changed', async() => {
|
|
let newHotSettings = null;
|
|
let App = Vue.extend({
|
|
data: function () {
|
|
return {
|
|
data: [{a: 1, b: 2, c: 3}],
|
|
}
|
|
},
|
|
methods: {
|
|
updateData: function (changedRow) {
|
|
Vue.set(this.data, 0, Object.assign({}, changedRow));
|
|
}
|
|
},
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
ref: 'hotInstance',
|
|
props: {
|
|
data: this.data,
|
|
afterUpdateSettings: function (newSettings) {
|
|
newHotSettings = newSettings
|
|
}
|
|
}
|
|
})
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
sync: false
|
|
});
|
|
|
|
testWrapper.vm.updateData({a: 1, b: 2, c: 3, d: 4});
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([[1, 2, 3, 4]]);
|
|
expect(JSON.stringify(newHotSettings)).toBe(JSON.stringify({
|
|
data: [{a: 1, b: 2, c: 3, d: 4}]
|
|
}));
|
|
|
|
testWrapper.vm.updateData({a: 1});
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([[1]]);
|
|
expect(JSON.stringify(newHotSettings)).toBe(JSON.stringify({
|
|
data: [{a: 1}]
|
|
}));
|
|
});
|
|
|
|
it('should NOT call Handsontable\'s `updateSettings` method, when the table data was changed by reference while the' +
|
|
' dataset is an array of object and property number DID NOT change', async() => {
|
|
let newHotSettings = null;
|
|
let App = Vue.extend({
|
|
data: function () {
|
|
return {
|
|
data: [{a: 1, b: 2, c: 3}],
|
|
}
|
|
},
|
|
methods: {
|
|
addRow: function () {
|
|
this.data.push({a: 12, b: 22, c: 32})
|
|
},
|
|
removeRow: function () {
|
|
this.data.pop()
|
|
}
|
|
},
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
ref: 'hotInstance',
|
|
props: {
|
|
data: this.data,
|
|
afterUpdateSettings: function (newSettings) {
|
|
newHotSettings = newSettings
|
|
}
|
|
}
|
|
})
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
sync: false
|
|
});
|
|
|
|
testWrapper.vm.addRow();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([[1, 2, 3], [12, 22, 32]]);
|
|
expect(newHotSettings).toBe(null);
|
|
|
|
testWrapper.vm.removeRow();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(testWrapper.vm.$children[0].hotInstance.getData()).toEqual([[1, 2, 3]]);
|
|
expect(newHotSettings).toBe(null);
|
|
});
|
|
});
|
|
|
|
describe('getRendererWrapper', () => {
|
|
it('should create the wrapper function for the provided renderer child component', () => {
|
|
// mocks
|
|
const mockVNode = {
|
|
componentOptions: {
|
|
Ctor: class {
|
|
$mount() {
|
|
return {
|
|
$data: {},
|
|
$el: document.createElement('TD')
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const mockComponent = {
|
|
editorCache: new Map(),
|
|
rendererCache: new LRUMap(100),
|
|
$parent: {}
|
|
};
|
|
|
|
const getRendererWrapper = (HotTable as any).methods.getRendererWrapper;
|
|
const mockTD = document.createElement('TD');
|
|
|
|
expect(typeof getRendererWrapper.call(mockComponent, mockVNode, mockComponent)).toEqual('function');
|
|
expect(getRendererWrapper.call(mockComponent, mockVNode, mockComponent)({}, mockTD, 0, 0, 0, '', {})).toEqual(mockTD);
|
|
});
|
|
});
|
|
|
|
describe('getEditorClass', () => {
|
|
it('should create a fresh class to be used as an editor, based on the editor component provided.', () => {
|
|
// mocks
|
|
const mockVNode = {
|
|
componentOptions: {
|
|
Ctor: class {
|
|
static get options() {
|
|
return {
|
|
name: 'name'
|
|
};
|
|
}
|
|
|
|
$mount() {
|
|
return {
|
|
$data: {
|
|
hotCustomEditorClass: class B {
|
|
prepare() {
|
|
return 'not-undefined';
|
|
}
|
|
}
|
|
},
|
|
$el: document.createElement('TD')
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const mockComponent = {
|
|
editorCache: new Map(),
|
|
rendererCache: new LRUMap(100),
|
|
$parent: {}
|
|
};
|
|
|
|
const getEditorClass = (HotTable as any).methods.getEditorClass;
|
|
const editorClass = getEditorClass.call(mockComponent, mockVNode, mockComponent);
|
|
|
|
expect(editorClass.constructor).not.toEqual(void 0);
|
|
expect(editorClass.prototype.prepare).not.toEqual(void 0);
|
|
});
|
|
});
|
|
|
|
describe('Global editors and renderers', () => {
|
|
it('should allow defining renderer and editor components to work globally on the entire table', () => {
|
|
const dummyHtmlElement = document.createElement('DIV');
|
|
dummyHtmlElement.id = 'dummy';
|
|
|
|
const dummyEditorComponent = Vue.component('renderer-component', {
|
|
name: 'EditorComponent',
|
|
extends: BaseEditorComponent,
|
|
render: function (h) {
|
|
return h('div', {
|
|
'attrs': {
|
|
'id': 'dummy-editor'
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
const dummyRendererComponent = Vue.component('renderer-component', {
|
|
name: 'RendererComponent',
|
|
render: function (h) {
|
|
return h('div', {
|
|
'attrs': {
|
|
'id': 'dummy-renderer'
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
let App = Vue.extend({
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
props: {
|
|
data: createSampleData(50, 2),
|
|
autoRowSize: false,
|
|
autoColumnSize: false,
|
|
width: 400,
|
|
height: 400,
|
|
init: function () {
|
|
mockClientDimensions(this.rootElement, 400, 400);
|
|
}
|
|
}
|
|
}, [
|
|
h(dummyRendererComponent, {
|
|
attrs: {
|
|
'hot-renderer': true
|
|
}
|
|
}),
|
|
h(dummyEditorComponent, {
|
|
attrs: {
|
|
'hot-editor': true
|
|
}
|
|
})
|
|
])
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
attachTo: createDomContainer()
|
|
});
|
|
const hotTableComponent = testWrapper.vm.$children[0];
|
|
const globalEditor = hotTableComponent.hotInstance.getSettings().editor;
|
|
const globalEditorInstance = new globalEditor(hotTableComponent.hotInstance);
|
|
|
|
expect(globalEditorInstance._fullEditMode).toEqual(false);
|
|
expect(globalEditorInstance.hot).toEqual(hotTableComponent.hotInstance);
|
|
expect(hotTableComponent.hotInstance.getSettings().renderer(hotTableComponent.hotInstance, document.createElement('DIV'), 555, 0, 0, '0', {}).childNodes[0].id).toEqual('dummy-renderer');
|
|
|
|
testWrapper.destroy();
|
|
});
|
|
});
|
|
|
|
it('should inject an `isRenderer` and `isEditor` properties to renderer/editor components', () => {
|
|
const dummyEditorComponent = Vue.component('renderer-component', {
|
|
name: 'EditorComponent',
|
|
extends: BaseEditorComponent,
|
|
render: function (h) {
|
|
return h('div', {
|
|
'attrs': {
|
|
'id': 'dummy-editor'
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
const dummyRendererComponent = Vue.component('renderer-component', {
|
|
name: 'RendererComponent',
|
|
render: function (h) {
|
|
return h('div', {
|
|
'attrs': {
|
|
'id': 'dummy-renderer'
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
let App = Vue.extend({
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
props: {
|
|
data: createSampleData(50, 2),
|
|
licenseKey: 'non-commercial-and-evaluation',
|
|
autoRowSize: false,
|
|
autoColumnSize: false
|
|
}
|
|
}, [
|
|
h(dummyRendererComponent, {
|
|
attrs: {
|
|
'hot-renderer': true
|
|
}
|
|
}),
|
|
h(dummyEditorComponent, {
|
|
attrs: {
|
|
'hot-editor': true
|
|
}
|
|
})
|
|
])
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
attachTo: createDomContainer()
|
|
});
|
|
const hotTableComponent = testWrapper.vm.$children[0];
|
|
|
|
expect(hotTableComponent.$data.rendererCache.get('0-0').component.$data.isRenderer).toEqual(true);
|
|
expect(hotTableComponent.$data.editorCache.get('EditorComponent').$data.isEditor).toEqual(true);
|
|
|
|
testWrapper.destroy();
|
|
});
|
|
|
|
it('should be possible to access the `hotInstance` property of the HotTable instance from a parent-component', () => {
|
|
let hotInstanceFromRef = 'not-set';
|
|
let App = Vue.extend({
|
|
data: function () {
|
|
return {
|
|
rowHeaders: true,
|
|
colHeaders: true,
|
|
readOnly: true,
|
|
}
|
|
},
|
|
methods: {
|
|
cellsCallback: function() {
|
|
if (hotInstanceFromRef === 'not-set') {
|
|
hotInstanceFromRef = this.$refs.hTable.hotInstance;
|
|
}
|
|
}
|
|
},
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
ref: 'hTable',
|
|
props: {
|
|
rowHeaders: this.rowHeaders,
|
|
colHeaders: this.colHeaders,
|
|
readOnly: this.readOnly,
|
|
cells: this.cellsCallback
|
|
}
|
|
})
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
attachTo: createDomContainer()
|
|
});
|
|
|
|
expect(['not-set', null].includes(hotInstanceFromRef)).toBe(false);
|
|
|
|
testWrapper.destroy();
|
|
});
|
|
|
|
it('should be possible to pass props to the editor and renderer components', () => {
|
|
const dummyEditorComponent = Vue.component('renderer-component', {
|
|
name: 'EditorComponent',
|
|
extends: BaseEditorComponent,
|
|
props: ['test-prop'],
|
|
render: function (h) {
|
|
return h('div', {});
|
|
}
|
|
});
|
|
|
|
const dummyRendererComponent = Vue.component('renderer-component', {
|
|
name: 'RendererComponent',
|
|
props: ['test-prop'],
|
|
render: function (h) {
|
|
return h('div', {});
|
|
}
|
|
});
|
|
|
|
let App = Vue.extend({
|
|
render(h) {
|
|
// HotTable
|
|
return h(HotTable, {
|
|
props: {
|
|
data: createSampleData(1, 1),
|
|
licenseKey: 'non-commercial-and-evaluation',
|
|
}
|
|
}, [
|
|
h(dummyRendererComponent, {
|
|
attrs: {
|
|
'hot-renderer': true,
|
|
'test-prop': 'test-prop-value'
|
|
}
|
|
}),
|
|
h(dummyEditorComponent, {
|
|
attrs: {
|
|
'hot-editor': true,
|
|
'test-prop': 'test-prop-value'
|
|
}
|
|
})
|
|
])
|
|
}
|
|
});
|
|
|
|
let testWrapper = mount(App, {
|
|
attachTo: createDomContainer()
|
|
});
|
|
const hotTableComponent = testWrapper.vm.$children[0];
|
|
|
|
expect(hotTableComponent.rendererCache.get('0-0').component.$props.testProp).toEqual('test-prop-value');
|
|
expect(hotTableComponent.editorCache.get('EditorComponent').$props.testProp).toEqual('test-prop-value');
|
|
|
|
testWrapper.destroy();
|
|
});
|
|
|
|
it('should display a warning and not throw any errors, when the underlying Handsontable instance ' +
|
|
'has been destroyed', () => {
|
|
const warnFunc = console.warn;
|
|
const testWrapper = mount(HotTable, {
|
|
propsData: {
|
|
data: [[1]],
|
|
licenseKey: 'non-commercial-and-evaluation',
|
|
}
|
|
});
|
|
const warnCalls = [];
|
|
|
|
console.warn = (warningMessage) => {
|
|
warnCalls.push(warningMessage);
|
|
}
|
|
|
|
expect(testWrapper.vm.hotInstance.isDestroyed).toEqual(false);
|
|
|
|
testWrapper.vm.hotInstance.destroy();
|
|
|
|
expect(testWrapper.vm.hotInstance).toEqual(null);
|
|
|
|
expect(warnCalls.length).toBeGreaterThan(0);
|
|
warnCalls.forEach((message) => {
|
|
expect(message).toEqual(HOT_DESTROYED_WARNING);
|
|
});
|
|
|
|
testWrapper.destroy();
|
|
|
|
console.warn = warnFunc;
|
|
});
|
|
|
|
describe('HOT-based CRUD actions', () => {
|
|
it('should should not add/remove any additional rows when calling `alter` on the HOT instance', async() => {
|
|
const testWrapper = mount(HotTable, {
|
|
propsData: {
|
|
data: createSampleData(4, 4),
|
|
rowHeaders: true,
|
|
colHeaders: true,
|
|
}
|
|
});
|
|
const hotInstance = testWrapper.vm.hotInstance;
|
|
|
|
hotInstance.alter('insert_row_above', 2, 2);
|
|
hotInstance.alter('insert_col_end', 2, 2);
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(hotInstance.countRows()).toEqual(6);
|
|
expect(hotInstance.countSourceRows()).toEqual(6);
|
|
expect(hotInstance.countCols()).toEqual(6);
|
|
expect(hotInstance.countSourceCols()).toEqual(6);
|
|
expect(hotInstance.getSourceData().length).toEqual(6);
|
|
expect(hotInstance.getSourceData()[0].length).toEqual(6);
|
|
|
|
hotInstance.alter('remove_row', 2, 2);
|
|
hotInstance.alter('remove_col', 2, 2);
|
|
|
|
expect(hotInstance.countRows()).toEqual(4);
|
|
expect(hotInstance.countSourceRows()).toEqual(4);
|
|
expect(hotInstance.countCols()).toEqual(4);
|
|
expect(hotInstance.countSourceCols()).toEqual(4);
|
|
expect(hotInstance.getSourceData().length).toEqual(4);
|
|
expect(hotInstance.getSourceData()[0].length).toEqual(4);
|
|
});
|
|
});
|
|
|
|
describe('Non-HOT based CRUD actions', () => {
|
|
it('should should not add/remove any additional rows when modifying a data array passed to the wrapper', async() => {
|
|
const externalData = createSampleData(4, 4);
|
|
const testWrapper = mount(HotTable, {
|
|
propsData: {
|
|
data: externalData,
|
|
rowHeaders: true,
|
|
colHeaders: true,
|
|
}
|
|
});
|
|
const hotInstance = testWrapper.vm.hotInstance;
|
|
|
|
externalData.push(externalData[0], externalData[0]);
|
|
externalData[0].push('test', 'test');
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(hotInstance.countRows()).toEqual(6);
|
|
expect(hotInstance.countSourceRows()).toEqual(6);
|
|
expect(hotInstance.countCols()).toEqual(6);
|
|
expect(hotInstance.countSourceCols()).toEqual(6);
|
|
expect(hotInstance.getSourceData().length).toEqual(6);
|
|
expect(hotInstance.getSourceData()[0].length).toEqual(6);
|
|
|
|
externalData.pop();
|
|
externalData.pop();
|
|
externalData[0].pop();
|
|
externalData[0].pop();
|
|
|
|
await Vue.nextTick();
|
|
|
|
expect(hotInstance.countRows()).toEqual(4);
|
|
expect(hotInstance.countSourceRows()).toEqual(4);
|
|
expect(hotInstance.countCols()).toEqual(4);
|
|
expect(hotInstance.countSourceCols()).toEqual(4);
|
|
expect(hotInstance.getSourceData().length).toEqual(4);
|
|
expect(hotInstance.getSourceData()[0].length).toEqual(4);
|
|
});
|
|
});
|