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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 O8!$1nG^o*YOZpGX%prFG literal 0 HcmV?d00001 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 };