core.plugin.tests.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. describe('Chart.plugins', function() {
  2. beforeEach(function() {
  3. this._plugins = Chart.plugins.getAll();
  4. Chart.plugins.clear();
  5. });
  6. afterEach(function() {
  7. Chart.plugins.clear();
  8. Chart.plugins.register(this._plugins);
  9. delete this._plugins;
  10. });
  11. describe('Chart.plugins.register', function() {
  12. it('should register a plugin', function() {
  13. Chart.plugins.register({});
  14. expect(Chart.plugins.count()).toBe(1);
  15. Chart.plugins.register({});
  16. expect(Chart.plugins.count()).toBe(2);
  17. });
  18. it('should register an array of plugins', function() {
  19. Chart.plugins.register([{}, {}, {}]);
  20. expect(Chart.plugins.count()).toBe(3);
  21. });
  22. it('should succeed to register an already registered plugin', function() {
  23. var plugin = {};
  24. Chart.plugins.register(plugin);
  25. expect(Chart.plugins.count()).toBe(1);
  26. Chart.plugins.register(plugin);
  27. expect(Chart.plugins.count()).toBe(1);
  28. Chart.plugins.register([{}, plugin, plugin]);
  29. expect(Chart.plugins.count()).toBe(2);
  30. });
  31. });
  32. describe('Chart.plugins.unregister', function() {
  33. it('should unregister a plugin', function() {
  34. var plugin = {};
  35. Chart.plugins.register(plugin);
  36. expect(Chart.plugins.count()).toBe(1);
  37. Chart.plugins.unregister(plugin);
  38. expect(Chart.plugins.count()).toBe(0);
  39. });
  40. it('should unregister an array of plugins', function() {
  41. var plugins = [{}, {}, {}];
  42. Chart.plugins.register(plugins);
  43. expect(Chart.plugins.count()).toBe(3);
  44. Chart.plugins.unregister(plugins.slice(0, 2));
  45. expect(Chart.plugins.count()).toBe(1);
  46. });
  47. it('should succeed to unregister a plugin not registered', function() {
  48. var plugin = {};
  49. Chart.plugins.register(plugin);
  50. expect(Chart.plugins.count()).toBe(1);
  51. Chart.plugins.unregister({});
  52. expect(Chart.plugins.count()).toBe(1);
  53. Chart.plugins.unregister([{}, plugin]);
  54. expect(Chart.plugins.count()).toBe(0);
  55. });
  56. });
  57. describe('Chart.plugins.notify', function() {
  58. it('should call inline plugins with arguments', function() {
  59. var plugin = {hook: function() {}};
  60. var chart = window.acquireChart({
  61. plugins: [plugin]
  62. });
  63. spyOn(plugin, 'hook');
  64. Chart.plugins.notify(chart, 'hook', 42);
  65. expect(plugin.hook.calls.count()).toBe(1);
  66. expect(plugin.hook.calls.first().args[0]).toBe(chart);
  67. expect(plugin.hook.calls.first().args[1]).toBe(42);
  68. expect(plugin.hook.calls.first().args[2]).toEqual({});
  69. });
  70. it('should call global plugins with arguments', function() {
  71. var plugin = {hook: function() {}};
  72. var chart = window.acquireChart({});
  73. spyOn(plugin, 'hook');
  74. Chart.plugins.register(plugin);
  75. Chart.plugins.notify(chart, 'hook', 42);
  76. expect(plugin.hook.calls.count()).toBe(1);
  77. expect(plugin.hook.calls.first().args[0]).toBe(chart);
  78. expect(plugin.hook.calls.first().args[1]).toBe(42);
  79. expect(plugin.hook.calls.first().args[2]).toEqual({});
  80. });
  81. it('should call plugin only once even if registered multiple times', function() {
  82. var plugin = {hook: function() {}};
  83. var chart = window.acquireChart({
  84. plugins: [plugin, plugin]
  85. });
  86. spyOn(plugin, 'hook');
  87. Chart.plugins.register([plugin, plugin]);
  88. Chart.plugins.notify(chart, 'hook');
  89. expect(plugin.hook.calls.count()).toBe(1);
  90. });
  91. it('should call plugins in the correct order (global first)', function() {
  92. var results = [];
  93. var chart = window.acquireChart({
  94. plugins: [{
  95. hook: function() {
  96. results.push(1);
  97. }
  98. }, {
  99. hook: function() {
  100. results.push(2);
  101. }
  102. }, {
  103. hook: function() {
  104. results.push(3);
  105. }
  106. }]
  107. });
  108. Chart.plugins.register([{
  109. hook: function() {
  110. results.push(4);
  111. }
  112. }, {
  113. hook: function() {
  114. results.push(5);
  115. }
  116. }, {
  117. hook: function() {
  118. results.push(6);
  119. }
  120. }]);
  121. var ret = Chart.plugins.notify(chart, 'hook');
  122. expect(ret).toBeTruthy();
  123. expect(results).toEqual([4, 5, 6, 1, 2, 3]);
  124. });
  125. it('should return TRUE if no plugin explicitly returns FALSE', function() {
  126. var chart = window.acquireChart({
  127. plugins: [{
  128. hook: function() {}
  129. }, {
  130. hook: function() {
  131. return null;
  132. }
  133. }, {
  134. hook: function() {
  135. return 0;
  136. }
  137. }, {
  138. hook: function() {
  139. return true;
  140. }
  141. }, {
  142. hook: function() {
  143. return 1;
  144. }
  145. }]
  146. });
  147. var plugins = chart.config.plugins;
  148. plugins.forEach(function(plugin) {
  149. spyOn(plugin, 'hook').and.callThrough();
  150. });
  151. var ret = Chart.plugins.notify(chart, 'hook');
  152. expect(ret).toBeTruthy();
  153. plugins.forEach(function(plugin) {
  154. expect(plugin.hook).toHaveBeenCalled();
  155. });
  156. });
  157. it('should return FALSE if any plugin explicitly returns FALSE', function() {
  158. var chart = window.acquireChart({
  159. plugins: [{
  160. hook: function() {}
  161. }, {
  162. hook: function() {
  163. return null;
  164. }
  165. }, {
  166. hook: function() {
  167. return false;
  168. }
  169. }, {
  170. hook: function() {
  171. return 42;
  172. }
  173. }, {
  174. hook: function() {
  175. return 'bar';
  176. }
  177. }]
  178. });
  179. var plugins = chart.config.plugins;
  180. plugins.forEach(function(plugin) {
  181. spyOn(plugin, 'hook').and.callThrough();
  182. });
  183. var ret = Chart.plugins.notify(chart, 'hook');
  184. expect(ret).toBeFalsy();
  185. expect(plugins[0].hook).toHaveBeenCalled();
  186. expect(plugins[1].hook).toHaveBeenCalled();
  187. expect(plugins[2].hook).toHaveBeenCalled();
  188. expect(plugins[3].hook).not.toHaveBeenCalled();
  189. expect(plugins[4].hook).not.toHaveBeenCalled();
  190. });
  191. });
  192. describe('config.options.plugins', function() {
  193. it('should call plugins with options at last argument', function() {
  194. var plugin = {id: 'foo', hook: function() {}};
  195. var chart = window.acquireChart({
  196. options: {
  197. plugins: {
  198. foo: {a: '123'},
  199. }
  200. }
  201. });
  202. spyOn(plugin, 'hook');
  203. Chart.plugins.register(plugin);
  204. Chart.plugins.notify(chart, 'hook');
  205. Chart.plugins.notify(chart, 'hook', ['bla']);
  206. Chart.plugins.notify(chart, 'hook', ['bla', 42]);
  207. expect(plugin.hook.calls.count()).toBe(3);
  208. expect(plugin.hook.calls.argsFor(0)[1]).toEqual({a: '123'});
  209. expect(plugin.hook.calls.argsFor(1)[2]).toEqual({a: '123'});
  210. expect(plugin.hook.calls.argsFor(2)[3]).toEqual({a: '123'});
  211. });
  212. it('should call plugins with options associated to their identifier', function() {
  213. var plugins = {
  214. a: {id: 'a', hook: function() {}},
  215. b: {id: 'b', hook: function() {}},
  216. c: {id: 'c', hook: function() {}}
  217. };
  218. Chart.plugins.register(plugins.a);
  219. var chart = window.acquireChart({
  220. plugins: [plugins.b, plugins.c],
  221. options: {
  222. plugins: {
  223. a: {a: '123'},
  224. b: {b: '456'},
  225. c: {c: '789'}
  226. }
  227. }
  228. });
  229. spyOn(plugins.a, 'hook');
  230. spyOn(plugins.b, 'hook');
  231. spyOn(plugins.c, 'hook');
  232. Chart.plugins.notify(chart, 'hook');
  233. expect(plugins.a.hook).toHaveBeenCalled();
  234. expect(plugins.b.hook).toHaveBeenCalled();
  235. expect(plugins.c.hook).toHaveBeenCalled();
  236. expect(plugins.a.hook.calls.first().args[1]).toEqual({a: '123'});
  237. expect(plugins.b.hook.calls.first().args[1]).toEqual({b: '456'});
  238. expect(plugins.c.hook.calls.first().args[1]).toEqual({c: '789'});
  239. });
  240. it('should not called plugins when config.options.plugins.{id} is FALSE', function() {
  241. var plugins = {
  242. a: {id: 'a', hook: function() {}},
  243. b: {id: 'b', hook: function() {}},
  244. c: {id: 'c', hook: function() {}}
  245. };
  246. Chart.plugins.register(plugins.a);
  247. var chart = window.acquireChart({
  248. plugins: [plugins.b, plugins.c],
  249. options: {
  250. plugins: {
  251. a: false,
  252. b: false
  253. }
  254. }
  255. });
  256. spyOn(plugins.a, 'hook');
  257. spyOn(plugins.b, 'hook');
  258. spyOn(plugins.c, 'hook');
  259. Chart.plugins.notify(chart, 'hook');
  260. expect(plugins.a.hook).not.toHaveBeenCalled();
  261. expect(plugins.b.hook).not.toHaveBeenCalled();
  262. expect(plugins.c.hook).toHaveBeenCalled();
  263. });
  264. it('should call plugins with default options when plugin options is TRUE', function() {
  265. var plugin = {id: 'a', hook: function() {}};
  266. Chart.defaults.global.plugins.a = {a: 42};
  267. Chart.plugins.register(plugin);
  268. var chart = window.acquireChart({
  269. options: {
  270. plugins: {
  271. a: true
  272. }
  273. }
  274. });
  275. spyOn(plugin, 'hook');
  276. Chart.plugins.notify(chart, 'hook');
  277. expect(plugin.hook).toHaveBeenCalled();
  278. expect(plugin.hook.calls.first().args[1]).toEqual({a: 42});
  279. });
  280. it('should call plugins with default options if plugin config options is undefined', function() {
  281. var plugin = {id: 'a', hook: function() {}};
  282. Chart.defaults.global.plugins.a = {a: 'foobar'};
  283. Chart.plugins.register(plugin);
  284. spyOn(plugin, 'hook');
  285. var chart = window.acquireChart();
  286. Chart.plugins.notify(chart, 'hook');
  287. expect(plugin.hook).toHaveBeenCalled();
  288. expect(plugin.hook.calls.first().args[1]).toEqual({a: 'foobar'});
  289. delete Chart.defaults.global.plugins.a;
  290. });
  291. // https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
  292. it('should invalidate cache when update plugin options', function() {
  293. var plugin = {id: 'a', hook: function() {}};
  294. var chart = window.acquireChart({
  295. plugins: [plugin],
  296. options: {
  297. plugins: {
  298. a: {
  299. foo: 'foo'
  300. }
  301. }
  302. },
  303. });
  304. spyOn(plugin, 'hook');
  305. Chart.plugins.notify(chart, 'hook');
  306. expect(plugin.hook).toHaveBeenCalled();
  307. expect(plugin.hook.calls.first().args[1]).toEqual({foo: 'foo'});
  308. chart.options.plugins.a = {bar: 'bar'};
  309. chart.update();
  310. plugin.hook.calls.reset();
  311. Chart.plugins.notify(chart, 'hook');
  312. expect(plugin.hook).toHaveBeenCalled();
  313. expect(plugin.hook.calls.first().args[1]).toEqual({bar: 'bar'});
  314. });
  315. });
  316. });