Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/test.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,13 +29,13 @@ case $1 in

jasmine)
npm run test-jasmine -- --skip-tags=gl,noCI,flaky || EXIT_STATE=$?
npm run test-bundle || EXIT_STATE=$?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which gives:

image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚖️ 👍
💃 still applies :)

exit $EXIT_STATE
;;

jasmine2)
retry npm run test-jasmine -- --tags=gl --skip-tags=noCI,flaky
retry npm run test-jasmine -- --tags=flaky --skip-tags=noCI
npm run test-bundle || EXIT_STATE=$?
exit $EXIT_STATE
;;

Expand Down
44 changes: 37 additions & 7 deletions tasks/test_bundle.js
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,46 @@
var path = require('path');
var exec = require('child_process').exec;
var glob = require('glob');
var runSeries = require('run-series');

var constants = require('./util/constants');
var common = require('./util/common');
var pathToJasmineBundleTests = path.join(constants.pathToJasmineBundleTests);

var pathToJasmineBundleTests = constants.pathToJasmineBundleTests;

/**
* Run all jasmine 'bundle' test in series
*
* To run specific bundle tests, use
*
* $ npm run test-jasmine -- --bundleTest=<name-of-suite>
*/
glob(pathToJasmineBundleTests + '/*.js', function(err, files) {
files.forEach(function(file) {
var baseName = path.basename(file);
var cmd = 'npm run test-jasmine -- --bundleTest=' + baseName;
var tasks = files.map(function(file) {
return function(cb) {
var cmd = [
'karma', 'start',
path.join(constants.pathToRoot, 'test', 'jasmine', 'karma.conf.js'),
'--bundleTest=' + path.basename(file),
'--nowatch'
].join(' ');

console.log('Running: ' + cmd);

exec(cmd, function(err) {
cb(null, err);
}).stdout.pipe(process.stdout);
};
});

runSeries(tasks, function(err, results) {
if(err) throw err;

var failed = results.filter(function(r) { return r; });

common.execCmd(cmd);
if(failed.length) {
console.log('\ntest-bundle summary:');
failed.forEach(function(r) { console.warn('- ' + r.cmd + ' failed'); });
console.log('');
process.exit(1);
}
});
});
4 changes: 2 additions & 2 deletions tasks/util/browserify_wrapper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = opts.pathToMinBundle ? 2 : 1;
var pending = pathToMinBundle ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All@@ -58,7 +58,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}
});

