From 2dbf1cd1af69f494f971c3603063e4265fb10e88 Mon Sep 17 00:00:00 2001 From: Simon Brunel Date: Sat, 20 Oct 2018 11:38:48 +0200 Subject: [PATCH] Add support for *.js test fixture config (#5777) JSON doesn't support functions which are needed to create scriptable options, so implement a very basic method to load a JavaScript file exporting the config in `module.exports`. Also rename test sources (remove the `jasmine.` prefix), cleanup `karma.conf.js` and add an example .js fixture config (bubble radius option). --- gulpfile.js | 20 +---- karma.conf.js | 13 ++- test/{jasmine.context.js => context.js} | 0 test/fixture.js | 85 ++++++++++++++++++ .../controller.bubble/radius-scriptable.js | 45 ++++++++++ .../controller.bubble/radius-scriptable.png | Bin 0 -> 3989 bytes test/{jasmine.index.js => index.js} | 11 ++- test/{jasmine.matchers.js => matchers.js} | 2 +- test/specs/controller.bar.tests.js | 2 +- test/specs/controller.bubble.tests.js | 2 +- test/specs/controller.line.tests.js | 2 +- test/specs/controller.polarArea.tests.js | 2 +- test/specs/controller.radar.tests.js | 2 +- test/specs/core.scale.tests.js | 2 +- test/specs/element.point.tests.js | 2 +- test/specs/plugin.filler.tests.js | 2 +- test/{jasmine.utils.js => utils.js} | 57 +----------- 17 files changed, 162 insertions(+), 87 deletions(-) rename test/{jasmine.context.js => context.js} (100%) create mode 100644 test/fixture.js create mode 100644 test/fixtures/controller.bubble/radius-scriptable.js create mode 100644 test/fixtures/controller.bubble/radius-scriptable.png rename test/{jasmine.index.js => index.js} (88%) rename test/{jasmine.matchers.js => matchers.js} (99%) rename test/{jasmine.utils.js => utils.js} (72%) diff --git a/gulpfile.js b/gulpfile.js index f6795fa7f..daba620f0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -198,27 +198,15 @@ function docsTask(done) { }); } -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', - ].concat( - argv.inputs ? - argv.inputs.split(';') : - ['./test/specs/**/*.js'] - ); -} - function unittestTask(done) { new karma.Server({ configFile: path.join(__dirname, 'karma.conf.js'), singleRun: !argv.watch, - files: startTest(), args: { - coverage: !!argv.coverage + coverage: !!argv.coverage, + inputs: argv.inputs + ? argv.inputs.split(';') + : ['./test/specs/**/*.js'] } }, // https://github.com/karma-runner/gulp-karma/issues/18 diff --git a/karma.conf.js b/karma.conf.js index 5bb73ef03..4b3a301f1 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -25,9 +25,18 @@ module.exports = function(karma) { } }, + files: [ + {pattern: 'test/fixtures/**/*.js', included: false}, + {pattern: 'test/fixtures/**/*.json', included: false}, + {pattern: 'test/fixtures/**/*.png', included: false}, + 'node_modules/moment/min/moment.min.js', + 'test/index.js', + 'src/**/*.js' + ].concat(args.inputs), + preprocessors: { - './test/jasmine.index.js': ['browserify'], - './src/**/*.js': ['browserify'] + 'test/index.js': ['browserify'], + 'src/**/*.js': ['browserify'] }, browserify: { diff --git a/test/jasmine.context.js b/test/context.js similarity index 100% rename from test/jasmine.context.js rename to test/context.js diff --git a/test/fixture.js b/test/fixture.js new file mode 100644 index 000000000..5652c13e9 --- /dev/null +++ b/test/fixture.js @@ -0,0 +1,85 @@ +/* global __karma__ */ + +'use strict'; + +var utils = require('./utils'); + +function readFile(url, callback) { + var request = new XMLHttpRequest(); + request.onreadystatechange = function() { + if (request.readyState === 4) { + return callback(request.responseText); + } + }; + + request.open('GET', url, false); + request.send(null); +} + +function loadConfig(url, callback) { + var regex = /\.(json|js)$/i; + var matches = url.match(regex); + var type = matches ? matches[1] : 'json'; + var cfg = null; + + readFile(url, function(content) { + switch (type) { + case 'js': + // eslint-disable-next-line + cfg = new Function('"use strict"; var module = {};' + content + '; return module.exports;')(); + break; + case 'json': + cfg = JSON.parse(content); + break; + default: + } + + callback(cfg); + }); +} + +function specFromFixture(description, inputs) { + var input = inputs.js || inputs.json; + it(input, function(done) { + loadConfig(input, function(json) { + var chart = utils.acquireChart(json.config, json.options); + if (!inputs.png) { + fail('Missing PNG comparison file for ' + inputs.json); + done(); + } + + utils.readImageData(inputs.png, function(expected) { + expect(chart).toEqualImageData(expected, json); + utils.releaseChart(chart); + done(); + }); + }); + }); +} + +function specsFromFixtures(path) { + var regex = new RegExp('(^/base/test/fixtures/' + path + '.+)\\.(png|json|js)'); + 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 = { + specs: specsFromFixtures +}; + diff --git a/test/fixtures/controller.bubble/radius-scriptable.js b/test/fixtures/controller.bubble/radius-scriptable.js new file mode 100644 index 000000000..593316b3c --- /dev/null +++ b/test/fixtures/controller.bubble/radius-scriptable.js @@ -0,0 +1,45 @@ +module.exports = { + config: { + type: 'bubble', + data: { + datasets: [{ + data: [ + {x: 0, y: 0}, + {x: 1, y: 0}, + {x: 2, y: 0}, + {x: 3, y: 0}, + {x: 4, y: 0}, + {x: 5, y: 0} + ], + radius: function(ctx) { + return ctx.dataset.data[ctx.dataIndex].x * 4; + } + }] + }, + options: { + legend: false, + title: false, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + }, + elements: { + point: { + backgroundColor: '#444' + } + }, + layout: { + padding: { + left: 24, + right: 24 + } + } + } + }, + options: { + canvas: { + height: 128, + width: 256 + } + } +}; diff --git a/test/fixtures/controller.bubble/radius-scriptable.png b/test/fixtures/controller.bubble/radius-scriptable.png new file mode 100644 index 0000000000000000000000000000000000000000..546466f7192830b3be443775f1dadba6d202e158 GIT binary patch literal 3989 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 MHn7mI(REGy56jFUcK`qY literal 0 Hc-jL100001 diff --git a/test/jasmine.index.js b/test/index.js similarity index 88% rename from test/jasmine.index.js rename to test/index.js index c1706130f..b3fa6cf3b 100644 --- a/test/jasmine.index.js +++ b/test/index.js @@ -1,6 +1,9 @@ -var Context = require('./jasmine.context'); -var matchers = require('./jasmine.matchers'); -var utils = require('./jasmine.utils'); +'use strict'; + +var fixture = require('./fixture'); +var Context = require('./context'); +var matchers = require('./matchers'); +var utils = require('./utils'); (function() { @@ -42,7 +45,7 @@ var utils = require('./jasmine.utils'); 'position: absolute' + '}'); - jasmine.specsFromFixtures = utils.specsFromFixtures; + jasmine.fixture = fixture; jasmine.triggerMouseEvent = utils.triggerMouseEvent; beforeEach(function() { diff --git a/test/jasmine.matchers.js b/test/matchers.js similarity index 99% rename from test/jasmine.matchers.js rename to test/matchers.js index 88f5de8fe..92a6f9704 100644 --- a/test/jasmine.matchers.js +++ b/test/matchers.js @@ -1,7 +1,7 @@ 'use strict'; var pixelmatch = require('pixelmatch'); -var utils = require('./jasmine.utils'); +var utils = require('./utils'); function toPercent(value) { return Math.round(value * 10000) / 100; diff --git a/test/specs/controller.bar.tests.js b/test/specs/controller.bar.tests.js index 7957b6ab5..0e843e143 100644 --- a/test/specs/controller.bar.tests.js +++ b/test/specs/controller.bar.tests.js @@ -1,5 +1,5 @@ describe('Chart.controllers.bar', function() { - describe('auto', jasmine.specsFromFixtures('controller.bar')); + describe('auto', jasmine.fixture.specs('controller.bar')); it('should be constructed', function() { var chart = window.acquireChart({ diff --git a/test/specs/controller.bubble.tests.js b/test/specs/controller.bubble.tests.js index 2597b9ae6..a5f5b89a5 100644 --- a/test/specs/controller.bubble.tests.js +++ b/test/specs/controller.bubble.tests.js @@ -1,5 +1,5 @@ describe('Chart.controllers.bubble', function() { - describe('auto', jasmine.specsFromFixtures('controller.bubble')); + describe('auto', jasmine.fixture.specs('controller.bubble')); it('should be constructed', function() { var chart = window.acquireChart({ diff --git a/test/specs/controller.line.tests.js b/test/specs/controller.line.tests.js index ed8f4ec5c..25a9ed6b0 100644 --- a/test/specs/controller.line.tests.js +++ b/test/specs/controller.line.tests.js @@ -1,5 +1,5 @@ describe('Chart.controllers.line', function() { - describe('auto', jasmine.specsFromFixtures('controller.line')); + describe('auto', jasmine.fixture.specs('controller.line')); it('should be constructed', function() { var chart = window.acquireChart({ diff --git a/test/specs/controller.polarArea.tests.js b/test/specs/controller.polarArea.tests.js index 11e0be0b7..b706f8376 100644 --- a/test/specs/controller.polarArea.tests.js +++ b/test/specs/controller.polarArea.tests.js @@ -1,4 +1,4 @@ -describe('auto', jasmine.specsFromFixtures('controller.polarArea')); +describe('auto', jasmine.fixture.specs('controller.polarArea')); describe('Chart.controllers.polarArea', function() { it('should be constructed', function() { diff --git a/test/specs/controller.radar.tests.js b/test/specs/controller.radar.tests.js index 2bc0a2e0d..7e85e9e7e 100644 --- a/test/specs/controller.radar.tests.js +++ b/test/specs/controller.radar.tests.js @@ -1,5 +1,5 @@ describe('Chart.controllers.radar', function() { - describe('auto', jasmine.specsFromFixtures('controller.radar')); + describe('auto', jasmine.fixture.specs('controller.radar')); it('Should be constructed', function() { var chart = window.acquireChart({ diff --git a/test/specs/core.scale.tests.js b/test/specs/core.scale.tests.js index dc2da042a..2981c35c9 100644 --- a/test/specs/core.scale.tests.js +++ b/test/specs/core.scale.tests.js @@ -1,5 +1,5 @@ describe('Core.scale', function() { - describe('auto', jasmine.specsFromFixtures('core.scale')); + describe('auto', jasmine.fixture.specs('core.scale')); it('should provide default scale label options', function() { expect(Chart.defaults.scale.scaleLabel).toEqual({ diff --git a/test/specs/element.point.tests.js b/test/specs/element.point.tests.js index 8d1227003..0f3a03e31 100644 --- a/test/specs/element.point.tests.js +++ b/test/specs/element.point.tests.js @@ -1,5 +1,5 @@ describe('Chart.elements.Point', function() { - describe('auto', jasmine.specsFromFixtures('element.point')); + describe('auto', jasmine.fixture.specs('element.point')); it ('Should be constructed', function() { var point = new Chart.elements.Point({ diff --git a/test/specs/plugin.filler.tests.js b/test/specs/plugin.filler.tests.js index 117f68036..949793758 100644 --- a/test/specs/plugin.filler.tests.js +++ b/test/specs/plugin.filler.tests.js @@ -7,7 +7,7 @@ describe('Plugin.filler', function() { }); } - describe('auto', jasmine.specsFromFixtures('plugin.filler')); + describe('auto', jasmine.fixture.specs('plugin.filler')); describe('dataset.fill', function() { it('should support boundaries', function() { diff --git a/test/jasmine.utils.js b/test/utils.js similarity index 72% rename from test/jasmine.utils.js rename to test/utils.js index 2c2006a2c..80430d4d5 100644 --- a/test/jasmine.utils.js +++ b/test/utils.js @@ -1,18 +1,3 @@ -/* 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; @@ -112,46 +97,6 @@ function injectCSS(css) { 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); - 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]); - }); - }; -} - function waitForResize(chart, callback) { var override = chart.resize; chart.resize = function() { @@ -180,7 +125,7 @@ module.exports = { createCanvas: createCanvas, acquireChart: acquireChart, releaseChart: releaseChart, - specsFromFixtures: specsFromFixtures, + readImageData: readImageData, triggerMouseEvent: triggerMouseEvent, waitForResize: waitForResize }; -- 2.47.3