vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

513 lines
16 KiB

  1. var assert = require('assert');
  2. var DataSet = require('../lib/DataSet');
  3. var Queue = require('../lib/Queue');
  4. // TODO: test the source code immediately, but this is ES6
  5. var now = new Date();
  6. describe('DataSet', function () {
  7. it('should work', function () {
  8. // TODO: improve DataSet tests, split up in one test per function
  9. var data = new DataSet({
  10. type: {
  11. start: 'Date',
  12. end: 'Date'
  13. }
  14. });
  15. // add single items with different date types
  16. data.add({id: 1, content: 'Item 1', start: new Date(now.valueOf())});
  17. data.add({id: 2, content: 'Item 2', start: now.toISOString()});
  18. data.add([
  19. //{id: 3, content: 'Item 3', start: moment(now)}, // TODO: moment fails, not the same instance
  20. {id: 3, content: 'Item 3', start: now},
  21. {id: 4, content: 'Item 4', start: '/Date(' + now.valueOf() + ')/'}
  22. ]);
  23. var items = data.get();
  24. assert.equal(data.length, 4);
  25. assert.equal(items.length, 4);
  26. items.forEach(function (item) {
  27. assert.ok(item.start instanceof Date);
  28. });
  29. // get filtered fields only
  30. var sort = function (a, b) {
  31. return a.id > b.id;
  32. };
  33. assert.deepEqual(data.get({
  34. fields: ['id', 'content']
  35. }).sort(sort), [
  36. {id: 1, content: 'Item 1'},
  37. {id: 2, content: 'Item 2'},
  38. {id: 3, content: 'Item 3'},
  39. {id: 4, content: 'Item 4'}
  40. ]);
  41. // convert dates
  42. assert.deepEqual(data.get({
  43. fields: ['id', 'start'],
  44. type: {start: 'Number'}
  45. }).sort(sort), [
  46. {id: 1, start: now.valueOf()},
  47. {id: 2, start: now.valueOf()},
  48. {id: 3, start: now.valueOf()},
  49. {id: 4, start: now.valueOf()}
  50. ]);
  51. // get a single item
  52. assert.deepEqual(data.get(1, {
  53. fields: ['id', 'start'],
  54. type: {start: 'ISODate'}
  55. }), {
  56. id: 1,
  57. start: now.toISOString()
  58. });
  59. // remove an item
  60. data.remove(2);
  61. assert.deepEqual(data.get({
  62. fields: ['id']
  63. }).sort(sort), [
  64. {id: 1},
  65. {id: 3},
  66. {id: 4}
  67. ]);
  68. assert.equal(data.length, 3);
  69. // add an item
  70. data.add({id: 5, content: 'Item 5', start: now.valueOf()});
  71. assert.deepEqual(data.get({
  72. fields: ['id']
  73. }).sort(sort), [
  74. {id: 1},
  75. {id: 3},
  76. {id: 4},
  77. {id: 5}
  78. ]);
  79. assert.equal(data.length, 4);
  80. // update an item
  81. data.update({id: 5, content: 'changed!'}); // update item (extend existing fields)
  82. assert.equal(data.length, 4);
  83. data.remove(3); // remove existing item
  84. assert.equal(data.length, 3);
  85. data.add({id: 3, other: 'bla'}); // add new item
  86. assert.equal(data.length, 4);
  87. data.update({id: 6, content: 'created!', start: now.valueOf()}); // this item is not yet existing, create it
  88. assert.equal(data.length, 5);
  89. assert.deepEqual(data.get().sort(sort), [
  90. {id: 1, content: 'Item 1', start: now},
  91. {id: 3, other: 'bla'},
  92. {id: 4, content: 'Item 4', start: now},
  93. {id: 5, content: 'changed!', start: now},
  94. {id: 6, content: 'created!', start: now}
  95. ]);
  96. assert.equal(data.length, 5);
  97. data.clear();
  98. assert.equal(data.length, 0);
  99. assert.equal(data.get().length, 0);
  100. // test filtering and sorting
  101. data = new DataSet();
  102. data.add([
  103. {id: 1, age: 30, group: 2},
  104. {id: 2, age: 25, group: 4},
  105. {id: 3, age: 17, group: 2},
  106. {id: 4, age: 27, group: 3}
  107. ]);
  108. assert.deepEqual(data.get({order: 'age'}), [
  109. {id: 3, age: 17, group: 2},
  110. {id: 2, age: 25, group: 4},
  111. {id: 4, age: 27, group: 3},
  112. {id: 1, age: 30, group: 2}
  113. ]);
  114. assert.deepEqual(data.getIds({order: 'age'}), [3, 2, 4, 1]);
  115. assert.deepEqual(data.get({order: 'age', fields: ['id']}), [
  116. {id: 3},
  117. {id: 2},
  118. {id: 4},
  119. {id: 1}
  120. ]);
  121. assert.deepEqual(data.get({
  122. order: 'age',
  123. filter: function (item) {
  124. return item.group == 2;
  125. },
  126. fields: ['id']
  127. }), [
  128. {id: 3},
  129. {id: 1}
  130. ]);
  131. assert.deepEqual(data.getIds({
  132. order: 'age',
  133. filter: function (item) {
  134. return (item.group == 2);
  135. }
  136. }), [3, 1]);
  137. data.clear();
  138. // test if the setting of the showInternalIds works locally for a single get request
  139. data.add({content: 'Item 1'});
  140. data.add({content: 'Item 2'});
  141. assert.notStrictEqual(data.get()[0].id, undefined);
  142. // create a dataset with initial data
  143. var data = new DataSet([
  144. {id: 1, content: 'Item 1', start: new Date(now.valueOf())},
  145. {id: 2, content: 'Item 2', start: now.toISOString()}
  146. ]);
  147. assert.deepEqual(data.getIds(), [1, 2]);
  148. // create a dataset with initial data and options
  149. var data = new DataSet([
  150. {_id: 1, content: 'Item 1', start: new Date(now.valueOf())},
  151. {_id: 2, content: 'Item 2', start: now.toISOString()}
  152. ], {fieldId: '_id'});
  153. assert.deepEqual(data.getIds(), [1, 2]);
  154. });
  155. it('constructor should prevent duplicate ids', function () {
  156. assert.throws(function () { new DataSet([{id: 'duplicate'}, {id: 'duplicate'}]) }, Error, "duplicate id throws error");
  157. });
  158. it('add should prevent duplicate ids', function () {
  159. var dataset = new DataSet([{id: 'duplicate'}]);
  160. assert.throws(function () { dataset.add({id: 'duplicate'}) }, Error, "duplicate id throws error");
  161. });
  162. it('should queue and flush changes', function () {
  163. var options = {queue: true};
  164. var dataset = new DataSet([
  165. {id: 1, content: 'Item 1'},
  166. {id: 2, content: 'Item 2'}
  167. ], options);
  168. assert.deepEqual(dataset.get(), [
  169. {id: 1, content: 'Item 1'},
  170. {id: 2, content: 'Item 2'}
  171. ]);
  172. dataset.add({id: 3, content: 'Item 3'});
  173. dataset.update({id: 1, content: 'Item 1 (updated)'});
  174. dataset.remove(2);
  175. assert.deepEqual(dataset.get(), [
  176. {id: 1, content: 'Item 1'},
  177. {id: 2, content: 'Item 2'}
  178. ]);
  179. dataset.flush();
  180. assert.deepEqual(dataset.get(), [
  181. {id: 1, content: 'Item 1 (updated)'},
  182. {id: 3, content: 'Item 3'}
  183. ]);
  184. });
  185. it('should queue and flush changes after a timeout', function (done) {
  186. var options = {queue: {delay: 100}};
  187. var dataset = new DataSet([
  188. {id: 1, content: 'Item 1'},
  189. {id: 2, content: 'Item 2'}
  190. ], options);
  191. assert.deepEqual(dataset.get(), [
  192. {id: 1, content: 'Item 1'},
  193. {id: 2, content: 'Item 2'}
  194. ]);
  195. dataset.add({id: 3, content: 'Item 3'});
  196. dataset.update({id: 1, content: 'Item 1 (updated)'});
  197. dataset.remove(2);
  198. assert.deepEqual(dataset.get(), [
  199. {id: 1, content: 'Item 1'},
  200. {id: 2, content: 'Item 2'}
  201. ]);
  202. setTimeout(function () {
  203. assert.deepEqual(dataset.get(), [
  204. {id: 1, content: 'Item 1 (updated)'},
  205. {id: 3, content: 'Item 3'}
  206. ]);
  207. done();
  208. }, 200)
  209. });
  210. it('should remove a queue from the dataset', function () {
  211. var options = {queue: true};
  212. var dataset = new DataSet([
  213. {id: 1, content: 'Item 1'},
  214. {id: 2, content: 'Item 2'}
  215. ], options);
  216. assert.deepEqual(dataset.get(), [
  217. {id: 1, content: 'Item 1'},
  218. {id: 2, content: 'Item 2'}
  219. ]);
  220. dataset.add({id: 3, content: 'Item 3'});
  221. dataset.update({id: 1, content: 'Item 1 (updated)'});
  222. dataset.remove(2);
  223. assert.deepEqual(dataset.get(), [
  224. {id: 1, content: 'Item 1'},
  225. {id: 2, content: 'Item 2'}
  226. ]);
  227. dataset.setOptions({queue: false}); // remove queue, should flush changes
  228. assert.deepEqual(dataset.get(), [
  229. {id: 1, content: 'Item 1 (updated)'},
  230. {id: 3, content: 'Item 3'}
  231. ]);
  232. dataset.add({id: 4, content: 'Item 4'});
  233. assert.deepEqual(dataset.get(), [
  234. {id: 1, content: 'Item 1 (updated)'},
  235. {id: 3, content: 'Item 3'},
  236. {id: 4, content: 'Item 4'}
  237. ]);
  238. });
  239. describe('add', function () {
  240. it('adds nothing for an empty array', function () {
  241. var dataset = new DataSet([]);
  242. var dataItems = [];
  243. assert.equal(dataset.add(dataItems).length, 0)
  244. });
  245. it('adds items of an array', function () {
  246. var dataset = new DataSet([]);
  247. var dataItems = [
  248. {_id: 1, content: 'Item 1', start: new Date(now.valueOf())},
  249. {_id: 2, content: 'Item 2', start: new Date(now.valueOf())}
  250. ];
  251. assert.equal(dataset.add(dataItems).length, 2)
  252. });
  253. it('adds a single object', function () {
  254. var dataset = new DataSet([]);
  255. var dataItem = {_id: 1, content: 'Item 1', start: new Date(now.valueOf())};
  256. assert.equal(dataset.add(dataItem).length, 1)
  257. });
  258. it('throws an error when passed bad datatypes', function () {
  259. var dataset = new DataSet([]);
  260. assert.throws(function () { dataset.add(null) }, Error, "null type throws error");
  261. assert.throws(function () { dataset.add(undefined) }, Error, "undefined type throws error");
  262. });
  263. });
  264. describe('setOptions', function () {
  265. var dataset = new DataSet([
  266. {_id: 1, content: 'Item 1', start: new Date(now.valueOf())}
  267. ], {queue: true});
  268. it('does not update queue when passed an undefined queue', function () {
  269. var dataset = new DataSet([], {queue: true});
  270. dataset.setOptions({queue: undefined});
  271. assert.notEqual(dataset._queue, undefined)
  272. });
  273. it('destroys the queue when queue set to false', function () {
  274. var dataset = new DataSet([]);
  275. dataset.setOptions({queue: false});
  276. assert.equal(dataset._queue, undefined)
  277. });
  278. it('udpates queue options', function () {
  279. var dataset = new DataSet([]);
  280. dataset.setOptions({queue: {max: 5, delay: 3}});
  281. assert.equal(dataset._queue.max, 5);
  282. assert.equal(dataset._queue.delay, 3);
  283. });
  284. it('creates new queue given if none is set', function () {
  285. var dataset = new DataSet([], {queue: true});
  286. dataset._queue.destroy();
  287. dataset._queue = null;
  288. dataset.setOptions({queue: {max: 5, delay: 3}});
  289. assert.equal(dataset._queue.max, 5);
  290. assert.equal(dataset._queue.delay, 3);
  291. });
  292. });
  293. describe('on / off', function () {
  294. var dataset = new DataSet([
  295. {_id: 1, content: 'Item 1', start: new Date(now.valueOf())}
  296. ]);
  297. var count = 0;
  298. function inc() {count++;}
  299. it('fires for put', function () {
  300. var dataset = new DataSet([]);
  301. count = 0;
  302. // on
  303. dataset.on('add', inc);
  304. dataset.add({_id: 1, content: 'Item 1', start: new Date(now.valueOf())});
  305. assert.equal(count, 1);
  306. // off
  307. dataset.off('add', inc);
  308. dataset.add({_id: 2, content: 'Item 2', start: new Date(now.valueOf())});
  309. assert.equal(count, 1);
  310. });
  311. it('fires for remove', function () {
  312. var dataset = new DataSet([]);
  313. count = 0;
  314. // on
  315. dataset.on('remove', inc);
  316. var id = dataset.add({_id: 1, content: 'Item 1', start: new Date(now.valueOf())});
  317. dataset.remove(id);
  318. assert.equal(count, 1);
  319. // off
  320. dataset.off('remove', inc);
  321. id = dataset.add({_id: 1, content: 'Item 1', start: new Date(now.valueOf())});
  322. dataset.remove(id);
  323. assert.equal(count, 1);
  324. });
  325. it('fires for update', function () {
  326. var dataset = new DataSet([]);
  327. count = 0;
  328. // on
  329. dataset.on('update', inc);
  330. var id = dataset.add({_id: 1, content: 'Item 1', start: new Date(now.valueOf())});
  331. dataset.update({id: id, content: 'beep boop'});
  332. assert.equal(count, 1);
  333. // off
  334. dataset.off('update', inc);
  335. id = dataset.add({_id: 1, content: 'Item 1', start: new Date(now.valueOf())});
  336. dataset.update({id: id, content: 'beep boop'});
  337. assert.equal(count, 1);
  338. });
  339. });
  340. describe('min', function () {
  341. it('finds the minimum value', function () {
  342. var dataset = new DataSet([{id: 1}, {id: 2}, {id: 3}]);
  343. var minValue = dataset.min('id');
  344. assert.deepEqual(minValue, {id: 1});
  345. });
  346. it('returns null for empty dataset', function () {
  347. var dataset = new DataSet([]);
  348. var minValue = dataset.min('id');
  349. assert.equal(minValue, null);
  350. });
  351. it('ignores undefined values', function () {
  352. var dataset = new DataSet([{id: undefined}, {id: 1}, {id: 2}, {id: 3}]);
  353. var minValue = dataset.min('id');
  354. assert.deepEqual(minValue, {id: 1});
  355. });
  356. it('handles big values', function () {
  357. var dataset = new DataSet([{id: 10000000000000001}, {id: 10000000000000002}, {id: 10000000000000003}]);
  358. var minValue = dataset.min('id');
  359. assert.deepEqual(minValue, {id: 10000000000000001});
  360. });
  361. xit('handles big values - but not really, because of javascript number handling', function () {
  362. var dataset = new DataSet([{id: -10000000000000001}, {id: -10000000000000002}, {id: -10000000000000003}]);
  363. var minValue = dataset.min('id');
  364. assert.deepEqual(minValue, {id: -10000000000000003});
  365. assert.equal('' + minValue.id, '-10000000000000003')
  366. });
  367. });
  368. describe('max', function () {
  369. it('finds the maximum value', function () {
  370. var dataset = new DataSet([{id: 1}, {id: 2}, {id: 3}]);
  371. var maxValue = dataset.max('id');
  372. assert.deepEqual(maxValue, {id: 3});
  373. });
  374. it('returns null for empty dataset', function () {
  375. var dataset = new DataSet([]);
  376. var maxValue = dataset.max('id');
  377. assert.equal(maxValue, null);
  378. });
  379. it('ignores undefined values', function () {
  380. var dataset = new DataSet([{id: undefined}, {id: 1}, {id: 2}, {id: 3}]);
  381. var maxValue = dataset.max('id');
  382. assert.deepEqual(maxValue, {id: 3});
  383. });
  384. xit('handles big values - but not really, because of javascript number handling', function () {
  385. var dataset = new DataSet([{id: 10000000000000001}, {id: 10000000000000002}, {id: 10000000000000003}]);
  386. var maxValue = dataset.max('id');
  387. assert.deepEqual(maxValue, {id: 10000000000000003});
  388. assert.equal('' + maxValue.id, '10000000000000003')
  389. });
  390. xit('handles negative values - This does not work because of javascript', function () {
  391. var dataset = new DataSet([{id: -10000000000000001}, {id: -10000000000000002}, {id: -10000000000000003}]);
  392. var maxValue = dataset.max('id');
  393. assert.deepEqual(maxValue, {id: -10000000000000001});
  394. });
  395. });
  396. describe('distinct', function () {
  397. it('finds distinct values', function () {
  398. var dataset = new DataSet([{val: 1}, {val: 2}, {val: 3}]);
  399. var distinctValues = dataset.distinct('val');
  400. assert.deepEqual(distinctValues, [1, 2, 3]);
  401. });
  402. it('returns empty list for empty dataset', function () {
  403. var dataset = new DataSet([]);
  404. var distinctValues = dataset.distinct('val');
  405. assert.deepEqual(distinctValues, []);
  406. });
  407. it('ignores undefined values', function () {
  408. var dataset = new DataSet([{val: undefined}, {val: 1}, {val: 2}, {val: 3}]);
  409. var distinctValues = dataset.distinct('val');
  410. assert.deepEqual(distinctValues, [1, 2, 3]);
  411. });
  412. xit('handles big values - but not really, because of javascript number handling', function () {
  413. var dataset = new DataSet([{val: 10000000000000001}, {val: 10000000000000002}, {val: 10000000000000003}, {val: 10000000000000004}]);
  414. var distinctValues = dataset.distinct('val');
  415. assert.deepEqual(distinctValues, [ 10000000000000000, 10000000000000002, 10000000000000003, 10000000000000004]);
  416. });
  417. xit('handles negative values - This does not work because of javascript', function () {
  418. var dataset = new DataSet([{val: -10000000000000001}, {val: -10000000000000002}, {val: -10000000000000003}, {val: -10000000000000004}]);
  419. var distinctValues = dataset.distinct('val');
  420. assert.deepEqual(distinctValues, [ -10000000000000000, -10000000000000002, -10000000000000003, -10000000000000004]);
  421. });
  422. });
  423. describe('getDataSet', function () {
  424. it('returns this', function () {
  425. var dataset = new DataSet([{val: 1}, {val: 2}, {val: 3}]);
  426. assert.equal(dataset, dataset.getDataSet());
  427. });
  428. });
  429. });