| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633 |
- describe('Core_loadData', () => {
- var id = 'testContainer';
- beforeEach(function() {
- this.$container = $(`<div id="${id}"></div>`).appendTo('body');
- });
- afterEach(function() {
- if (this.$container) {
- destroy();
- this.$container.remove();
- }
- });
- var arrayOfArrays = function() {
- return [
- ['', 'Kia', 'Nissan', 'Toyota', 'Honda'],
- ['2008', 10, 11, 12, 13],
- ['2009', 20, 11, 14, 13],
- ['2010', 30, 15, 12, 13]
- ];
- };
- var arrayOfObjects = function() {
- return [
- {id: 1, name: 'Ted', lastName: 'Right'},
- {id: 2, name: 'Frank', lastName: 'Honest'},
- {id: 3, name: 'Joan', lastName: 'Well'},
- {id: 4, name: 'Sid', lastName: 'Strong'},
- {id: 5, name: 'Jane', lastName: 'Neat'},
- {id: 6, name: 'Chuck', lastName: 'Jackson'},
- {id: 7, name: 'Meg', lastName: 'Jansen'},
- {id: 8, name: 'Rob', lastName: 'Norris'},
- {id: 9, name: 'Sean', lastName: 'O\'Hara'},
- {id: 10, name: 'Eve', lastName: 'Branson'}
- ];
- };
- var arrayOfNestedObjects = function() {
- return [
- {
- id: 1,
- name: {
- first: 'Ted',
- last: 'Right'
- },
- 'full.street': 'Street I',
- },
- {
- id: 2,
- name: {
- first: 'Frank',
- last: 'Honest'
- },
- 'full.street': 'Street II',
- },
- {
- id: 3,
- name: {
- first: 'Joan',
- last: 'Well'
- },
- 'full.street': 'Street III',
- }
- ];
- };
- var htmlData = [
- ['<b>H&M</b>']
- ];
- it('should allow array of arrays', () => {
- handsontable();
- loadData(arrayOfArrays());
- expect(getDataAtCell(0, 2)).toEqual('Nissan');
- });
- it('should allow array of objects', () => {
- handsontable({
- columns: [
- {data: 'id'},
- {data: 'lastName'},
- {data: 'name'}
- ]
- });
- loadData(arrayOfObjects());
- expect(getDataAtCell(0, 2)).toEqual('Ted');
- });
- it('should allow array of objects when columns as a function', () => {
- handsontable({
- columns(column) {
- var colMeta = {};
- if (column === 0) {
- colMeta.data = 'id';
- } else if (column === 1) {
- colMeta.data = 'lastName';
- } else if (column === 2) {
- colMeta.data = 'name';
- } else {
- colMeta = null;
- }
- return colMeta;
- }
- });
- loadData(arrayOfObjects());
- expect(getDataAtCell(0, 2)).toEqual('Ted');
- });
- it('should allow array of nested objects', () => {
- handsontable({
- data: arrayOfNestedObjects(),
- colHeaders: true,
- columns: [
- {data: 'id'},
- {data: 'name.last'},
- {data: 'name.first'},
- {data: 'full.street'},
- ]
- });
- expect(getDataAtCell(0, 2)).toEqual('Ted');
- expect(getDataAtCell(1, 3)).toEqual('Street II');
- expect(getDataAtRowProp(2, 'full.street')).toEqual('Street III');
- });
- it('should allow array of nested objects when columns as a function', () => {
- handsontable({
- data: arrayOfNestedObjects(),
- colHeaders: true,
- columns(column) {
- var colMeta = {};
- if (column === 0) {
- colMeta.data = 'id';
- } else if (column === 1) {
- colMeta.data = 'name.last';
- } else if (column === 2) {
- colMeta.data = 'name.first';
- } else if (column === 3) {
- colMeta.data = 'full.street';
- } else {
- colMeta = null;
- }
- return colMeta;
- }
- });
- expect(getDataAtCell(0, 2)).toEqual('Ted');
- expect(getDataAtCell(1, 3)).toEqual('Street II');
- expect(getDataAtRowProp(2, 'full.street')).toEqual('Street III');
- });
- it('should figure out default column names for array of nested objects', () => {
- handsontable({
- data: arrayOfNestedObjects(),
- colHeaders: true
- });
- expect(getDataAtCell(0, 2)).toEqual('Right');
- });
- it('should trigger onChange callback when loaded array of arrays', () => {
- var called = false;
- handsontable({
- afterChange(changes, source) {
- if (source === 'loadData') {
- called = true;
- }
- }
- });
- loadData(arrayOfArrays());
- expect(called).toEqual(true);
- });
- it('should trigger onChange callback when loaded array of objects', () => {
- var called = false;
- handsontable({
- afterChange(changes, source) {
- if (source === 'loadData') {
- called = true;
- }
- }
- });
- loadData(arrayOfObjects());
- expect(called).toEqual(true);
- });
- it('should trigger onChange callback when loaded array of nested objects', () => {
- var called = false;
- handsontable({
- afterChange(changes, source) {
- if (source === 'loadData') {
- called = true;
- }
- }
- });
- loadData(arrayOfNestedObjects());
- expect(called).toEqual(true);
- });
- it('should create new rows for array of arrays (and respect minRows)', () => {
- handsontable({
- minRows: 20, // minRows should be respected
- data: arrayOfArrays()
- });
- expect(countRows()).toEqual(20); // TODO why this must be checked after render?
- });
- it('should create new rows for array of nested objects (and respect minRows)', () => {
- handsontable({
- minRows: 20, // minRows should be respected
- data: arrayOfNestedObjects()
- });
- expect(countRows()).toEqual(20); // TODO why this must be checked after render?
- });
- it('HTML special chars should be escaped by default', () => {
- handsontable();
- loadData(htmlData);
- expect(getCell(0, 0).innerHTML).toEqual('<b>H&M</b>');
- });
- it('should create as many rows as needed by array of objects', () => {
- handsontable({
- minRows: 6,
- data: arrayOfObjects()
- });
- expect(getCell(9, 1).innerHTML).toEqual('Eve');
- });
- // https://github.com/handsontable/handsontable/pull/233
- it('should not invoke the cells callback multiple times with the same row/col (without overlays)', () => {
- var cellsSpy = jasmine.createSpy('cellsSpy');
- handsontable({
- data: arrayOfNestedObjects(),
- colWidths: [90, 90, 90, 90],
- rowHeights: [23, 23, 23, 23],
- cells: cellsSpy
- });
- //
- expect(cellsSpy.calls.count()).toEqual(43);
- });
- it('should not invoke the cells callback multiple times with the same row/col (with overlays)', () => {
- var cellsSpy = jasmine.createSpy('cellsSpy');
- handsontable({
- data: arrayOfNestedObjects(),
- colHeaders: true,
- rowHeaders: true,
- colWidths: [90, 90, 90, 90],
- rowHeights: [90, 90, 90, 90],
- cells: cellsSpy
- });
- expect(cellsSpy.calls.count()).toEqual(56);
- });
- it('should remove grid rows if new data source has less of them', () => {
- var data1 = [
- ['a'],
- ['b'],
- ['c'],
- ['d'],
- ['e'],
- ['f'],
- ['g'],
- ['h']
- ];
- var data2 = [
- ['a'],
- ['b'],
- ['c'],
- ['d'],
- ['e']
- ];
- handsontable({
- data: data1,
- rowHeaders: true,
- colHeaders: true
- });
- selectCell(7, 0);
- loadData(data2);
- expect(countRows()).toBe(data2.length);
- expect(getSelected()).toEqual([4, 0, 4, 0]);
- });
- it('should remove grid rows if new data source has less of them (with minSpareRows)', () => {
- var data1 = [
- ['a'],
- ['b'],
- ['c'],
- ['d'],
- ['e'],
- ['f'],
- ['g'],
- ['h']
- ];
- var data2 = [
- ['a'],
- ['b'],
- ['c'],
- ['d'],
- ['e']
- ];
- handsontable({
- data: data1,
- minSpareCols: 1,
- minSpareRows: 1,
- rowHeaders: true,
- colHeaders: true
- });
- selectCell(8, 0);
- loadData(data2);
- expect(countRows()).toBe(6); // +1 because of minSpareRows
- expect(getSelected()).toEqual([5, 0, 5, 0]);
- });
- it('loading empty data should remove all rows', () => {
- var data1 = [
- ['a'],
- ['b'],
- ['c'],
- ['d'],
- ['e'],
- ['f'],
- ['g'],
- ['h']
- ];
- var data2 = [];
- handsontable({
- data: data1,
- rowHeaders: true,
- colHeaders: true
- });
- selectCell(7, 0);
- loadData(data2);
- expect(countRows()).toBe(0);
- expect(getSelected()).toBe(void 0);
- });
- it('should only have as many columns as in settings', () => {
- var data1 = arrayOfArrays();
- handsontable({
- data: data1,
- columns: [
- { data: 1 },
- { data: 3 }
- ]
- });
- expect(countCols()).toBe(2);
- });
- it('should only have as many columns as in settings when columns is a function', () => {
- var data1 = arrayOfArrays();
- handsontable({
- data: data1,
- columns(column) {
- var colMeta = {
- data: column
- };
- if ([1, 3].indexOf(column) < 0) {
- colMeta = null;
- }
- return colMeta;
- }
- });
- expect(countCols()).toBe(2);
- });
- it('should throw error when trying to load a string (constructor)', () => {
- var errors = 0;
- try {
- handsontable({
- data: 'string'
- });
- } catch (e) {
- errors++;
- }
- expect(errors).toBe(1);
- });
- it('should throw error when trying to load a string (loadData)', () => {
- var errors = 0;
- try {
- handsontable();
- loadData('string');
- } catch (e) {
- errors++;
- }
- expect(errors).toBe(1);
- });
- it('should load Backbone Collection as data source', () => {
- // code borrowed from demo/backbone.js
- var CarModel = Backbone.Model.extend({});
- var CarCollection = Backbone.Collection.extend({
- model: CarModel,
- // Backbone.Collection doesn't support `splice`, yet! Easy to add.
- splice: hackedSplice
- });
- var cars = new CarCollection();
- cars.add([
- {make: 'Dodge', model: 'Ram', year: 2012, weight: 6811},
- {make: 'Toyota', model: 'Camry', year: 2012, weight: 3190},
- {make: 'Smart', model: 'Fortwo', year: 2012, weight: 1808}
- ]);
- handsontable({
- data: cars,
- columns: [
- attr('make'),
- attr('model'),
- attr('year')
- ]
- });
- // use the "good" Collection methods to emulate Array.splice
- function hackedSplice(index, howMany /* model1, ... modelN */) {
- var args = _.toArray(arguments).slice(2).concat({at: index}),
- removed = this.models.slice(index, index + howMany);
- this.remove(removed).add.apply(this, args);
- return removed;
- }
- // normally, you'd get these from the server with .fetch()
- function attr(attr) {
- // this lets us remember `attr` for when when it is get/set
- return {
- data(car, value) {
- if (_.isUndefined(value)) {
- return car.get(attr);
- }
- car.set(attr, value);
- }
- };
- }
- expect(countRows()).toBe(3);
- });
- it('should load Backbone Collection as data source when columns is a function', () => {
- // code borrowed from demo/backbone.js
- var CarModel = Backbone.Model.extend({});
- var CarCollection = Backbone.Collection.extend({
- model: CarModel,
- // Backbone.Collection doesn't support `splice`, yet! Easy to add.
- splice: hackedSplice
- });
- var cars = new CarCollection();
- cars.add([
- {make: 'Dodge', model: 'Ram', year: 2012, weight: 6811},
- {make: 'Toyota', model: 'Camry', year: 2012, weight: 3190},
- {make: 'Smart', model: 'Fortwo', year: 2012, weight: 1808}
- ]);
- handsontable({
- data: cars,
- columns(column) {
- var colMeta = null;
- if (column === 0) {
- colMeta = attr('make');
- } else if (column === 1) {
- colMeta = attr('model');
- } else if (column === 2) {
- colMeta = attr('year');
- }
- return colMeta;
- }
- });
- // use the "good" Collection methods to emulate Array.splice
- function hackedSplice(index, howMany /* model1, ... modelN */) {
- var args = _.toArray(arguments).slice(2).concat({at: index}),
- removed = this.models.slice(index, index + howMany);
- this.remove(removed).add.apply(this, args);
- return removed;
- }
- // normally, you'd get these from the server with .fetch()
- function attr(attr) {
- // this lets us remember `attr` for when when it is get/set
- return {
- data(car, value) {
- if (_.isUndefined(value)) {
- return car.get(attr);
- }
- car.set(attr, value);
- }
- };
- }
- expect(countRows()).toBe(3);
- });
- it('should clear cell properties after loadData', () => {
- handsontable();
- loadData(arrayOfArrays());
- getCellMeta(0, 0).foo = 'bar';
- expect(getCellMeta(0, 0).foo).toEqual('bar');
- loadData(arrayOfArrays());
- expect(getCellMeta(0, 0).foo).toBeUndefined();
- });
- it('should clear cell properties after loadData, but before rendering new data', function() {
- handsontable();
- loadData(arrayOfArrays());
- getCellMeta(0, 0).valid = false;
- render();
- expect(this.$container.find('tbody tr:eq(0) td:eq(0)').hasClass('htInvalid')).toEqual(true);
- loadData(arrayOfArrays());
- expect(this.$container.find('tbody tr:eq(0) td:eq(0)').hasClass('htInvalid')).toEqual(false);
- });
- // https://github.com/handsontable/handsontable/issues/1700
- // can't edit anything after starting editing cell with no nested object
- it('should correct behave with cell with no nested object data source corresponding to column mapping', () => {
- var objectData = [
- {id: 1, user: {name: {first: 'Ted', last: 'Right'}}},
- {id: 2, user: {name: {}}},
- {id: 3}
- ];
- handsontable({
- data: objectData,
- columns: [
- {data: 'id'},
- {data: 'user.name.first'},
- {data: 'user.name.last'}
- ]
- });
- mouseDoubleClick(getCell(1, 1));
- document.activeElement.value = 'Harry';
- deselectCell();
- expect(objectData[1].user.name.first).toEqual('Harry');
- mouseDoubleClick(getCell(2, 1));
- document.activeElement.value = 'Barry';
- deselectCell();
- expect(objectData[2].user.name.first).toEqual('Barry');
- });
- it('should correct behave with cell with no nested object data source corresponding to column mapping when columns is a function', () => {
- var objectData = [
- {id: 1, user: {name: {first: 'Ted', last: 'Right'}}},
- {id: 2, user: {name: {}}},
- {id: 3}
- ];
- handsontable({
- data: objectData,
- columns(column) {
- var colMeta = null;
- if (column === 0) {
- colMeta = {data: 'id'};
- } else if (column === 1) {
- colMeta = {data: 'user.name.first'};
- } else if (column === 2) {
- colMeta = {data: 'user.name.last'};
- }
- return colMeta;
- }
- });
- mouseDoubleClick(getCell(1, 1));
- document.activeElement.value = 'Harry';
- deselectCell();
- expect(objectData[1].user.name.first).toEqual('Harry');
- mouseDoubleClick(getCell(2, 1));
- document.activeElement.value = 'Barry';
- deselectCell();
- expect(objectData[2].user.name.first).toEqual('Barry');
- });
- });
|