tableParamsSpec.js 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573
  1. describe('NgTableParams', function () {
  2. var scope, ctrl, data = [
  3. {name: "Moroni", age: 50, role: 'Administrator'},
  4. {name: "Tiancum", age: 43, role: 'Administrator'},
  5. {name: "Jacob", age: 27, role: 'Administrator'},
  6. {name: "Nephi", age: 29, role: 'Moderator'},
  7. {name: "Enos", age: 34, role: 'User'},
  8. {name: "Tiancum", age: 43, role: 'User'},
  9. {name: "Jacob", age: 27, role: 'User'},
  10. {name: "Nephi", age: 29, role: 'Moderator'},
  11. {name: "Enos", age: 34, role: 'User'},
  12. {name: "Tiancum", age: 43, role: 'Moderator'},
  13. {name: "Jacob", age: 27, role: 'User'},
  14. {name: "Nephi", age: 29, role: 'User'},
  15. {name: "Enos", age: 34, role: 'Moderator'},
  16. {name: "Tiancum", age: 43, role: 'User'},
  17. {name: "Jacob", age: 27, role: 'User'},
  18. {name: "Nephi", age: 29, role: 'User'},
  19. {name: "Enos", age: 34, role: 'User'}
  20. ];
  21. var NgTableParams,
  22. $rootScope;
  23. beforeEach(function () {
  24. // Initialize the service provider
  25. // by injecting it to a fake module's config block
  26. var fakeModule = angular.module('test.config', function () {});
  27. fakeModule.config( function ($provide) {
  28. $provide.decorator('ngTableDefaultGetData', createSpy);
  29. createSpy.$inject = ['$delegate'];
  30. function createSpy(ngTableDefaultGetData){
  31. return jasmine.createSpy('ngTableDefaultGetDataSpy',ngTableDefaultGetData).and.callThrough();
  32. }
  33. });
  34. // Initialize test.app injector
  35. module('ngTable', 'test.config');
  36. });
  37. beforeEach(inject(function ($controller, _$rootScope_, _NgTableParams_) {
  38. $rootScope = _$rootScope_;
  39. scope = $rootScope.$new();
  40. NgTableParams = _NgTableParams_;
  41. }));
  42. function createNgTableParams(settings) {
  43. var initialParams;
  44. if (arguments.length === 2){
  45. initialParams = arguments[0];
  46. settings = arguments[1];
  47. }
  48. settings = angular.extend({}, {
  49. filterDelay: 0
  50. }, settings);
  51. var tableParams = new NgTableParams(initialParams, settings);
  52. spyOn(tableParams.settings(), 'getData').and.callThrough();
  53. return tableParams;
  54. }
  55. it('NgTableParams should be defined', function () {
  56. expect(NgTableParams).toBeDefined();
  57. });
  58. describe('generatePagesArray', function(){
  59. it('should generate pages array using arguments supplied', function(){
  60. var params = new NgTableParams();
  61. expect(params.generatePagesArray(1, 30, 10)).toEqual([
  62. { type: 'prev', number: 1, active: false },
  63. { type: 'first', number: 1, active: false, current: true },
  64. { type: 'page', number: 2, active: true, current: false },
  65. { type: 'last', number: 3, active: true, current: false },
  66. { type: 'next', number: 2, active: true }
  67. ]);
  68. expect(params.generatePagesArray(2, 30, 10)).toEqual([
  69. { type: 'prev', number: 1, active: true },
  70. { type: 'first', number: 1, active: true, current: false },
  71. { type: 'page', number: 2, active: false, current: true },
  72. { type: 'last', number: 3, active: true, current: false },
  73. { type: 'next', number: 3, active: true }
  74. ]);
  75. expect(params.generatePagesArray(2, 100, 10)).toEqual([
  76. { type: 'prev', number: 1, active: true },
  77. { type: 'first', number: 1, active: true, current: false },
  78. { type: 'page', number: 2, active: false, current: true },
  79. { type: 'page', number: 3, active: true, current: false },
  80. { type: 'page', number: 4, active: true, current: false },
  81. { type: 'page', number: 5, active: true, current: false },
  82. { type: 'page', number: 6, active: true, current: false },
  83. { type: 'page', number: 7, active: true, current: false },
  84. { type: 'more', active: false },
  85. { type: 'last', number: 10, active: true, current: false },
  86. { type: 'next', number: 3, active: true }
  87. ]);
  88. });
  89. it('should use own parameter values to generate pages when no arguments supplied', function(){
  90. var params = new NgTableParams({ page: 2, count: 10 }, { total: 30 });
  91. expect(params.generatePagesArray()).toEqual([
  92. { type: 'prev', number: 1, active: true },
  93. { type: 'first', number: 1, active: true, current: false },
  94. { type: 'page', number: 2, active: false, current: true },
  95. { type: 'last', number: 3, active: true, current: false },
  96. { type: 'next', number: 3, active: true }
  97. ]);
  98. });
  99. });
  100. it('NgTableParams `page` parameter', function () {
  101. var params = new NgTableParams();
  102. expect(params.page()).toBe(1);
  103. expect(params.page(2)).toEqual(params);
  104. expect(params.page()).toBe(2);
  105. params = new NgTableParams({
  106. page: 3
  107. });
  108. expect(params.page()).toBe(3);
  109. });
  110. it('NgTableParams parse url parameters', function () {
  111. var params = new NgTableParams({
  112. 'sorting[name]': 'asc',
  113. 'sorting[age]': 'desc',
  114. 'filter[name]': 'test',
  115. 'filter[age]': 20
  116. });
  117. expect(params.filter()).toEqual({ 'name': 'test', 'age': 20 });
  118. expect(params.filter({})).toEqual(params);
  119. expect(params.sorting()).toEqual({ 'age': 'desc' }); // sorting only by one column
  120. expect(params.sorting({})).toEqual(params);
  121. });
  122. it('NgTableParams return url parameters', function () {
  123. var params = new NgTableParams({
  124. 'sorting[name]': 'asc',
  125. 'sorting[age]': 'desc',
  126. 'filter[name]': 'test',
  127. 'filter[age]': 20
  128. });
  129. expect(params.url()).toEqual({
  130. 'page': '1',
  131. 'count': '1',
  132. 'filter[name]': 'test',
  133. 'filter[age]': 20,
  134. 'sorting[age]': 'desc'
  135. });
  136. expect(params.url(true)).toEqual([
  137. 'page=1',
  138. 'count=1',
  139. 'filter[name]=test',
  140. 'filter[age]=20',
  141. 'sorting[age]=desc'
  142. ]);
  143. });
  144. it('NgTableParams test orderBy', function () {
  145. var params = new NgTableParams({
  146. 'sorting[name]': 'asc'
  147. });
  148. expect(params.orderBy()).toEqual([ '+name' ]); // for angular sorting function
  149. params.sorting({ name: 'desc', age: 'asc' });
  150. expect(params.orderBy()).toEqual([ '-name', '+age' ]);
  151. });
  152. it('NgTableParams test settings', function () {
  153. var params = new NgTableParams();
  154. expect(params.settings()).toEqual(jasmine.objectContaining({
  155. $loading: false,
  156. data: null,
  157. total: 0,
  158. defaultSort : 'desc',
  159. counts: [10, 25, 50, 100],
  160. interceptors: [],
  161. paginationMaxBlocks: 11,
  162. paginationMinBlocks: 5,
  163. sortingIndicator : 'span',
  164. getData: params.getData,
  165. getGroups: params.getGroups,
  166. filterDelay: 750
  167. }));
  168. params = new NgTableParams({}, { total: 100, counts: [1,2] });
  169. expect(params.settings()).toEqual(jasmine.objectContaining({
  170. $loading: false,
  171. data: null,
  172. total: 100,
  173. defaultSort : 'desc',
  174. counts: [1,2],
  175. interceptors: [],
  176. paginationMaxBlocks: 11,
  177. paginationMinBlocks: 5,
  178. sortingIndicator : 'span',
  179. getData: params.getData,
  180. getGroups: params.getGroups,
  181. filterDelay: 750
  182. }));
  183. });
  184. it('changing settings().data should reset page to 1', function(){
  185. // given
  186. var tableParams = createNgTableParams({ count: 1, page: 2 }, { data: [1,2,3]});
  187. tableParams.reload();
  188. scope.$digest();
  189. expect(tableParams.page()).toBe(2); // checking assumptions
  190. // when
  191. tableParams.settings({ data: [1,2,3, 4]});
  192. // then
  193. expect(tableParams.page()).toBe(1);
  194. });
  195. describe('reload', function(){
  196. it('should call getData to retrieve data', function(){
  197. var tp = createNgTableParams();
  198. tp.reload();
  199. scope.$digest();
  200. expect(tp.settings().getData.calls.count()).toBe(1);
  201. });
  202. it('should add the results returned by getData to the data field', function(){
  203. var tp = createNgTableParams({ getData: function(){
  204. return [1,2,3];
  205. }});
  206. tp.reload();
  207. scope.$digest();
  208. expect(tp.data).toEqual([1,2,3]);
  209. });
  210. it('should use ngTableDefaultGetData function when NgTableParams not supplied a getData function', inject(function(ngTableDefaultGetData){
  211. // given
  212. var tp = createNgTableParams();
  213. // when
  214. tp.reload();
  215. scope.$digest();
  216. // then
  217. expect(ngTableDefaultGetData).toHaveBeenCalled();
  218. }));
  219. it('should propagate rejection reason from getData', inject(function($q){
  220. // given
  221. var tp = createNgTableParams({ getData: function(){
  222. return $q.reject('bad response')
  223. }});
  224. // when
  225. var actualRejection;
  226. tp.reload().catch(function(reason){
  227. actualRejection = reason;
  228. });
  229. scope.$digest();
  230. // then
  231. expect(actualRejection).toBe('bad response');
  232. }));
  233. });
  234. it('NgTableParams test grouping', inject(function ($rootScope) {
  235. var tp = createNgTableParams({ getData: function (/*params*/) {
  236. return data;
  237. }});
  238. var actualRoleGroups;
  239. tp.getGroups('role'/*, params*/).then(function(groups){
  240. actualRoleGroups = groups;
  241. });
  242. $rootScope.$digest();
  243. expect(actualRoleGroups).toEqual([
  244. {
  245. value: 'Administrator',
  246. data: [
  247. {name: "Moroni", age: 50, role: 'Administrator'},
  248. {name: "Tiancum", age: 43, role: 'Administrator'},
  249. {name: "Jacob", age: 27, role: 'Administrator'}
  250. ]
  251. },
  252. {
  253. value: 'Moderator',
  254. data: [
  255. {name: "Nephi", age: 29, role: 'Moderator'},
  256. {name: "Nephi", age: 29, role: 'Moderator'},
  257. {name: "Tiancum", age: 43, role: 'Moderator'},
  258. {name: "Enos", age: 34, role: 'Moderator'}
  259. ]
  260. },
  261. {
  262. value: 'User',
  263. data: [
  264. {name: "Enos", age: 34, role: 'User'},
  265. {name: "Tiancum", age: 43, role: 'User'},
  266. {name: "Jacob", age: 27, role: 'User'},
  267. {name: "Enos", age: 34, role: 'User'},
  268. {name: "Jacob", age: 27, role: 'User'},
  269. {name: "Nephi", age: 29, role: 'User'},
  270. {name: "Tiancum", age: 43, role: 'User'},
  271. {name: "Jacob", age: 27, role: 'User'},
  272. {name: "Nephi", age: 29, role: 'User'},
  273. {name: "Enos", age: 34, role: 'User'}
  274. ]
  275. }
  276. ]);
  277. var actualAgeGroups;
  278. tp.getGroups('age'/*, params*/).then(function(groups){
  279. actualAgeGroups = groups;
  280. });
  281. $rootScope.$digest();
  282. expect(actualAgeGroups).toEqual([
  283. {
  284. value: 27,
  285. data: [
  286. {name: "Jacob", age: 27, role: 'Administrator'},
  287. {name: "Jacob", age: 27, role: 'User'},
  288. {name: "Jacob", age: 27, role: 'User'},
  289. {name: "Jacob", age: 27, role: 'User'}
  290. ]
  291. },
  292. {
  293. value: 29,
  294. data: [
  295. {name: "Nephi", age: 29, role: 'Moderator'},
  296. {name: "Nephi", age: 29, role: 'Moderator'},
  297. {name: "Nephi", age: 29, role: 'User'},
  298. {name: "Nephi", age: 29, role: 'User'}
  299. ]
  300. },
  301. {
  302. value: 34,
  303. data: [
  304. {name: "Enos", age: 34, role: 'User'},
  305. {name: "Enos", age: 34, role: 'User'},
  306. {name: "Enos", age: 34, role: 'Moderator'},
  307. {name: "Enos", age: 34, role: 'User'}
  308. ]
  309. },
  310. {
  311. value: 43,
  312. data: [
  313. {name: "Tiancum", age: 43, role: 'Administrator'},
  314. {name: "Tiancum", age: 43, role: 'User'},
  315. {name: "Tiancum", age: 43, role: 'Moderator'},
  316. {name: "Tiancum", age: 43, role: 'User'}
  317. ]
  318. },{
  319. value: 50,
  320. data: [
  321. {name: "Moroni", age: 50, role: 'Administrator'}
  322. ]
  323. }
  324. ]);
  325. }));
  326. it('ngTableParams test defaults', inject(function ($q, ngTableDefaults) {
  327. ngTableDefaults.params = {
  328. count: 2
  329. };
  330. ngTableDefaults.settings = {
  331. counts: []
  332. };
  333. var tp = new NgTableParams();
  334. expect(tp.count()).toEqual(2);
  335. expect(tp.page()).toEqual(1);
  336. var settings = tp.settings();
  337. expect(settings.counts.length).toEqual(0);
  338. expect(settings.interceptors.length).toEqual(0);
  339. expect(settings.filterDelay).toEqual(750);
  340. ngTableDefaults.settings.interceptors = [ { response: angular.identity }];
  341. tp = new NgTableParams();
  342. expect(tp.settings().interceptors.length).toEqual(1);
  343. }));
  344. describe('hasFilter', function(){
  345. var tp;
  346. beforeEach(inject(function(){
  347. tp = new NgTableParams({}, {});
  348. }));
  349. it('should return false for an empty filter object', function(){
  350. tp.filter({});
  351. expect(tp.hasFilter()).toBe(false);
  352. });
  353. it('should return true for when filter has a field with a significant value', function(){
  354. tp.filter({ a: 'b' });
  355. expect(tp.hasFilter()).toBe(true);
  356. tp.filter({ a: 0 });
  357. expect(tp.hasFilter()).toBe(true);
  358. });
  359. it('should return false when filter only has insignificant field values', function(){
  360. tp.filter({ a: '' });
  361. expect(tp.hasFilter()).toBe(false);
  362. tp.filter({ a: null });
  363. expect(tp.hasFilter()).toBe(false);
  364. tp.filter({ a: undefined });
  365. expect(tp.hasFilter()).toBe(false);
  366. tp.filter({ a: undefined, b: '', c: undefined });
  367. expect(tp.hasFilter()).toBe(false);
  368. //tp.filter({ a: NaN });
  369. //expect(tp.hasFilter()).toBe(false);
  370. });
  371. });
  372. describe('isDataReloadRequired', function(){
  373. var tp;
  374. beforeEach(inject(function(){
  375. tp = createNgTableParams();
  376. }));
  377. it('should return true after construction', function(){
  378. expect(tp.isDataReloadRequired()).toBe(true);
  379. });
  380. it('should return false once reload called after construction', function(){
  381. tp.reload();
  382. // note: we don't have to wait for the getData promise to be resolved before considering reload
  383. // to be unnecessary - that's why we're not having to run a $digest
  384. expect(tp.isDataReloadRequired()).toBe(false);
  385. });
  386. it('should return true when getData fails', inject(function($q){
  387. tp.settings({ getData: function(){
  388. return $q.reject('bad response');
  389. }});
  390. tp.reload();
  391. scope.$digest();
  392. expect(tp.isDataReloadRequired()).toBe(true);
  393. }));
  394. it('should detect direct changes to parameters', inject(function($q){
  395. // given
  396. tp.reload();
  397. scope.$digest();
  398. expect(tp.isDataReloadRequired()).toBe(false); // checking assumptions
  399. // when
  400. tp.filter().newField = 99;
  401. expect(tp.isDataReloadRequired()).toBe(true);
  402. }));
  403. it('should return true until changed parameters have been reloaded', function(){
  404. // given
  405. tp.reload();
  406. scope.$digest();
  407. // when, then...
  408. verifyIsDataReloadRequired(function(){
  409. tp.filter({ age: 1});
  410. });
  411. verifyIsDataReloadRequired(function(){
  412. tp.page(55);
  413. });
  414. verifyIsDataReloadRequired(function(){
  415. tp.sorting({ age: 'desc'});
  416. });
  417. verifyIsDataReloadRequired(function(){
  418. tp.count(100);
  419. });
  420. });
  421. it('should return false when parameters "touched" but not modified', function(){
  422. // given
  423. tp.filter({ age: 1});
  424. tp.reload();
  425. scope.$digest();
  426. // when, then...
  427. tp.filter({ age: 1});
  428. expect(tp.isDataReloadRequired()).toBe(false);
  429. });
  430. it('should return true when new settings data array supplied', function(){
  431. // given
  432. tp.reload();
  433. scope.$digest();
  434. verifyIsDataReloadRequired(function(){
  435. tp.settings({ data: [11,22,33]});
  436. });
  437. });
  438. it('should return true when existing settings data array is unset', function(){
  439. // given
  440. tp = createNgTableParams({ data: [1,2,3]});
  441. tp.reload();
  442. scope.$digest();
  443. verifyIsDataReloadRequired(function(){
  444. tp.settings({ data: null});
  445. });
  446. });
  447. it('status should not change when settings called without a data array', function(){
  448. // given
  449. tp = createNgTableParams({ data: [1,2,3]});
  450. tp.reload();
  451. scope.$digest();
  452. // when, then...
  453. tp.settings({ total : 100 });
  454. expect(tp.isDataReloadRequired()).toBe(false);
  455. });
  456. function verifyIsDataReloadRequired(modifer){
  457. modifer();
  458. expect(tp.isDataReloadRequired()).toBe(true);
  459. tp.reload();
  460. scope.$digest();
  461. expect(tp.isDataReloadRequired()).toBe(false);
  462. }
  463. });
  464. describe('hasFilterChanges', function(){
  465. var tp;
  466. beforeEach(inject(function(){
  467. tp = createNgTableParams();
  468. }));
  469. it('should return true after construction', function(){
  470. expect(tp.hasFilterChanges()).toBe(true);
  471. });
  472. it('should return false once reload called after construction', function(){
  473. tp.reload();
  474. // note: we don't have to wait for the getData promise to be resolved before considering reload
  475. // to be unnecessary - that's why we're not having to run a $digest
  476. expect(tp.hasFilterChanges()).toBe(false);
  477. });
  478. it('should return true when getData fails', inject(function($q){
  479. tp.settings({ getData: function(){
  480. return $q.reject('bad response');
  481. }});
  482. tp.reload();
  483. scope.$digest();
  484. expect(tp.hasFilterChanges()).toBe(true);
  485. }));
  486. it('should detect direct changes to filters', inject(function($q){
  487. // given
  488. tp.reload();
  489. scope.$digest();
  490. expect(tp.hasFilterChanges()).toBe(false); // checking assumptions
  491. // when
  492. tp.filter().newField = 99;
  493. expect(tp.hasFilterChanges()).toBe(true);
  494. }));
  495. it('should return true until changed filters have been reloaded', function(){
  496. // given
  497. tp.reload();
  498. scope.$digest();
  499. // when, then...
  500. tp.filter({ age: 1});
  501. expect(tp.hasFilterChanges()).toBe(true);
  502. tp.reload();
  503. scope.$digest();
  504. expect(tp.hasFilterChanges()).toBe(false);
  505. });
  506. it('should return false when filters "touched" but not modified', function(){
  507. // given
  508. tp.filter({ age: 1});
  509. tp.reload();
  510. scope.$digest();
  511. // when, then...
  512. tp.filter({ age: 1});
  513. expect(tp.hasFilterChanges()).toBe(false);
  514. });
  515. it('status should not change just because new settings data array supplied', function(){
  516. // given
  517. tp.reload();
  518. scope.$digest();
  519. // when, then...
  520. tp.settings({ data: [11,22,33]});
  521. expect(tp.hasFilterChanges()).toBe(false);
  522. });
  523. });
  524. describe('backwards compatibility shim', function(){
  525. it('shim should supply getData original arguments', inject(function(ngTableGetDataBcShim){
  526. // given
  527. var callCount = 0;
  528. var adaptedFn = ngTableGetDataBcShim(originalGetDataFn);
  529. // when
  530. var tableParams = new NgTableParams({}, {});
  531. adaptedFn(tableParams);
  532. // then
  533. expect(callCount).toBe(1);
  534. function originalGetDataFn($defer, params){
  535. callCount++;
  536. expect($defer).toBeDefined();
  537. expect($defer.resolve).toBeDefined();
  538. expect(params).toBeDefined();
  539. expect(params).toEqual(jasmine.any(NgTableParams));
  540. }
  541. }));
  542. it('shim should return the getData "$defer" promise', inject(function(ngTableGetDataBcShim){
  543. // given
  544. var callCount = 0;
  545. var adaptedFn = ngTableGetDataBcShim(originalGetDataFn);
  546. // when
  547. var tableParams = new NgTableParams({}, {});
  548. var results = adaptedFn(tableParams);
  549. // then
  550. expect(results).toBeDefined();
  551. expect(results.then).toBeDefined();
  552. results.then(function(data){
  553. expect(data.length).toBe(3);
  554. });
  555. scope.$digest();
  556. function originalGetDataFn($defer/*, params*/){
  557. $defer.resolve([1,2,3]);
  558. }
  559. }));
  560. it('shim should return the data', inject(function(ngTableGetDataBcShim){
  561. // given
  562. var callCount = 0;
  563. var adaptedFn = ngTableGetDataBcShim(originalGetDataFn);
  564. // when
  565. var tableParams = new NgTableParams({}, {});
  566. var results = adaptedFn(tableParams);
  567. // then
  568. expect(results).toBeDefined();
  569. expect(results).toEqual([1,2,3]);
  570. function originalGetDataFn(/*$defer, params*/){
  571. return [1,2,3];
  572. }
  573. }));
  574. it('shim should be applied when getData function supplied has more than one parameter', function(){
  575. // given
  576. var tp = createNgTableParams({ getData: originalGetDataFn});
  577. // when
  578. var dataFetched = tp.reload();
  579. // then
  580. var actualData;
  581. dataFetched.then(function(data){
  582. actualData = data;
  583. });
  584. scope.$digest();
  585. expect(actualData).toEqual([1,2,3]);
  586. function originalGetDataFn($defer, params){
  587. params.total(3);
  588. $defer.resolve([1,2,3]);
  589. }
  590. });
  591. it('shim should NOT be applied when getData has new signature', function(){
  592. // given
  593. var tp = createNgTableParams({ getData: newGetDataFn});
  594. // when
  595. var dataFetched = tp.reload();
  596. // then
  597. var actualData;
  598. dataFetched.then(function(data){
  599. actualData = data;
  600. });
  601. scope.$digest();
  602. expect(actualData).toEqual([1,2,3]);
  603. function newGetDataFn(params){
  604. params.total(3);
  605. return [1,2,3];
  606. }
  607. });
  608. });
  609. describe('interceptors', function(){
  610. it('can register interceptor', function(){
  611. var interceptor = { response: angular.identity };
  612. var tp = createNgTableParams({ interceptors: [interceptor]});
  613. expect(tp.settings().interceptors).toEqual([interceptor]);
  614. });
  615. it('can register multiple interceptor', function(){
  616. var interceptors = [{ response: angular.identity }, { response: angular.identity }];
  617. var tp = createNgTableParams({ interceptors: interceptors});
  618. expect(tp.settings().interceptors).toEqual(interceptors);
  619. });
  620. it('can register interceptors after NgTableParams created', function(){
  621. var interceptor = { response: angular.identity };
  622. var interceptor2 = { response: angular.identity };
  623. var tp = createNgTableParams({ interceptors: [interceptor]});
  624. var interceptors = tp.settings().interceptors.concat([interceptor2]);
  625. tp.settings({ interceptors: interceptors});
  626. expect(tp.settings().interceptors).toEqual(interceptors);
  627. });
  628. describe('one response interceptor', function(){
  629. it('should receive response from call to getData', function(){
  630. // given
  631. var interceptor = {
  632. response: function(/*data, params*/){
  633. this.hasRun = true;
  634. }
  635. };
  636. var tp = createNgTableParams({ interceptors: [interceptor]});
  637. // when
  638. tp.reload();
  639. scope.$digest();
  640. // then
  641. expect(interceptor.hasRun).toBeTruthy();
  642. });
  643. it('should be able to modify data returned by getData', function(){
  644. // given
  645. var interceptor = {
  646. response: function(data/*, params*/){
  647. data.forEach(function(item){
  648. item.modified = true;
  649. });
  650. return data;
  651. }
  652. };
  653. var tp = createNgTableParams({ interceptors: [interceptor], getData: function(){
  654. return [{}, {}];
  655. }});
  656. // when
  657. var actualData;
  658. tp.reload().then(function(data){
  659. actualData = data;
  660. });
  661. scope.$digest();
  662. // then
  663. expect(actualData).toEqual([{ modified: true }, { modified: true }]);
  664. });
  665. it('should be able to replace data returned by getData', function(){
  666. // given
  667. var interceptor = {
  668. response: function(data/*, params*/){
  669. return data.map(function(item){
  670. return item * 2;
  671. });
  672. }
  673. };
  674. var tp = createNgTableParams({ interceptors: [interceptor], getData: function(){
  675. return [2, 3];
  676. }});
  677. // when
  678. var actualData;
  679. tp.reload().then(function(data){
  680. actualData = data;
  681. });
  682. scope.$digest();
  683. // then
  684. expect(actualData).toEqual([4, 6]);
  685. });
  686. it('should be able to access tableParams supplied to getData', function(){
  687. // given
  688. var interceptor = {
  689. response: function(data, params){
  690. params.total(data.total);
  691. return data.results;
  692. }
  693. };
  694. var tp = createNgTableParams({ interceptors: [interceptor], getData: function(){
  695. return { results: [1,2,3], total: 3};
  696. }});
  697. // when
  698. var actualData;
  699. tp.reload().then(function(data){
  700. actualData = data;
  701. });
  702. scope.$digest();
  703. // then
  704. expect(actualData).toEqual([1,2,3]);
  705. expect(tp.total()).toEqual(3);
  706. });
  707. });
  708. describe('one responseError interceptor', function(){
  709. it('should receive rejections from getData', inject(function($q){
  710. // given
  711. var interceptor = {
  712. responseError: function(reason/*, params*/){
  713. this.actualReason = reason;
  714. }
  715. };
  716. var tp = createNgTableParams({
  717. interceptors: [interceptor],
  718. getData: function(/*params*/){
  719. return $q.reject('BANG!');
  720. }
  721. });
  722. // when
  723. tp.reload();
  724. scope.$digest();
  725. // then
  726. expect(interceptor.actualReason).toBe('BANG!');
  727. }));
  728. it('should NOT receive errors from getData', function(){
  729. // given
  730. var interceptor = {
  731. responseError: function(/*reason, params*/){
  732. this.hasRun = true;
  733. }
  734. };
  735. var tp = createNgTableParams({
  736. interceptors: [interceptor],
  737. getData: function(/*params*/){
  738. throw new Error('BANG!');
  739. }
  740. });
  741. // when, then
  742. expect(tp.reload).toThrow();
  743. expect(interceptor.hasRun).toBeFalsy();
  744. });
  745. it('should be able to modify reason returned by getData', inject(function($q){
  746. // given
  747. var interceptor = {
  748. responseError: function(reason/*, params*/){
  749. reason.code = 400;
  750. return $q.reject(reason);
  751. }
  752. };
  753. var tp = createNgTableParams({
  754. interceptors: [interceptor],
  755. getData: function(/*params*/){
  756. return $q.reject({ description: 'crappy data'});
  757. }
  758. });
  759. // when
  760. var actualReason;
  761. tp.reload().catch(function(reason){
  762. actualReason = reason;
  763. });
  764. scope.$digest();
  765. // then
  766. expect(actualReason.code).toBe(400);
  767. expect(actualReason.description).toBe('crappy data');
  768. }));
  769. it('should be able to replace reason returned by getData', inject(function($q){
  770. // given
  771. var interceptor = {
  772. responseError: function(/*reason, params*/){
  773. return $q.reject('Cancelled by user');
  774. }
  775. };
  776. var tp = createNgTableParams({
  777. interceptors: [interceptor],
  778. getData: function(/*params*/){
  779. return $q.reject('BANG!');
  780. }
  781. });
  782. // when
  783. var actualReason;
  784. tp.reload().catch(function(reason){
  785. actualReason = reason;
  786. });
  787. scope.$digest();
  788. // then
  789. expect(actualReason).toBe('Cancelled by user');
  790. }));
  791. it('should be able to access tableParams supplied to getData', function(){
  792. // given
  793. var interceptor = {
  794. response: function(reason, params){
  795. this.actualParams = params;
  796. }
  797. };
  798. var tp = createNgTableParams({ interceptors: [interceptor]});
  799. // when
  800. var actualData;
  801. tp.reload();
  802. scope.$digest();
  803. // then
  804. expect(interceptor.actualParams).toBe(tp);
  805. });
  806. });
  807. describe('one response plus responseError interceptor', function(){
  808. it('should NOT call responseError on same interceptor whose response method fails', inject(function($q){
  809. // given
  810. var interceptor = {
  811. response: function(/*data, params*/){
  812. return $q.reject('BANG!');
  813. },
  814. responseError: function(reason/*, params*/){
  815. this.hasRun = true;
  816. }
  817. };
  818. var tp = createNgTableParams({
  819. interceptors: [interceptor],
  820. getData: function(/*params*/){
  821. return [1,2,3];
  822. }
  823. });
  824. // when
  825. tp.reload();
  826. scope.$digest();
  827. // then
  828. expect(interceptor.hasRun).toBeFalsy();
  829. }));
  830. });
  831. describe('multiple response interceptors', function(){
  832. it('should run interceptors in the order they were registered', function(){
  833. // given
  834. var callCount = 0;
  835. var interceptor = {
  836. response: function(/*data, params*/){
  837. this.sequence = callCount;
  838. callCount++;
  839. }
  840. };
  841. var interceptors = [interceptor, angular.copy(interceptor)];
  842. var tp = createNgTableParams({ interceptors: interceptors});
  843. // when
  844. tp.reload();
  845. scope.$digest();
  846. // then
  847. expect(interceptors[0].sequence).toBe(0);
  848. expect(interceptors[1].sequence).toBe(1);
  849. });
  850. it('results of one interceptor should be piped to the next validator', function(){
  851. // given
  852. var interceptor = {
  853. response: function(data/*, params*/){
  854. return data.map(function(item){
  855. return item * 2;
  856. });
  857. }
  858. };
  859. var interceptor2 = {
  860. response: function(data/*, params*/){
  861. return data.map(function(item){
  862. return item.toString() + '0';
  863. });
  864. }
  865. };
  866. var tp = createNgTableParams({ interceptors: [interceptor, interceptor2], getData: function(){
  867. return [2, 3];
  868. }});
  869. // when
  870. var actualData;
  871. tp.reload().then(function(data){
  872. actualData = data;
  873. });
  874. scope.$digest();
  875. // then
  876. expect(actualData).toEqual(['40', '60']);
  877. });
  878. });
  879. describe('multiple response and responseError interceptors', function(){
  880. it('responseError of next interceptor should receive failures from previous interceptor', inject(function($q){
  881. // given
  882. var badInterceptor = {
  883. response: function(/*data, params*/){
  884. return $q.reject('BANG!');
  885. }
  886. };
  887. var nextInterceptor = {
  888. responseError: function(/*reason, params*/){
  889. this.hasRun = true;
  890. }
  891. };
  892. var tp = createNgTableParams({ interceptors: [badInterceptor, nextInterceptor]});
  893. // when
  894. tp.reload();
  895. scope.$digest();
  896. // then
  897. expect(nextInterceptor.hasRun).toBe(true);
  898. }));
  899. it('should call next response interceptor when previous interceptor recovers from failure', inject(function($q){
  900. // given
  901. var badInterceptor = {
  902. response: function(/*data, params*/){
  903. return $q.reject('BANG!');
  904. }
  905. };
  906. var recoveringInterceptor = {
  907. responseError: function(/*reason, params*/){
  908. return [8894,58];
  909. }
  910. };
  911. var recoveredData;
  912. var nextInterceptor = {
  913. response: function(data/*, params*/){
  914. this.hasRun = true;
  915. recoveredData = data;
  916. }
  917. };
  918. var tp = createNgTableParams({ interceptors: [badInterceptor, recoveringInterceptor, nextInterceptor]});
  919. // when
  920. tp.reload();
  921. scope.$digest();
  922. // then
  923. expect(nextInterceptor.hasRun).toBe(true);
  924. expect(recoveredData).toEqual([8894,58]);
  925. }));
  926. });
  927. });
  928. describe('events', function(){
  929. var actualEventArgs,
  930. actualPublisher,
  931. fakeTableParams,
  932. ngTableEventsChannel;
  933. beforeEach(inject(function(_ngTableEventsChannel_){
  934. ngTableEventsChannel = _ngTableEventsChannel_;
  935. fakeTableParams = {};
  936. actualPublisher = undefined;
  937. actualEventArgs = undefined;
  938. }));
  939. function getSubscriberCount(){
  940. var allEventNames = Object.keys($rootScope.$$listenerCount);
  941. var ngTableEvents = allEventNames.filter(function(event){
  942. return event.indexOf('ngTable:') === 0;
  943. });
  944. return ngTableEvents.reduce(function(result, event){
  945. result += $rootScope.$$listenerCount[event];
  946. return result;
  947. }, 0);
  948. }
  949. describe('general pub/sub mechanics', function(){
  950. var supportedEvents = ['DatasetChanged', 'AfterReloadData', 'PagesChanged', 'AfterCreated'];
  951. it('should be safe to publish event when no subscribers', function () {
  952. function test(event) {
  953. ngTableEventsChannel['publish' + event](fakeTableParams);
  954. }
  955. supportedEvents.forEach(test);
  956. });
  957. it('publishing event should notify registered subscribers (one)', function(){
  958. function test(event){
  959. // given
  960. var cbCount = 0;
  961. ngTableEventsChannel['on' + event](function(){
  962. cbCount++;
  963. });
  964. // when
  965. ngTableEventsChannel['publish' + event](fakeTableParams);
  966. // then
  967. expect(cbCount).toBe(1);
  968. }
  969. supportedEvents.forEach(test);
  970. });
  971. it('publishing event should notify registered subscribers (multiple)', function(){
  972. function test(event){
  973. // given
  974. var cb1Count = 0;
  975. ngTableEventsChannel['on' + event](function(){
  976. cb1Count++;
  977. });
  978. var cb2Count = 0;
  979. ngTableEventsChannel['on' + event](function(){
  980. cb2Count++;
  981. });
  982. // when
  983. ngTableEventsChannel['publish' + event](fakeTableParams);
  984. // then
  985. expect(cb1Count).toBe(1);
  986. expect(cb2Count).toBe(1);
  987. }
  988. supportedEvents.forEach(test);
  989. });
  990. it('subscriber should be able to unregister their callback', function(){
  991. function test(event){
  992. // given
  993. var cbCount = 0;
  994. var subscription = ngTableEventsChannel['on' + event](function(){
  995. cbCount++;
  996. });
  997. ngTableEventsChannel['publish' + event](fakeTableParams);
  998. expect(cbCount).toBe(1); // checking assumptions
  999. expect(getSubscriberCount()).toBe(1); // checking assumptions
  1000. cbCount = 0; // reset
  1001. // when
  1002. subscription(); // unsubscribe
  1003. ngTableEventsChannel['publish' + event](fakeTableParams);
  1004. // then
  1005. expect(cbCount).toBe(0);
  1006. expect(getSubscriberCount()).toBe(0);
  1007. }
  1008. supportedEvents.forEach(test);
  1009. });
  1010. it('subscriber should be able specify the scope to receive events', function(){
  1011. // this is useful as it allows all subscriptions to be removed by calling $destroy on that scope
  1012. function test(event){
  1013. // given
  1014. var childScope = $rootScope.$new();
  1015. var cbCount = 0;
  1016. ngTableEventsChannel['on' + event](function(){
  1017. cbCount++;
  1018. }, childScope);
  1019. // when, then
  1020. ngTableEventsChannel['publish' + event](fakeTableParams);
  1021. expect(cbCount).toBe(1);
  1022. cbCount = 0; // reset
  1023. // when, then
  1024. childScope.$destroy();
  1025. ngTableEventsChannel['publish' + event](fakeTableParams);
  1026. // then
  1027. expect(cbCount).toBe(0);
  1028. }
  1029. supportedEvents.forEach(test);
  1030. });
  1031. it('should not notify subscribers who have filter out the publisher', function(){
  1032. function test(event){
  1033. // given
  1034. var cbCount = 0;
  1035. ngTableEventsChannel['on' + event](function(){
  1036. cbCount++;
  1037. }, function(publisher){
  1038. return publisher === fakeTableParams;
  1039. });
  1040. // when
  1041. ngTableEventsChannel['publish' + event](fakeTableParams);
  1042. var anoParams = {};
  1043. ngTableEventsChannel['publish' + event](anoParams);
  1044. // then
  1045. expect(cbCount).toBe(1);
  1046. }
  1047. supportedEvents.forEach(test);
  1048. });
  1049. it('should not notify subscribers who have filter not to receive event based on arg values', function(){
  1050. function test(event){
  1051. // given
  1052. var cbCount = 0;
  1053. ngTableEventsChannel['on' + event](function(){
  1054. cbCount++;
  1055. }, function(publisher, arg1){
  1056. return arg1 === 1;
  1057. });
  1058. // when
  1059. ngTableEventsChannel['publish' + event](fakeTableParams, 'cc');
  1060. ngTableEventsChannel['publish' + event](fakeTableParams, 1);
  1061. // then
  1062. expect(cbCount).toBe(1);
  1063. }
  1064. supportedEvents.forEach(test);
  1065. });
  1066. it('should support a shorthand for subscribers to receive events from specific NgTableParams instance', function () {
  1067. function test(event) {
  1068. // given
  1069. var cbCount = 0;
  1070. ngTableEventsChannel['on' + event](function () {
  1071. cbCount++;
  1072. }, fakeTableParams);
  1073. // when
  1074. ngTableEventsChannel['publish' + event](fakeTableParams);
  1075. var anoParams = {};
  1076. ngTableEventsChannel['publish' + event](anoParams);
  1077. // then
  1078. expect(cbCount).toBe(1);
  1079. }
  1080. supportedEvents.forEach(test);
  1081. });
  1082. it('publisher should be supplied to subscriber callback', function(){
  1083. function test(event){
  1084. // given
  1085. var cbCount = 0;
  1086. ngTableEventsChannel['on' + event](function(params){
  1087. actualPublisher = params;
  1088. });
  1089. // when
  1090. ngTableEventsChannel['publish' + event](fakeTableParams);
  1091. // then
  1092. expect(actualPublisher).toBe(fakeTableParams);
  1093. }
  1094. supportedEvents.forEach(test);
  1095. });
  1096. it('remaining event args should be supplied to subscriber callback', function(){
  1097. function test(event){
  1098. // given
  1099. ngTableEventsChannel['on' + event](function(params/*, ...args*/){
  1100. actualPublisher = params;
  1101. actualEventArgs = _.rest(arguments);
  1102. });
  1103. // when
  1104. var arg1 = [1, 2];
  1105. var arg2 = [1];
  1106. ngTableEventsChannel['publish' + event](fakeTableParams, arg1, arg2);
  1107. // then
  1108. expect(actualEventArgs).toEqual([arg1, arg2]);
  1109. }
  1110. supportedEvents.forEach(test);
  1111. });
  1112. it('subscribers should never receive events from null instance of tableParams', function(){
  1113. function test(event){
  1114. // given
  1115. var cbCount = 0;
  1116. ngTableEventsChannel['on' + event](function(params/*, ...args*/){
  1117. cbCount++;
  1118. });
  1119. // when
  1120. fakeTableParams.isNullInstance = true;
  1121. ngTableEventsChannel['publish' + event](fakeTableParams);
  1122. // then
  1123. expect(cbCount).toEqual(0);
  1124. }
  1125. supportedEvents.forEach(test);
  1126. });
  1127. });
  1128. describe('afterCreated', function(){
  1129. it('should fire when a new NgTableParams has been constructed', function(){
  1130. // given
  1131. ngTableEventsChannel.onAfterCreated(function(params){
  1132. actualPublisher = params;
  1133. });
  1134. // when
  1135. var params = createNgTableParams();
  1136. // then
  1137. expect(actualPublisher).toBe(params);
  1138. });
  1139. });
  1140. describe('afterReloadData', function(){
  1141. it('should fire when a reload completes', function(){
  1142. // given
  1143. ngTableEventsChannel.onAfterReloadData(function(params, newVal, oldVal){
  1144. actualPublisher = params;
  1145. actualEventArgs = [newVal, oldVal];
  1146. });
  1147. var newDatapage = [1, 5, 6];
  1148. var params = createNgTableParams({ getData: function(){
  1149. return newDatapage;
  1150. }});
  1151. // when
  1152. params.reload();
  1153. scope.$digest();
  1154. // then
  1155. expect(actualPublisher).toBe(params);
  1156. expect(actualEventArgs).toEqual([newDatapage, []]);
  1157. });
  1158. it('should fire on reload even if datapage remains the same array', function(){
  1159. // given
  1160. var callCount = 0;
  1161. ngTableEventsChannel.onAfterReloadData(function(/*params, newVal, oldVal*/){
  1162. callCount++;
  1163. });
  1164. var dataPage = [1,2,3];
  1165. var params = createNgTableParams({ getData: function(){
  1166. return dataPage;
  1167. }});
  1168. // when
  1169. params.reload();
  1170. scope.$digest();
  1171. params.reload();
  1172. scope.$digest();
  1173. // then
  1174. expect(callCount).toBe(2);
  1175. });
  1176. });
  1177. describe('pagesChanged', function(){
  1178. it('should fire when a reload completes', function(){
  1179. // given
  1180. ngTableEventsChannel.onPagesChanged(function(params, newVal, oldVal){
  1181. actualPublisher = params;
  1182. actualEventArgs = [newVal, oldVal];
  1183. });
  1184. var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: [1,2,3,4,5,6]});
  1185. // when
  1186. params.reload();
  1187. scope.$digest();
  1188. // then
  1189. var expectedPages = params.generatePagesArray(params.page(), params.total(), params.count());
  1190. expect(expectedPages.length).toBeGreaterThan(0); // checking assumptions
  1191. expect(actualEventArgs).toEqual([expectedPages, undefined]);
  1192. });
  1193. it('should fire when a reload completes - no data', function(){
  1194. // given
  1195. ngTableEventsChannel.onPagesChanged(function(params, newVal, oldVal){
  1196. actualPublisher = params;
  1197. actualEventArgs = [newVal, oldVal];
  1198. });
  1199. var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: []});
  1200. // when
  1201. params.reload();
  1202. scope.$digest();
  1203. // then
  1204. expect(actualEventArgs).toEqual([[], undefined]);
  1205. });
  1206. it('should fire when a reload completes (multiple)', function(){
  1207. // given
  1208. var callCount = 0;
  1209. ngTableEventsChannel.onPagesChanged(function(/*params, newVal, oldVal*/){
  1210. callCount++;
  1211. });
  1212. var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: [1,2,3,4,5,6]});
  1213. // when
  1214. params.reload();
  1215. scope.$digest();
  1216. params.page(2); // trigger a change to pages data structure
  1217. params.reload();
  1218. scope.$digest();
  1219. // then
  1220. expect(callCount).toBe(2);
  1221. });
  1222. it('should not fire on reload when pages remain the same', function(){
  1223. // given
  1224. var callCount = 0;
  1225. ngTableEventsChannel.onPagesChanged(function(/*params, newVal, oldVal*/){
  1226. callCount++;
  1227. });
  1228. var params = createNgTableParams({ count: 5 }, { counts: [5,10], data: [1,2,3,4,5,6]});
  1229. params.reload();
  1230. scope.$digest();
  1231. // when
  1232. params.reload();
  1233. scope.$digest();
  1234. // then
  1235. expect(callCount).toBe(1);
  1236. });
  1237. });
  1238. describe('datasetChanged', function(){
  1239. it('should fire when a initial dataset is supplied as a settings value', function(){
  1240. // given
  1241. ngTableEventsChannel.onDatasetChanged(function(params, newVal, oldVal){
  1242. actualPublisher = params;
  1243. actualEventArgs = [newVal, oldVal];
  1244. });
  1245. // when
  1246. var initialDs = [5, 10];
  1247. var params = createNgTableParams({ data: initialDs});
  1248. // then
  1249. expect(actualPublisher).toBe(params);
  1250. expect(actualEventArgs).toEqual([initialDs, null]);
  1251. });
  1252. it('should fire when a new dataset is supplied as a settings value', function(){
  1253. // given
  1254. var initialDs = [1, 2];
  1255. ngTableEventsChannel.onDatasetChanged(function(params, newVal, oldVal){
  1256. actualPublisher = params;
  1257. actualEventArgs = [newVal, oldVal];
  1258. });
  1259. var params = createNgTableParams({ data: initialDs});
  1260. // when
  1261. var newDs = [5, 10];
  1262. params.settings({ data: newDs});
  1263. // then
  1264. expect(actualPublisher).toBe(params);
  1265. expect(actualEventArgs).toEqual([newDs, initialDs]);
  1266. });
  1267. it('should fire when a dataset is removed from settings value', function(){
  1268. // given
  1269. var initialDs = [1, 2];
  1270. ngTableEventsChannel.onDatasetChanged(function(params, newVal, oldVal){
  1271. actualPublisher = params;
  1272. actualEventArgs = [newVal, oldVal];
  1273. });
  1274. var params = createNgTableParams({ data: initialDs});
  1275. // when
  1276. var newDs = null;
  1277. params.settings({ data: newDs});
  1278. // then
  1279. expect(actualPublisher).toBe(params);
  1280. expect(actualEventArgs).toEqual([newDs, initialDs]);
  1281. });
  1282. it('should NOT fire when the same data array is supplied as a new settings value', function(){
  1283. // given
  1284. var callCount = 0;
  1285. var initialDs = [1, 2];
  1286. ngTableEventsChannel.onDatasetChanged(function(/*params, newVal, oldVal*/){
  1287. callCount++;
  1288. });
  1289. var params = createNgTableParams({ data: initialDs});
  1290. // when
  1291. params.settings({ data: initialDs});
  1292. // then
  1293. expect(callCount).toBe(1);
  1294. });
  1295. it('settings().data on publisher should reference the new dataset', function(){
  1296. var initialDs = [1, 2];
  1297. var newDs = [1, 2, 3];
  1298. var params = createNgTableParams({ data: initialDs});
  1299. ngTableEventsChannel.onDatasetChanged(function(params, newVal/*, oldVal*/){
  1300. expect(params.settings().data).toBe(newVal);
  1301. });
  1302. params.settings({ data: newDs});
  1303. });
  1304. });
  1305. })
  1306. });