Attempt to make easier the creation of unit tests that check the drawing output. Until now, this was done by checking calls on a 'fake' context, which is hard to maintain (need to update pixel values by hands) and also not reliable when optimizing code (i.e. different calls sequence but same result).
As of now, it's possible to define 'auto' tests based on JSON/PNG fixtures: chart is generated from the JSON file and compared to the associated PNG image. The image diff is done using `pixelmatch`. As an example (and in preparation of the `filler` plugin), add auto tests for the line element `fill` options.
function startTest() {
return [
+ {pattern: './test/fixtures/**/*.json', included: false},
+ {pattern: './test/fixtures/**/*.png', included: false},
'./node_modules/moment/min/moment.min.js',
'./test/jasmine.index.js',
'./src/**/*.js',
"karma-jasmine": "^1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"merge-stream": "^1.0.0",
+ "pixelmatch": "^4.0.2",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.7.0",
"yargs": "^5.0.0"
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 255, 0.25)",
+ "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+ }, {
+ "backgroundColor": "rgba(0, 255, 0, 0.25)",
+ "data": [6, 2, null, 4, 5, null, null, 2, 1]
+ }, {
+ "backgroundColor": "rgba(255, 0, 0, 0.25)",
+ "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+ }, {
+ "backgroundColor": "rgba(0, 0, 255, 0.25)",
+ "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": true,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "fill": "bottom",
+ "tension": 0
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 255, 0.25)",
+ "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+ }, {
+ "backgroundColor": "rgba(0, 255, 0, 0.25)",
+ "data": [6, 2, null, 4, 5, null, null, 2, 1]
+ }, {
+ "backgroundColor": "rgba(255, 0, 0, 0.25)",
+ "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+ }, {
+ "backgroundColor": "rgba(0, 0, 255, 0.25)",
+ "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": false,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "fill": "bottom",
+ "tension": 0
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+ }, {
+ "backgroundColor": "rgba(128, 0, 128, 0.25)",
+ "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": true,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "cubicInterpolationMode": "monotone",
+ "borderColor": "transparent",
+ "fill": "zero"
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+ }, {
+ "backgroundColor": "rgba(128, 0, 128, 0.25)",
+ "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": false,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "cubicInterpolationMode": "monotone",
+ "borderColor": "transparent",
+ "fill": "zero"
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+ }, {
+ "backgroundColor": "rgba(128, 0, 128, 0.25)",
+ "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": true,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "cubicInterpolationMode": "monotone",
+ "borderColor": "transparent",
+ "stepped": true,
+ "fill": "zero"
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+ }, {
+ "backgroundColor": "rgba(128, 0, 128, 0.25)",
+ "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": false,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "cubicInterpolationMode": "monotone",
+ "borderColor": "transparent",
+ "stepped": true,
+ "fill": "zero"
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [5.5, 2, null, 4, 5, null, null, 2, 1]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+ }, {
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": true,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "fill": "top",
+ "tension": 0
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [5.5, 2, null, 4, 5, null, null, 2, 1]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+ }, {
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [8, 7, 6.5, -6, -4, -6, 4, 5, 8]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": false,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "fill": "top",
+ "tension": 0
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [6, 2, null, 4, 5, null, null, 2, 1]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+ }, {
+ "backgroundColor": "rgba(0, 64, 192, 0.25)",
+ "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": true,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "fill": "zero",
+ "tension": 0
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "line",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 3, 4, -4, -2, 1, 0]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [6, 2, null, 4, 5, null, null, 2, 1]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [7, 3, 4, 5, 6, 1, 4, null, null]
+ }, {
+ "backgroundColor": "rgba(0, 64, 192, 0.25)",
+ "data": [8, 7, 6, -6, -4, -6, 4, 5, 8]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "spanGaps": false,
+ "legend": false,
+ "title": false,
+ "scales": {
+ "xAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }],
+ "yAxes": [{
+ "ticks": {
+ "display": false
+ }
+ }]
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "fill": "zero",
+ "tension": 0
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 512
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "radar",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+ }, {
+ "backgroundColor": "rgba(128, 0, 128, 0.25)",
+ "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "legend": false,
+ "title": false,
+ "scale": {
+ "pointLabels": {
+ "fontSize": 0
+ },
+ "ticks": {
+ "display": false
+ }
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "tension": 0.5,
+ "fill": "zero"
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 256
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "radar",
+ "data": {
+ "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+ "datasets": [{
+ "backgroundColor": "rgba(0, 0, 192, 0.25)",
+ "data": [null, null, 2, 4, 2, 1, -1, 1, 2]
+ }, {
+ "backgroundColor": "rgba(0, 192, 0, 0.25)",
+ "data": [4, 2, null, 3, 2.5, null, -2, 1.5, 3]
+ }, {
+ "backgroundColor": "rgba(192, 0, 0, 0.25)",
+ "data": [3.5, 2, 1, 2.5, -2, 3, -1, null, null]
+ }, {
+ "backgroundColor": "rgba(128, 0, 128, 0.25)",
+ "data": [5, 6, 5, -2, -4, -3, 4, 2, 4.5]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "legend": false,
+ "title": false,
+ "scale": {
+ "pointLabels": {
+ "fontSize": 0
+ },
+ "ticks": {
+ "display": false
+ }
+ },
+ "elements": {
+ "point": {
+ "radius": 0
+ },
+ "line": {
+ "borderColor": "transparent",
+ "fill": "zero"
+ }
+ }
+ }
+ },
+ "options": {
+ "canvas": {
+ "height": 256,
+ "width": 256
+ }
+ }
+}
'position: absolute' +
'}');
+ jasmine.specsFromFixtures = utils.specsFromFixtures;
+
beforeEach(function() {
jasmine.addMatchers(matchers);
});
'use strict';
+var pixelmatch = require('pixelmatch');
+var utils = require('./jasmine.utils');
+
+function toPercent(value) {
+ return Math.round(value * 10000) / 100;
+}
+
+function createImageData(w, h) {
+ var canvas = utils.createCanvas(w, h);
+ var context = canvas.getContext('2d');
+ return context.getImageData(0, 0, w, h);
+}
+
+function canvasFromImageData(data) {
+ var canvas = utils.createCanvas(data.width, data.height);
+ var context = canvas.getContext('2d');
+ context.putImageData(data, 0, 0);
+ return canvas;
+}
+
+function buildPixelMatchPreview(actual, expected, diff, threshold, tolerance, count) {
+ var ratio = count / (actual.width * actual.height);
+ var wrapper = document.createElement('div');
+
+ wrapper.style.cssText = 'display: flex; overflow-y: auto';
+
+ [
+ {data: actual, label: 'Actual'},
+ {data: expected, label: 'Expected'},
+ {data: diff, label:
+ 'diff: ' + count + 'px ' +
+ '(' + toPercent(ratio) + '%)<br/>' +
+ 'thr: ' + toPercent(threshold) + '%, ' +
+ 'tol: '+ toPercent(tolerance) + '%'
+ }
+ ].forEach(function(values) {
+ var item = document.createElement('div');
+ item.style.cssText = 'text-align: center; font: 12px monospace; line-height: 1.4; margin: 8px';
+ item.innerHTML = '<div style="margin: 8px; height: 32px">' + values.label + '</div>';
+ item.appendChild(canvasFromImageData(values.data));
+ wrapper.appendChild(item);
+ });
+
+ // WORKAROUND: https://github.com/karma-runner/karma-jasmine/issues/139
+ wrapper.indexOf = function() {
+ return -1;
+ };
+
+ return wrapper;
+}
+
function toBeCloseToPixel() {
return {
compare: function(actual, expected) {
};
}
+function toEqualImageData() {
+ return {
+ compare: function(actual, expected, opts) {
+ var message = null;
+ var debug = opts.debug || false;
+ var tolerance = opts.tolerance === undefined? 0.001 : opts.tolerance;
+ var threshold = opts.threshold === undefined? 0.1 : opts.threshold;
+ var ctx, idata, ddata, w, h, count, ratio;
+
+ if (actual instanceof Chart) {
+ ctx = actual.ctx;
+ } else if (actual instanceof HTMLCanvasElement) {
+ ctx = actual.getContext('2d');
+ } else if (actual instanceof CanvasRenderingContext2D) {
+ ctx = actual;
+ }
+
+ if (ctx) {
+ h = expected.height;
+ w = expected.width;
+ idata = ctx.getImageData(0, 0, w, h);
+ ddata = createImageData(w, h);
+ count = pixelmatch(idata.data, expected.data, ddata.data, w, h, {threshold: threshold});
+ ratio = count / (w * h);
+
+ if ((ratio > tolerance) || debug) {
+ message = buildPixelMatchPreview(idata, expected, ddata, threshold, tolerance, count);
+ }
+ } else {
+ message = 'Input value is not a valid image source.';
+ }
+
+ return {
+ message: message,
+ pass: !message
+ };
+ }
+ };
+}
+
module.exports = {
toBeCloseToPixel: toBeCloseToPixel,
toEqualOneOf: toEqualOneOf,
toBeValidChart: toBeValidChart,
- toBeChartOfSize: toBeChartOfSize
+ toBeChartOfSize: toBeChartOfSize,
+ toEqualImageData: toEqualImageData
};
+/* global __karma__ */
+
+function loadJSON(url, callback) {
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function() {
+ if (request.readyState === 4) {
+ return callback(JSON.parse(request.responseText));
+ }
+ };
+
+ request.overrideMimeType('application/json');
+ request.open('GET', url, true);
+ request.send(null);
+}
+
+function createCanvas(w, h) {
+ var canvas = document.createElement('canvas');
+ canvas.width = w;
+ canvas.height = h;
+ return canvas;
+}
+
+function readImageData(url, callback) {
+ var image = new Image();
+
+ image.onload = function() {
+ var h = image.height;
+ var w = image.width;
+ var canvas = createCanvas(w, h);
+ var ctx = canvas.getContext('2d');
+ ctx.drawImage(image, 0, 0, w, h);
+ callback(ctx.getImageData(0, 0, w, h));
+ };
+
+ image.src = url;
+}
+
/**
* Injects a new canvas (and div wrapper) and creates teh associated Chart instance
* using the given config. Additional options allow tweaking elements generation.
head.appendChild(style);
}
+function specFromFixture(description, inputs) {
+ it(inputs.json, function(done) {
+ loadJSON(inputs.json, function(json) {
+ var chart = acquireChart(json.config, json.options);
+ if (!inputs.png) {
+ fail('Missing PNG comparison file for ' + inputs.json);
+ if (!json.debug) {
+ releaseChart(chart);
+ }
+ done();
+ }
+
+ readImageData(inputs.png, function(expected) {
+ expect(chart).toEqualImageData(expected, json);
+ releaseChart(chart);
+ done();
+ });
+ });
+ });
+}
+
+function specsFromFixtures(path) {
+ var regex = new RegExp('(^/base/test/fixtures/' + path + '.+)\\.(png|json)');
+ var inputs = {};
+
+ Object.keys(__karma__.files || {}).forEach(function(file) {
+ var matches = file.match(regex);
+ var name = matches && matches[1];
+ var type = matches && matches[2];
+
+ if (name && type) {
+ inputs[name] = inputs[name] || {};
+ inputs[name][type] = file;
+ }
+ });
+
+ return function() {
+ Object.keys(inputs).forEach(function(key) {
+ specFromFixture(key, inputs[key]);
+ });
+ };
+}
+
module.exports = {
injectCSS: injectCSS,
+ createCanvas: createCanvas,
acquireChart: acquireChart,
- releaseChart: releaseChart
+ releaseChart: releaseChart,
+ specsFromFixtures: specsFromFixtures
};
// Tests for the line element
-describe('Line element tests', function() {
+describe('Chart.elements.Line', function() {
+ describe('auto', jasmine.specsFromFixtures('element.line'));
+
it('should be constructed', function() {
var line = new Chart.elements.Line({
_datasetindex: 2,