3946c96858ebe9d9d2f3f0c4ba011cf119ad071682b3db051547b886ad12933277bda4c6e8220da5e89b8417c04f369891365067b1f31222a5170f56e56e86 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. 'use strict';
  2. describe('HandsontableObserveChanges', function () {
  3. var id = 'testContainer';
  4. beforeEach(function () {
  5. this.$container = $('<div id="' + id + '"></div>').appendTo('body');
  6. });
  7. afterEach(function () {
  8. if (this.$container) {
  9. destroy();
  10. this.$container.remove();
  11. }
  12. });
  13. function createHOT(data, observeChanges) {
  14. return handsontable({
  15. data: data,
  16. width: 200,
  17. height: 200,
  18. observeChanges: observeChanges
  19. });
  20. }
  21. describe('refreshing table after changes have been detected', function () {
  22. describe('array data', function () {
  23. it('should render newly added row', function (done) {
  24. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  25. var hot = createHOT(data, true);
  26. data.push(['A3', 'B3']);
  27. var htCore = getHtCore();
  28. setTimeout(function () {
  29. expect(htCore.find('tr').length).toEqual(3);
  30. expect(htCore.find('col').length).toEqual(2);
  31. done();
  32. }, 200);
  33. });
  34. it('should render newly added column', function (done) {
  35. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  36. var hot = createHOT(data, true);
  37. var htCore = getHtCore();
  38. data[0].push('C1');
  39. data[1].push('C2');
  40. setTimeout(function () {
  41. expect(htCore.find('tr').length).toEqual(2);
  42. expect(htCore.find('col').length).toEqual(3);
  43. done();
  44. }, 200);
  45. });
  46. it('should render removed row', function (done) {
  47. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  48. var hot = createHOT(data, true);
  49. var htCore = getHtCore();
  50. data.splice(0, 1); // removes one row at index 0
  51. setTimeout(function () {
  52. expect(htCore.find('tr').length).toEqual(1);
  53. expect(htCore.find('col').length).toEqual(2);
  54. done();
  55. }, 200);
  56. });
  57. it('should render removed column', function (done) {
  58. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  59. var hot = createHOT(data, true);
  60. var htCore = getHtCore();
  61. data[0].splice(0, 1); // removes one column at index 0 in first row
  62. data[1].splice(0, 1); // removes one column at index 0 in second row
  63. setTimeout(function () {
  64. expect(htCore.find('tr').length).toEqual(2);
  65. expect(htCore.find('col').length).toEqual(1);
  66. done();
  67. }, 200);
  68. });
  69. it('should render cell change from string to string', function (done) {
  70. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  71. var hot = createHOT(data, true);
  72. var htCore = getHtCore();
  73. data[0][0] = 'new string';
  74. setTimeout(function () {
  75. expect(htCore.find('td:eq(0)').html()).toEqual('new string');
  76. done();
  77. }, 200);
  78. });
  79. it('should render cell change in a new row', function (done) {
  80. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  81. var hot = createHOT(data, true);
  82. var htCore = getHtCore();
  83. data.push(['A3', 'B3']);
  84. setTimeout(function () {
  85. expect(htCore.find('tr:eq(2) td:eq(0)').html()).toEqual('A3');
  86. data[2][0] = 'new string';
  87. }, 200);
  88. setTimeout(function () {
  89. expect(htCore.find('tr:eq(2) td:eq(0)').html()).toEqual('new string');
  90. done();
  91. }, 1200);
  92. });
  93. it('should not render cell change when turned off (`observeChanges: false`)', function (done) {
  94. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  95. createHOT(data, false);
  96. var htCore = getHtCore();
  97. data[0][0] = 'new string';
  98. setTimeout(function () {
  99. expect(htCore.find('td:eq(0)').html()).toEqual('A1');
  100. done();
  101. }, 100);
  102. });
  103. });
  104. describe('object data', function () {
  105. it('should render newly added row', function (done) {
  106. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  107. var hot = createHOT(data, true);
  108. var htCore = getHtCore();
  109. data.push({ prop0: 'A3', prop1: 'B3' });
  110. setTimeout(function () {
  111. expect(htCore.find('tr').length).toEqual(3);
  112. expect(htCore.find('col').length).toEqual(2);
  113. done();
  114. }, 200);
  115. });
  116. it('should render removed row', function (done) {
  117. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  118. var hot = createHOT(data, true);
  119. var htCore = getHtCore();
  120. data.splice(0, 1); // removes one row at index 0
  121. setTimeout(function () {
  122. expect(htCore.find('tr').length).toEqual(1);
  123. expect(htCore.find('col').length).toEqual(2);
  124. done();
  125. }, 200);
  126. });
  127. it('should render cell change from string to string', function (done) {
  128. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  129. var hot = createHOT(data, true);
  130. var htCore = getHtCore();
  131. data[0].prop0 = 'new string';
  132. setTimeout(function () {
  133. expect(htCore.find('td:eq(0)').html()).toEqual('new string');
  134. done();
  135. }, 200);
  136. });
  137. it('should render cell change in a new row', function (done) {
  138. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  139. var hot = createHOT(data, true);
  140. var htCore = getHtCore();
  141. data.push({ prop0: 'A3', prop1: 'B3' });
  142. setTimeout(function () {
  143. expect(htCore.find('tr:eq(2) td:eq(0)').html()).toEqual('A3');
  144. data[2].prop0 = 'new string';
  145. }, 200);
  146. setTimeout(function () {
  147. expect(htCore.find('tr:eq(2) td:eq(0)').html()).toEqual('new string');
  148. done();
  149. }, 1200);
  150. });
  151. it('should not break with undefined data properties', function () {
  152. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  153. data[0].prop0 = undefined;
  154. expect(function () {
  155. var hot = createHOT(data, true);
  156. var htCore = getHtCore();
  157. }).not.toThrow();
  158. });
  159. it('should not render cell change when turned off (`observeChanges: false`)', function (done) {
  160. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  161. createHOT(data, false);
  162. var htCore = getHtCore();
  163. data[0].prop0 = 'new string';
  164. setTimeout(function () {
  165. expect(htCore.find('td:eq(0)').html()).toEqual('A1');
  166. done();
  167. }, 200);
  168. });
  169. });
  170. });
  171. describe('enabling/disabling plugin', function () {
  172. it('should be possible to enable plugin using updateSettings', function (done) {
  173. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  174. var hot = createHOT(data, false);
  175. var htCore = getHtCore();
  176. data[0][0] = 'new string';
  177. setTimeout(function () {
  178. expect(htCore.find('td:eq(0)').html()).toEqual('A1');
  179. updateSettings({
  180. observeChanges: true
  181. });
  182. data[1][0] = 'another new string';
  183. }, 200);
  184. setTimeout(function () {
  185. expect(htCore.find('tr:eq(1) td:eq(0)').html()).toEqual('another new string');
  186. done();
  187. }, 400);
  188. });
  189. it('should be possible to disable plugin using updateSettings', function (done) {
  190. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  191. var hot = createHOT(data, true);
  192. var htCore = getHtCore();
  193. data[0][0] = 'new string';
  194. setTimeout(function () {
  195. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('new string');
  196. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('A2');
  197. updateSettings({
  198. observeChanges: false
  199. });
  200. data[1][0] = 'another new string';
  201. }, 200);
  202. setTimeout(function () {
  203. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('new string');
  204. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('A2');
  205. hot.render();
  206. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('new string');
  207. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('another new string');
  208. done();
  209. }, 300);
  210. });
  211. it('should be possible to pause observing changes without disabling the plugin', function (done) {
  212. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  213. var hot = createHOT(data, true);
  214. var htCore = getHtCore();
  215. data[0][0] = 'new string';
  216. setTimeout(function () {
  217. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('new string');
  218. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('A2');
  219. hot.pauseObservingChanges();
  220. data[1][0] = 'another new string';
  221. }, 200);
  222. setTimeout(function () {
  223. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('new string');
  224. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('A2');
  225. hot.render();
  226. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('new string');
  227. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('another new string');
  228. done();
  229. }, 300);
  230. });
  231. it('should be possible to resume observing changes after it was paused', function (done) {
  232. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  233. var hot = createHOT(data, true);
  234. var htCore = getHtCore();
  235. hot.pauseObservingChanges();
  236. data[0][0] = 'new string';
  237. setTimeout(function () {
  238. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('A1');
  239. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('A2');
  240. hot.resumeObservingChanges();
  241. data[1][0] = 'another new string';
  242. }, 100);
  243. setTimeout(function () {
  244. expect(htCore.find('tbody tr:eq(0) td:eq(0)').html()).toEqual('new string');
  245. expect(htCore.find('tbody tr:eq(1) td:eq(0)').html()).toEqual('another new string');
  246. done();
  247. }, 1200);
  248. });
  249. });
  250. describe('observeChanges fires appropriate events when changes are detected', function () {
  251. describe('array data', function () {
  252. it('should fire afterChangesObserved event after changes has been noticed', function (done) {
  253. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  254. var hot = createHOT(data, true);
  255. var afterChangesObservedCallback = jasmine.createSpy('afterChangesObservedCallback');
  256. hot.addHook('afterChangesObserved', afterChangesObservedCallback);
  257. data[0][0] = 'new string';
  258. setTimeout(function () {
  259. expect(afterChangesObservedCallback.calls.count()).toEqual(1);
  260. done();
  261. }, 200);
  262. });
  263. it('should fire afterCreateRow event after detecting that new row has been added', function (done) {
  264. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  265. var hot = createHOT(data, true);
  266. var afterCreateRowCallback = jasmine.createSpy('afterCreateRowCallback');
  267. hot.addHook('afterCreateRow', afterCreateRowCallback);
  268. data.push(['A2', 'B2']);
  269. setTimeout(function () {
  270. expect(afterCreateRowCallback.calls.count()).toEqual(1);
  271. expect(afterCreateRowCallback).toHaveBeenCalledWith(2, 1, 'ObserveChanges.change', undefined, undefined, undefined);
  272. done();
  273. }, 200);
  274. });
  275. it('should fire afterRemoveRow event after detecting that row has been removed', function (done) {
  276. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  277. var hot = createHOT(data, true);
  278. var afterRemoveRowCallback = jasmine.createSpy('afterRemoveRowCallback');
  279. hot.addHook('afterRemoveRow', afterRemoveRowCallback);
  280. data.pop();
  281. setTimeout(function () {
  282. expect(afterRemoveRowCallback.calls.count()).toEqual(1);
  283. expect(afterRemoveRowCallback).toHaveBeenCalledWith(1, 1, 'ObserveChanges.change', undefined, undefined, undefined);
  284. done();
  285. }, 200);
  286. });
  287. it('should fire afterRemoveRow event after detecting that multiple rows have been removed', function (done) {
  288. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  289. var hot = createHOT(data, true);
  290. var afterRemoveRowCallback = jasmine.createSpy('afterRemoveRowCallback');
  291. hot.addHook('afterRemoveRow', afterRemoveRowCallback);
  292. data.splice(0, 2);
  293. setTimeout(function () {
  294. expect(afterRemoveRowCallback.calls.count()).toEqual(2);
  295. // The order of run hooks depends on whether objectObserve uses native Object.observe or a shim
  296. var args = [];
  297. args.push(afterRemoveRowCallback.calls.argsFor(0));
  298. args.push(afterRemoveRowCallback.calls.argsFor(1));
  299. expect(args).toContain([1, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  300. expect(args).toContain([0, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  301. done();
  302. }, 200);
  303. });
  304. it('should fire afterCreateCol event after detecting that new col has been added', function (done) {
  305. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  306. var hot = createHOT(data, true);
  307. var afterCreateColCallback = jasmine.createSpy('afterCreateColCallback');
  308. hot.addHook('afterCreateCol', afterCreateColCallback);
  309. data[0].push('C1');
  310. data[1].push('C2');
  311. setTimeout(function () {
  312. expect(afterCreateColCallback.calls.count()).toEqual(1);
  313. expect(afterCreateColCallback.calls.argsFor(0)).toEqual([2, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  314. done();
  315. }, 200);
  316. });
  317. it('should fire afterRemoveCol event after detecting that col has been removed', function (done) {
  318. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  319. var hot = createHOT(data, true);
  320. var afterRemoveColCallback = jasmine.createSpy('afterRemoveColCallback');
  321. hot.addHook('afterRemoveCol', afterRemoveColCallback);
  322. data[0].pop();
  323. data[1].pop();
  324. setTimeout(function () {
  325. expect(afterRemoveColCallback.calls.count()).toEqual(1);
  326. expect(afterRemoveColCallback.calls.argsFor(0)).toEqual([1, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  327. done();
  328. }, 200);
  329. });
  330. it('should fire afterRemoveCol event after detecting that multiple cols have been removed', function (done) {
  331. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  332. var hot = createHOT(data, true);
  333. var afterRemoveColCallback = jasmine.createSpy('afterRemoveColCallback');
  334. hot.addHook('afterRemoveCol', afterRemoveColCallback);
  335. data[0].pop();
  336. data[0].pop();
  337. data[1].pop();
  338. data[1].pop();
  339. setTimeout(function () {
  340. expect(afterRemoveColCallback.calls.count()).toEqual(2);
  341. // The order of run hooks depends on whether objectObserve uses native Object.observe or a shim
  342. var args = [];
  343. args.push(afterRemoveColCallback.calls.argsFor(0));
  344. args.push(afterRemoveColCallback.calls.argsFor(1));
  345. expect(args).toContain([1, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  346. expect(args).toContain([0, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  347. done();
  348. }, 200);
  349. });
  350. it('should fire afterChange event after detecting that table data has changed', function (done) {
  351. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  352. var hot = createHOT(data, true);
  353. var afterChangeCallback = jasmine.createSpy('afterChangeCallback');
  354. hot.addHook('afterChange', afterChangeCallback);
  355. data[0][0] = 'new string';
  356. setTimeout(function () {
  357. expect(afterChangeCallback.calls.count()).toEqual(1);
  358. expect(afterChangeCallback).toHaveBeenCalledWith([0, 0, null, 'new string'], 'ObserveChanges.change', undefined, undefined, undefined, undefined);
  359. done();
  360. }, 200);
  361. });
  362. });
  363. describe('object data', function () {
  364. it('should fire afterChangesObserved event after changes has been noticed', function (done) {
  365. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  366. var hot = createHOT(data, true);
  367. var afterChangesObservedCallback = jasmine.createSpy('afterChangesObservedCallback');
  368. hot.addHook('afterChangesObserved', afterChangesObservedCallback);
  369. data[0].prop0 = 'new string';
  370. setTimeout(function () {
  371. expect(afterChangesObservedCallback.calls.count()).toEqual(1);
  372. done();
  373. }, 200);
  374. });
  375. it('should fire afterCreateRow event after detecting that new row has been added', function (done) {
  376. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  377. var hot = createHOT(data, true);
  378. var afterCreateRowCallback = jasmine.createSpy('afterCreateRowCallback');
  379. hot.addHook('afterCreateRow', afterCreateRowCallback);
  380. data.push({ prop0: 'A2', prop1: 'B2' });
  381. setTimeout(function () {
  382. expect(afterCreateRowCallback.calls.count()).toEqual(1);
  383. expect(afterCreateRowCallback).toHaveBeenCalledWith(2, 1, 'ObserveChanges.change', undefined, undefined, undefined);
  384. done();
  385. }, 200);
  386. });
  387. it('should fire afterRemoveRow event after detecting that row has been removed', function (done) {
  388. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  389. var hot = createHOT(data, true);
  390. var afterRemoveRowCallback = jasmine.createSpy('afterRemoveRowCallback');
  391. hot.addHook('afterRemoveRow', afterRemoveRowCallback);
  392. data.pop();
  393. setTimeout(function () {
  394. expect(afterRemoveRowCallback.calls.count()).toEqual(1);
  395. expect(afterRemoveRowCallback).toHaveBeenCalledWith(1, 1, 'ObserveChanges.change', undefined, undefined, undefined);
  396. done();
  397. }, 200);
  398. });
  399. it('should fire afterRemoveRow event after detecting that multiple rows have been removed', function (done) {
  400. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  401. var hot = createHOT(data, true);
  402. var afterRemoveRowCallback = jasmine.createSpy('afterRemoveRowCallback');
  403. hot.addHook('afterRemoveRow', afterRemoveRowCallback);
  404. data.splice(0, 2);
  405. setTimeout(function () {
  406. expect(afterRemoveRowCallback.calls.count()).toEqual(2);
  407. // The order of run hooks depends on whether objectObserve uses native Object.observe or a shim
  408. var args = [];
  409. args.push(afterRemoveRowCallback.calls.argsFor(0));
  410. args.push(afterRemoveRowCallback.calls.argsFor(1));
  411. expect(args).toContain([1, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  412. expect(args).toContain([0, 1, 'ObserveChanges.change', undefined, undefined, undefined]);
  413. done();
  414. }, 200);
  415. });
  416. it('should fire afterChange event after detecting that table data has changed', function (done) {
  417. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  418. var hot = createHOT(data, true);
  419. var afterChangeCallback = jasmine.createSpy('afterChangeCallback');
  420. hot.addHook('afterChange', afterChangeCallback);
  421. data[0].prop0 = 'new string';
  422. setTimeout(function () {
  423. expect(afterChangeCallback.calls.count()).toEqual(1);
  424. expect(afterChangeCallback).toHaveBeenCalledWith([0, 'prop0', null, 'new string'], 'ObserveChanges.change', undefined, undefined, undefined, undefined);
  425. done();
  426. }, 200);
  427. });
  428. });
  429. });
  430. describe('using HOT data manipulation methods, when observeChanges plugin is enabled', function () {
  431. describe('array data', function () {
  432. it('should run render ONCE after detecting that new row has been added', function (done) {
  433. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  434. var hot = createHOT(data, true);
  435. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  436. hot.addHook('afterRender', afterRenderSpy);
  437. alter('insert_row');
  438. setTimeout(function () {
  439. expect(countRows()).toEqual(3);
  440. expect(afterRenderSpy.calls.count()).toEqual(1);
  441. done();
  442. }, 200);
  443. });
  444. it('should run render ONCE after detecting that row has been removed', function (done) {
  445. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  446. var hot = createHOT(data, true);
  447. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  448. hot.addHook('afterRender', afterRenderSpy);
  449. var afterChangesObservedCallback = jasmine.createSpy('afterChangesObservedCallback');
  450. hot.addHook('afterChangesObserved', afterChangesObservedCallback);
  451. alter('remove_row');
  452. setTimeout(function () {
  453. expect(countRows()).toEqual(1);
  454. expect(afterChangesObservedCallback.calls.count()).toEqual(1);
  455. expect(afterRenderSpy.calls.count()).toEqual(1);
  456. done();
  457. }, 200);
  458. });
  459. it('should run render ONCE after detecting that new column has been added', function (done) {
  460. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  461. var hot = createHOT(data, true);
  462. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  463. hot.addHook('afterRender', afterRenderSpy);
  464. alter('insert_col');
  465. setTimeout(function () {
  466. expect(countCols()).toEqual(3);
  467. expect(afterRenderSpy.calls.count()).toEqual(1);
  468. done();
  469. }, 200);
  470. });
  471. it('should run render ONCE after detecting that column has been removed', function (done) {
  472. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  473. var hot = createHOT(data, true);
  474. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  475. hot.addHook('afterRender', afterRenderSpy);
  476. var afterChangesObservedCallback = jasmine.createSpy('afterChangesObservedCallback');
  477. hot.addHook('afterChangesObserved', afterChangesObservedCallback);
  478. alter('remove_col');
  479. setTimeout(function () {
  480. expect(countCols()).toEqual(1);
  481. expect(afterChangesObservedCallback.calls.count()).toEqual(1);
  482. expect(afterRenderSpy.calls.count()).toEqual(1);
  483. done();
  484. }, 200);
  485. });
  486. it('should run render ONCE after detecting that table data has changed', function (done) {
  487. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  488. var hot = createHOT(data, true);
  489. var htCore = getHtCore();
  490. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  491. hot.addHook('afterRender', afterRenderSpy);
  492. var afterChangesObservedCallback = jasmine.createSpy('afterChangesObservedCallback');
  493. hot.addHook('afterChangesObserved', afterChangesObservedCallback);
  494. setDataAtCell(0, 0, 'new value');
  495. setTimeout(function () {
  496. expect(htCore.find('tbody tr:eq(0) td:eq(0)').text()).toEqual('new value');
  497. expect(afterChangesObservedCallback.calls.count()).toEqual(1);
  498. expect(afterRenderSpy.calls.count()).toEqual(1);
  499. done();
  500. }, 200);
  501. });
  502. });
  503. describe('object data', function () {
  504. it('should run render ONCE after detecting that new row has been added', function (done) {
  505. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  506. var hot = createHOT(data, true);
  507. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  508. hot.addHook('afterRender', afterRenderSpy);
  509. alter('insert_row');
  510. setTimeout(function () {
  511. expect(countRows()).toEqual(3);
  512. expect(afterRenderSpy.calls.count()).toEqual(1);
  513. done();
  514. }, 200);
  515. });
  516. it('should run render ONCE after detecting that row has been removed', function (done) {
  517. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  518. var hot = createHOT(data, true);
  519. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  520. hot.addHook('afterRender', afterRenderSpy);
  521. var afterChangesObservedCallback = jasmine.createSpy('afterChangesObservedCallback');
  522. hot.addHook('afterChangesObserved', afterChangesObservedCallback);
  523. alter('remove_row');
  524. setTimeout(function () {
  525. expect(countRows()).toEqual(1);
  526. expect(afterChangesObservedCallback.calls.count()).toEqual(1);
  527. expect(afterRenderSpy.calls.count()).toEqual(1);
  528. done();
  529. }, 200);
  530. });
  531. it('should run render ONCE after detecting that table data has changed', function (done) {
  532. var data = Handsontable.helper.createSpreadsheetObjectData(2, 2);
  533. var hot = createHOT(data, true);
  534. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  535. hot.addHook('afterRender', afterRenderSpy);
  536. var afterChangesObservedCallback = jasmine.createSpy('afterChangesObservedCallback');
  537. hot.addHook('afterChangesObserved', afterChangesObservedCallback);
  538. setDataAtRowProp(0, 'prop0', 'new value');
  539. setTimeout(function () {
  540. expect(spec().$container.find('tbody tr:eq(0) td:eq(0)').text()).toEqual('new value');
  541. expect(afterChangesObservedCallback.calls.count()).toEqual(1);
  542. expect(afterRenderSpy.calls.count()).toEqual(1);
  543. done();
  544. }, 200);
  545. });
  546. });
  547. });
  548. describe('refreshing table after changes have been detected', function () {
  549. it('should observe changes to new data bound using loadData', function (done) {
  550. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  551. var newData = Handsontable.helper.createSpreadsheetData(2, 2);
  552. var hot = createHOT(data, true);
  553. var htCore = getHtCore();
  554. hot.loadData(newData);
  555. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  556. hot.addHook('afterRender', afterRenderSpy);
  557. newData.push(['A3', 'B3']);
  558. setTimeout(function () {
  559. expect(afterRenderSpy.calls.count()).toBe(1);
  560. expect(htCore.find('tr').length).toEqual(3);
  561. expect(htCore.find('col').length).toEqual(2);
  562. done();
  563. }, 200);
  564. });
  565. it('should not observe changes to old data after it was replaced using loadData', function (done) {
  566. var data = Handsontable.helper.createSpreadsheetData(2, 2);
  567. var newData = Handsontable.helper.createSpreadsheetData(2, 2);
  568. var hot = createHOT(data, true);
  569. var htCore = getHtCore();
  570. hot.loadData(newData);
  571. var afterRenderSpy = jasmine.createSpy('afterRenderSpy');
  572. hot.addHook('afterRender', afterRenderSpy);
  573. data.push(['A3', 'B3']);
  574. setTimeout(function () {
  575. expect(afterRenderSpy.calls.count()).toBe(0);
  576. expect(htCore.find('tr').length).toEqual(2);
  577. expect(htCore.find('col').length).toEqual(2);
  578. done();
  579. }, 1000);
  580. });
  581. });
  582. });