if(opts.pathToMinBundle) {
if(pathToMinBundle) {
bundleStream
.pipe(minify(constants.uglifyOptions))
.pipe(fs.createWriteStream(pathToMinBundle))
Expand Down
13 changes: 10 additions & 3 deletions tasks/util/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,10 +85,17 @@ module.exports = {
testContainerHome: '/var/www/streambed/image_server/plotly.js',

uglifyOptions: {
ecma: 5,
mangle: true,
// the compress flag break mapbox-gl,
// TODO find a way to only skip compression on mapbox-gl files
compress: false,
compress: {
// see full list of compress option
// https://github.com/fabiosantoscode/terser#compress-options
//
// need to turn off 'typeofs' to make mapbox-gl work in
// minified bundles, for more info see:
// https://github.com/plotly/plotly.js/issues/2787
typeofs: false
},
output: {
beautify: false,
ascii_only: true
Expand Down
69 changes: 69 additions & 0 deletions test/jasmine/assets/mock_lists.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
// list of mocks that should include *all* plotly.js trace modules

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

var mapboxMockList = [
['scattermapbox', require('@mocks/mapbox_bubbles-text.json')]
];

module.exports = {
svg: svgMockList,
gl: glMockList,
mapbox: mapboxMockList,
all: svgMockList.concat(glMockList).concat(mapboxMockList)
};
28 changes: 28 additions & 0 deletions test/jasmine/bundle_tests/minified_bundle_test.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
/* global Plotly:false */

var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var mockLists = require('../assets/mock_lists');

// only needed for mapbox subplots
var LONG_TIMEOUT_INTERVAL = 5 * jasmine.DEFAULT_TIMEOUT_INTERVAL;

describe('Test plotly.min.js', function() {
'use strict';

var gd = document.createElement('div');
document.body.appendChild(gd);

it('should expose Plotly global', function() {
expect(window.Plotly).toBeDefined();
});

Plotly.setPlotConfig({
mapboxAccessToken: MAPBOX_ACCESS_TOKEN
});

mockLists.all.forEach(function(mockSpec) {
it('can plot "' + mockSpec[0] + '"', function(done) {
Plotly.newPlot(gd, mockSpec[1]).catch(fail).then(done);
}, LONG_TIMEOUT_INTERVAL);
});
});
4 changes: 4 additions & 0 deletions test/jasmine/karma.conf.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -255,6 +255,10 @@ if(isFullSuite) {
];
delete func.defaultConfig.preprocessors[pathToCustomMatchers];
break;
case 'minified_bundle':
func.defaultConfig.files.push(constants.pathToPlotlyDistMin);
func.defaultConfig.preprocessors[testFileGlob] = ['browserify'];
break;
case 'ie9':
// load ie9_mock.js before plotly.js+test bundle
// to catch reference errors that could occur
Expand Down
73 changes: 9 additions & 64 deletions test/jasmine/tests/plot_api_test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,7 @@ var destroyGraphDiv = require('../assets/destroy_graph_div');
var failTest = require('../assets/fail_test');
var checkTicks = require('../assets/custom_assertions').checkTicks;
var supplyAllDefaults = require('../assets/supply_defaults');
var mockLists = require('../assets/mock_lists');

describe('Test plot api', function() {
'use strict';
Expand DownExpand Up@@ -3230,63 +3231,6 @@ describe('Test plot api', function() {
.then(done);
});

var svgMockList = [
['1', require('@mocks/1.json')],
['4', require('@mocks/4.json')],
['5', require('@mocks/5.json')],
['10', require('@mocks/10.json')],
['11', require('@mocks/11.json')],
['17', require('@mocks/17.json')],
['21', require('@mocks/21.json')],
['22', require('@mocks/22.json')],
['airfoil', require('@mocks/airfoil.json')],
['annotations-autorange', require('@mocks/annotations-autorange.json')],
['axes_enumerated_ticks', require('@mocks/axes_enumerated_ticks.json')],
['axes_visible-false', require('@mocks/axes_visible-false.json')],
['bar_and_histogram', require('@mocks/bar_and_histogram.json')],
['basic_error_bar', require('@mocks/basic_error_bar.json')],
['binding', require('@mocks/binding.json')],
['cheater_smooth', require('@mocks/cheater_smooth.json')],
['finance_style', require('@mocks/finance_style.json')],
['geo_first', require('@mocks/geo_first.json')],
['layout_image', require('@mocks/layout_image.json')],
['layout-colorway', require('@mocks/layout-colorway.json')],
['polar_categories', require('@mocks/polar_categories.json')],
['polar_direction', require('@mocks/polar_direction.json')],
['range_selector_style', require('@mocks/range_selector_style.json')],
['range_slider_multiple', require('@mocks/range_slider_multiple.json')],
['sankey_energy', require('@mocks/sankey_energy.json')],
['scattercarpet', require('@mocks/scattercarpet.json')],
['shapes', require('@mocks/shapes.json')],
['splom_iris', require('@mocks/splom_iris.json')],
['table_wrapped_birds', require('@mocks/table_wrapped_birds.json')],
['ternary_fill', require('@mocks/ternary_fill.json')],
['text_chart_arrays', require('@mocks/text_chart_arrays.json')],
['transforms', require('@mocks/transforms.json')],
['updatemenus', require('@mocks/updatemenus.json')],
['violin_side-by-side', require('@mocks/violin_side-by-side.json')],
['world-cals', require('@mocks/world-cals.json')],
['typed arrays', {
data: [{
x: new Float32Array([1, 2, 3]),
y: new Float32Array([1, 2, 1])
}]
}]
];

var glMockList = [
['gl2d_heatmapgl', require('@mocks/gl2d_heatmapgl.json')],
['gl2d_line_dash', require('@mocks/gl2d_line_dash.json')],
['gl2d_parcoords_2', require('@mocks/gl2d_parcoords_2.json')],
['gl2d_pointcloud-basic', require('@mocks/gl2d_pointcloud-basic.json')],
['gl3d_annotations', require('@mocks/gl3d_annotations.json')],
['gl3d_set-ranges', require('@mocks/gl3d_set-ranges.json')],
['gl3d_world-cals', require('@mocks/gl3d_world-cals.json')],
['gl3d_cone-autorange', require('@mocks/gl3d_cone-autorange.json')],
['gl3d_streamtube-simple', require('@mocks/gl3d_streamtube-simple.json')],
['glpolar_style', require('@mocks/glpolar_style.json')],
];

// make sure we've included every trace type in this suite
var typesTested = {};
var itemType;
Expand DownExpand Up@@ -3385,24 +3329,25 @@ describe('Test plot api', function() {
.then(done);
}

svgMockList.forEach(function(mockSpec) {
mockLists.svg.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (svg mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

glMockList.forEach(function(mockSpec) {
mockLists.gl.forEach(function(mockSpec) {
it('can redraw "' + mockSpec[0] + '" with no changes as a noop (gl mocks)', function(done) {
_runReactMock(mockSpec, done);
});
});

it('@noCI can redraw scattermapbox with no changes as a noop', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
mockLists.mapbox.forEach(function(mockSpec) {
it('@noCI can redraw "' + mockSpec[0] + '" with no changes as a noop (mapbpox mocks)', function(done) {
Plotly.setPlotConfig({
mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN
});
_runReactMock(mockSpec, done);
});

_runReactMock(['scattermapbox', require('@mocks/mapbox_bubbles-text.json')], done);
});

// since CI breaks up gl/svg types, and drops scattermapbox, this test won't work there
Expand Down