fac09f6ce5bed99db32650c83c5928984fdb71abd756b58843b62afedf278776cf11e3aba57044c376bd482b5b77cdcacbcad55f90649a90a9d3dc5bccfe20 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. describe('Core_dataSchema', () => {
  2. var id = 'testContainer';
  3. beforeEach(function() {
  4. this.$container = $(`<div id="${id}"></div>`).appendTo('body');
  5. });
  6. afterEach(function() {
  7. if (this.$container) {
  8. destroy();
  9. this.$container.remove();
  10. }
  11. });
  12. it('should be equal to `hot.getSchema()` when dataSchema is defined in settings (as object)', () => {
  13. var schema = {id: null, name: {first: null, last: null}, cars: [{brand: null}]},
  14. hot = handsontable({
  15. data: [],
  16. dataSchema: schema,
  17. minRows: 5,
  18. minCols: 4,
  19. colHeaders: ['ID', 'First Name', 'Last Name'],
  20. columns: [
  21. {data: 'id'},
  22. {data: 'name.first'},
  23. {data: 'name.last'}
  24. ],
  25. minSpareRows: 1
  26. });
  27. expect(JSON.stringify(hot.getSchema())).toEqual(JSON.stringify(schema));
  28. });
  29. it('should be equal to `hot.getSchema()` when dataSchema is defined in settings (as object) when columns is a function', () => {
  30. var schema = {id: null, name: {first: null, last: null}, cars: [{brand: null}]},
  31. hot = handsontable({
  32. data: [],
  33. dataSchema: schema,
  34. minRows: 5,
  35. minCols: 4,
  36. colHeaders: ['ID', 'First Name', 'Last Name'],
  37. columns(column) {
  38. var colMeta = {};
  39. if (column === 0) {
  40. colMeta.data = 'id';
  41. } else if (column === 1) {
  42. colMeta.data = 'name.first';
  43. } else if (column === 2) {
  44. colMeta.data = 'name.last';
  45. } else {
  46. colMeta = null;
  47. }
  48. return colMeta;
  49. },
  50. minSpareRows: 1
  51. });
  52. expect(JSON.stringify(hot.getSchema())).toEqual(JSON.stringify(schema));
  53. });
  54. it('should be equal to `hot.getSchema()` when dataSchema is defined in settings (as function)', () => {
  55. var schema = {id: null, name: {first: null, last: null}, cars: [{brand: null}]},
  56. hot = handsontable({
  57. data: [],
  58. dataSchema() {
  59. return schema;
  60. },
  61. minRows: 5,
  62. minCols: 4,
  63. colHeaders: ['ID', 'First Name', 'Last Name'],
  64. columns: [
  65. {data: 'id'},
  66. {data: 'name.first'},
  67. {data: 'name.last'}
  68. ],
  69. minSpareRows: 1
  70. });
  71. expect(JSON.stringify(hot.getSchema())).toEqual(JSON.stringify(schema));
  72. });
  73. it('should be equal to `hot.getSchema()` when dataSchema is defined in settings (as function) when columns is a function', () => {
  74. var schema = {id: null, name: {first: null, last: null}, cars: [{brand: null}]},
  75. hot = handsontable({
  76. data: [],
  77. dataSchema() {
  78. return schema;
  79. },
  80. minRows: 5,
  81. minCols: 4,
  82. colHeaders: ['ID', 'First Name', 'Last Name'],
  83. columns(column) {
  84. var colMeta = {};
  85. if (column === 0) {
  86. colMeta.data = 'id';
  87. } else if (column === 1) {
  88. colMeta.data = 'name.first';
  89. } else if (column === 2) {
  90. colMeta.data = 'name.last';
  91. } else {
  92. colMeta = null;
  93. }
  94. return colMeta;
  95. },
  96. minSpareRows: 1
  97. });
  98. expect(JSON.stringify(hot.getSchema())).toEqual(JSON.stringify(schema));
  99. });
  100. it('should be equal to `hot.getSchema()` when dataSchema is generated based on data structure', () => {
  101. var hot = handsontable({
  102. data: [
  103. {id: 1, name: {first: 'Alan', last: 'Pakoli'}, cars: [{brand: 'Ford'}]}
  104. ],
  105. minRows: 5,
  106. minCols: 4,
  107. colHeaders: ['ID', 'First Name', 'Last Name'],
  108. columns: [
  109. {data: 'id'},
  110. {data: 'name.first'},
  111. {data: 'name.last'}
  112. ],
  113. minSpareRows: 1
  114. });
  115. expect(JSON.stringify(hot.getSchema()))
  116. .toEqual(JSON.stringify({id: null, name: {first: null, last: null}, cars: [{brand: null}]}));
  117. });
  118. it('should be equal to `hot.getSchema()` when dataSchema is generated based on data structure when columns is a function', () => {
  119. var hot = handsontable({
  120. data: [
  121. {id: 1, name: {first: 'Alan', last: 'Pakoli'}, cars: [{brand: 'Ford'}]}
  122. ],
  123. minRows: 5,
  124. minCols: 4,
  125. colHeaders: ['ID', 'First Name', 'Last Name'],
  126. columns(column) {
  127. var colMeta = {};
  128. if (column === 0) {
  129. colMeta.data = 'id';
  130. } else if (column === 1) {
  131. colMeta.data = 'name.first';
  132. } else if (column === 2) {
  133. colMeta.data = 'name.last';
  134. } else {
  135. colMeta = null;
  136. }
  137. return colMeta;
  138. },
  139. minSpareRows: 1
  140. });
  141. expect(JSON.stringify(hot.getSchema()))
  142. .toEqual(JSON.stringify({id: null, name: {first: null, last: null}, cars: [{brand: null}]}));
  143. });
  144. it('should create new row from dataSchema', () => {
  145. handsontable({
  146. data: [],
  147. dataSchema: {id: null, name: {first: null, last: null}, address: null},
  148. minRows: 5,
  149. minCols: 4,
  150. colHeaders: ['ID', 'First Name', 'Last Name', 'Address'],
  151. columns: [
  152. {data: 'id'},
  153. {data: 'name.first'},
  154. {data: 'name.last'},
  155. {data: 'address'}
  156. ],
  157. minSpareRows: 1
  158. });
  159. selectCell(0, 1);
  160. keyDownUp('enter');
  161. keyProxy().val('Ted');
  162. keyDownUp('enter');
  163. expect(getData()[0][1]).toEqual('Ted');
  164. expect(getSourceData()[0].name.first).toEqual('Ted');
  165. });
  166. it('should create new row from dataSchema when columns is a function', () => {
  167. handsontable({
  168. data: [],
  169. dataSchema: {id: null, name: {first: null, last: null}, address: null},
  170. minRows: 5,
  171. minCols: 4,
  172. colHeaders: ['ID', 'First Name', 'Last Name', 'Address'],
  173. columns(column) {
  174. var colMeta = {};
  175. if (column === 0) {
  176. colMeta.data = 'id';
  177. } else if (column === 1) {
  178. colMeta.data = 'name.first';
  179. } else if (column === 2) {
  180. colMeta.data = 'name.last';
  181. } else if (column === 3) {
  182. colMeta.data = 'address';
  183. } else {
  184. colMeta = null;
  185. }
  186. return colMeta;
  187. },
  188. minSpareRows: 1
  189. });
  190. selectCell(0, 1);
  191. keyDownUp('enter');
  192. keyProxy().val('Ted');
  193. keyDownUp('enter');
  194. expect(getData()[0][1]).toEqual('Ted');
  195. expect(getSourceData()[0].name.first).toEqual('Ted');
  196. });
  197. it('should create new row from dataSchema (functional)', () => {
  198. handsontable({
  199. data: [],
  200. dataSchema(index) {
  201. return {id: 1000 + index, name: {first: null, last: null}, address: null};
  202. },
  203. isEmptyRow(r) {
  204. var row = this.getSourceData()[r];
  205. return (row.name.first === null || row.name.first === '') &&
  206. (row.name.last === null || row.name.last === '') &&
  207. (row.address === null || row.address === '');
  208. },
  209. minRows: 5,
  210. minCols: 4,
  211. colHeaders: ['ID', 'First Name', 'Last Name', 'Address'],
  212. columns: [
  213. {data: 'id'},
  214. {data: 'name.first'},
  215. {data: 'name.last'},
  216. {data: 'address'}
  217. ],
  218. minSpareRows: 1
  219. });
  220. selectCell(4, 1);
  221. expect(countRows()).toEqual(5);
  222. keyDownUp('enter');
  223. keyProxy().val('Ted');
  224. // need it in next frame as long as HT is rendered in async
  225. keyDownUp('enter');
  226. // need it in next frame as long as HT is rendered in async
  227. keyDownUp('enter');
  228. expect(getSourceData()[4].name.first).toEqual('Ted');
  229. expect(getSourceData()[4].id).toEqual(1004);
  230. expect(getData()[4][1]).toEqual('Ted');
  231. expect(getData()[4][0]).toEqual(1004);
  232. expect(countRows()).toEqual(6); // row should be added by keepEmptyRows
  233. });
  234. it('should create new row from dataSchema (functional) when columns is a function', () => {
  235. handsontable({
  236. data: [],
  237. dataSchema(index) {
  238. return {id: 1000 + index, name: {first: null, last: null}, address: null};
  239. },
  240. isEmptyRow(r) {
  241. var row = this.getSourceData()[r];
  242. return (row.name.first === null || row.name.first === '') &&
  243. (row.name.last === null || row.name.last === '') &&
  244. (row.address === null || row.address === '');
  245. },
  246. minRows: 5,
  247. minCols: 4,
  248. colHeaders: ['ID', 'First Name', 'Last Name', 'Address'],
  249. columns(column) {
  250. var colMeta = {};
  251. if (column === 0) {
  252. colMeta.data = 'id';
  253. } else if (column === 1) {
  254. colMeta.data = 'name.first';
  255. } else if (column === 2) {
  256. colMeta.data = 'name.last';
  257. } else if (column === 3) {
  258. colMeta.data = 'address';
  259. } else {
  260. colMeta = null;
  261. }
  262. return colMeta;
  263. },
  264. minSpareRows: 1
  265. });
  266. selectCell(4, 1);
  267. expect(countRows()).toEqual(5);
  268. keyDownUp('enter');
  269. keyProxy().val('Ted');
  270. // need it in next frame as long as HT is rendered in async
  271. keyDownUp('enter');
  272. // need it in next frame as long as HT is rendered in async
  273. keyDownUp('enter');
  274. expect(getSourceData()[4].name.first).toEqual('Ted');
  275. expect(getSourceData()[4].id).toEqual(1004);
  276. expect(getData()[4][1]).toEqual('Ted');
  277. expect(getData()[4][0]).toEqual(1004);
  278. expect(countRows()).toEqual(6); // row should be added by keepEmptyRows
  279. });
  280. it('should translate prop to col, when prop is a function', () => {
  281. var idAccessor = createAccessorForProperty('id');
  282. var nameAccessor = createAccessorForProperty('name');
  283. hot = handsontable({
  284. data: [
  285. Model({
  286. id: 1,
  287. name: 'Tom'
  288. }),
  289. Model({
  290. id: 2,
  291. name: 'Hanna'
  292. }),
  293. Model({
  294. id: 3,
  295. name: 'Jerry'
  296. })
  297. ],
  298. dataSchema: Model,
  299. columns: [
  300. {
  301. data: idAccessor
  302. },
  303. {
  304. data: nameAccessor
  305. }
  306. ]
  307. });
  308. expect(hot.propToCol(idAccessor)).toEqual(0);
  309. expect(hot.propToCol(nameAccessor)).toEqual(1);
  310. });
  311. it('should translate prop to col, when prop and columns is a function', () => {
  312. var idAccessor = createAccessorForProperty('id');
  313. var nameAccessor = createAccessorForProperty('name');
  314. hot = handsontable({
  315. data: [
  316. Model({
  317. id: 1,
  318. name: 'Tom'
  319. }),
  320. Model({
  321. id: 2,
  322. name: 'Hanna'
  323. }),
  324. Model({
  325. id: 3,
  326. name: 'Jerry'
  327. })
  328. ],
  329. dataSchema: Model,
  330. columns(column) {
  331. var colMeta = {};
  332. if (column === 0) {
  333. colMeta.data = idAccessor;
  334. } else if (column === 1) {
  335. colMeta.data = nameAccessor;
  336. } else {
  337. colMeta = null;
  338. }
  339. return colMeta;
  340. }
  341. });
  342. expect(hot.propToCol(idAccessor)).toEqual(0);
  343. expect(hot.propToCol(nameAccessor)).toEqual(1);
  344. });
  345. it('should create new row data matched to dataSchema (data type as `array`)', () => {
  346. var spy = jasmine.createSpy();
  347. var hot = handsontable({
  348. data: [[{id: 1}]],
  349. dataSchema: [{id: null}],
  350. columns: [
  351. {data: '0', renderer: spy}
  352. ],
  353. autoColumnSize: false,
  354. autoRowSize: false,
  355. });
  356. expect(spy.calls.count()).toBe(1);
  357. expect(spy.calls.argsFor(0)[5]).toEqual({id: 1});
  358. spy.calls.reset();
  359. hot.alter('insert_row', 0);
  360. expect(spy.calls.count()).toBe(2);
  361. expect(spy.calls.argsFor(0)[5]).toEqual({id: null});
  362. expect(spy.calls.argsFor(1)[5]).toEqual({id: 1});
  363. });
  364. it('should create new row data matched to dataSchema (data type as `array`) when columns is a function', () => {
  365. var spy = jasmine.createSpy();
  366. var hot = handsontable({
  367. data: [[{id: 1}]],
  368. dataSchema: [{id: null}],
  369. columns(column) {
  370. var colMeta = {};
  371. if (column === 0) {
  372. colMeta.data = '0';
  373. colMeta.renderer = spy;
  374. } else {
  375. colMeta = null;
  376. }
  377. return colMeta;
  378. },
  379. autoColumnSize: false,
  380. autoRowSize: false
  381. });
  382. expect(spy.calls.count()).toBe(1);
  383. expect(spy.calls.argsFor(0)[5]).toEqual({id: 1});
  384. spy.calls.reset();
  385. hot.alter('insert_row', 0);
  386. expect(spy.calls.count()).toBe(2);
  387. expect(spy.calls.argsFor(0)[5]).toEqual({id: null});
  388. expect(spy.calls.argsFor(1)[5]).toEqual({id: 1});
  389. });
  390. it('should create an array of objects as the source structure, when dataSchema is defined (as an object) but no data is provided', () => {
  391. var hot = handsontable({
  392. startCols: 2,
  393. minSpareRows: 4,
  394. dataSchema: {id: null, name: null, surname: null},
  395. });
  396. var dataAtRow = hot.getSourceDataAtRow(0);
  397. expect(Array.isArray(dataAtRow)).toBe(false);
  398. expect(dataAtRow.id).toEqual(null);
  399. expect(dataAtRow.name).toEqual(null);
  400. expect(dataAtRow.surname).toEqual(null);
  401. });
  402. it('should create an array of objects as the source structure, when dataSchema is defined (as a function) but no data is provided', () => {
  403. var hot = handsontable({
  404. startCols: 2,
  405. minSpareRows: 4,
  406. dataSchema() {
  407. return {id: null, name: null, surname: null};
  408. },
  409. });
  410. var dataAtRow = hot.getSourceDataAtRow(0);
  411. expect(Array.isArray(dataAtRow)).toBe(false);
  412. expect(dataAtRow.id).toEqual(null);
  413. expect(dataAtRow.name).toEqual(null);
  414. expect(dataAtRow.surname).toEqual(null);
  415. });
  416. it('should create an array of objects as the source structure, when dataSchema is defined (as an array with an object) but no data is provided', () => {
  417. var hot = handsontable({
  418. startCols: 2,
  419. minSpareRows: 4,
  420. dataSchema: [{id: null, name: null, surname: null}],
  421. });
  422. var dataAtRow = hot.getSourceDataAtRow(0);
  423. expect(Array.isArray(dataAtRow)).toBe(false);
  424. expect(dataAtRow.id).toEqual(null);
  425. expect(dataAtRow.name).toEqual(null);
  426. expect(dataAtRow.surname).toEqual(null);
  427. });
  428. });