jasmine.utils.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /* global __karma__ */
  2. function loadJSON(url, callback) {
  3. var request = new XMLHttpRequest();
  4. request.onreadystatechange = function() {
  5. if (request.readyState === 4) {
  6. return callback(JSON.parse(request.responseText));
  7. }
  8. };
  9. request.overrideMimeType('application/json');
  10. request.open('GET', url, true);
  11. request.send(null);
  12. }
  13. function createCanvas(w, h) {
  14. var canvas = document.createElement('canvas');
  15. canvas.width = w;
  16. canvas.height = h;
  17. return canvas;
  18. }
  19. function readImageData(url, callback) {
  20. var image = new Image();
  21. image.onload = function() {
  22. var h = image.height;
  23. var w = image.width;
  24. var canvas = createCanvas(w, h);
  25. var ctx = canvas.getContext('2d');
  26. ctx.drawImage(image, 0, 0, w, h);
  27. callback(ctx.getImageData(0, 0, w, h));
  28. };
  29. image.src = url;
  30. }
  31. /**
  32. * Injects a new canvas (and div wrapper) and creates teh associated Chart instance
  33. * using the given config. Additional options allow tweaking elements generation.
  34. * @param {object} config - Chart config.
  35. * @param {object} options - Chart acquisition options.
  36. * @param {object} options.canvas - Canvas attributes.
  37. * @param {object} options.wrapper - Canvas wrapper attributes.
  38. * @param {boolean} options.persistent - If true, the chart will not be released after the spec.
  39. */
  40. function acquireChart(config, options) {
  41. var wrapper = document.createElement('div');
  42. var canvas = document.createElement('canvas');
  43. var chart, key;
  44. config = config || {};
  45. options = options || {};
  46. options.canvas = options.canvas || {height: 512, width: 512};
  47. options.wrapper = options.wrapper || {class: 'chartjs-wrapper'};
  48. for (key in options.canvas) {
  49. if (options.canvas.hasOwnProperty(key)) {
  50. canvas.setAttribute(key, options.canvas[key]);
  51. }
  52. }
  53. for (key in options.wrapper) {
  54. if (options.wrapper.hasOwnProperty(key)) {
  55. wrapper.setAttribute(key, options.wrapper[key]);
  56. }
  57. }
  58. // by default, remove chart animation and auto resize
  59. config.options = config.options || {};
  60. config.options.animation = config.options.animation === undefined ? false : config.options.animation;
  61. config.options.responsive = config.options.responsive === undefined ? false : config.options.responsive;
  62. config.options.defaultFontFamily = config.options.defaultFontFamily || 'Arial';
  63. wrapper.appendChild(canvas);
  64. window.document.body.appendChild(wrapper);
  65. try {
  66. chart = new Chart(canvas.getContext('2d'), config);
  67. } catch (e) {
  68. window.document.body.removeChild(wrapper);
  69. throw e;
  70. }
  71. chart.$test = {
  72. persistent: options.persistent,
  73. wrapper: wrapper
  74. };
  75. return chart;
  76. }
  77. function releaseChart(chart) {
  78. chart.destroy();
  79. var wrapper = (chart.$test || {}).wrapper;
  80. if (wrapper && wrapper.parentNode) {
  81. wrapper.parentNode.removeChild(wrapper);
  82. }
  83. }
  84. function injectCSS(css) {
  85. // http://stackoverflow.com/q/3922139
  86. var head = document.getElementsByTagName('head')[0];
  87. var style = document.createElement('style');
  88. style.setAttribute('type', 'text/css');
  89. if (style.styleSheet) { // IE
  90. style.styleSheet.cssText = css;
  91. } else {
  92. style.appendChild(document.createTextNode(css));
  93. }
  94. head.appendChild(style);
  95. }
  96. function specFromFixture(description, inputs) {
  97. it(inputs.json, function(done) {
  98. loadJSON(inputs.json, function(json) {
  99. var chart = acquireChart(json.config, json.options);
  100. if (!inputs.png) {
  101. fail('Missing PNG comparison file for ' + inputs.json);
  102. done();
  103. }
  104. readImageData(inputs.png, function(expected) {
  105. expect(chart).toEqualImageData(expected, json);
  106. releaseChart(chart);
  107. done();
  108. });
  109. });
  110. });
  111. }
  112. function specsFromFixtures(path) {
  113. var regex = new RegExp('(^/base/test/fixtures/' + path + '.+)\\.(png|json)');
  114. var inputs = {};
  115. Object.keys(__karma__.files || {}).forEach(function(file) {
  116. var matches = file.match(regex);
  117. var name = matches && matches[1];
  118. var type = matches && matches[2];
  119. if (name && type) {
  120. inputs[name] = inputs[name] || {};
  121. inputs[name][type] = file;
  122. }
  123. });
  124. return function() {
  125. Object.keys(inputs).forEach(function(key) {
  126. specFromFixture(key, inputs[key]);
  127. });
  128. };
  129. }
  130. function waitForResize(chart, callback) {
  131. var override = chart.resize;
  132. chart.resize = function() {
  133. chart.resize = override;
  134. override.apply(this, arguments);
  135. callback();
  136. };
  137. }
  138. function triggerMouseEvent(chart, type, el) {
  139. var node = chart.canvas;
  140. var rect = node.getBoundingClientRect();
  141. var event = new MouseEvent(type, {
  142. clientX: rect.left + el._model.x,
  143. clientY: rect.top + el._model.y,
  144. cancelable: true,
  145. bubbles: true,
  146. view: window
  147. });
  148. node.dispatchEvent(event);
  149. }
  150. module.exports = {
  151. injectCSS: injectCSS,
  152. createCanvas: createCanvas,
  153. acquireChart: acquireChart,
  154. releaseChart: releaseChart,
  155. specsFromFixtures: specsFromFixtures,
  156. triggerMouseEvent: triggerMouseEvent,
  157. waitForResize: waitForResize
  158. };