Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running query tests in browser #8584

Merged
merged 62 commits into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
a6f18fc
WIP investigating migrating to tape
Jul 23, 2019
f286372
staging work with using rollup to build tests for the browser
Jul 23, 2019
2143ed6
working prototype of tests in browser with browserify
Jul 24, 2019
4cf2312
remove beforeEach and afterEach temporarily
Jul 24, 2019
6d3df51
stage
Jul 26, 2019
42013e3
refactor tape build process, working with rollupnow :party:
Jul 27, 2019
62923a7
revert change to util/test
Jul 27, 2019
a6ae97e
working build script for bundling fixtures into browser bundle
Jul 27, 2019
f54c2fc
working style json preprocessing
Jul 29, 2019
1b19da4
first working protoype of in-browser query tests
Jul 30, 2019
8705ef6
add __ENVIRONMENT__ flag and add request proxies
Jul 30, 2019
6f88052
working query tests!!
Jul 30, 2019
c6a5b9a
further improments
Aug 1, 2019
e02bc60
attempting switch to non esm node
Aug 1, 2019
f5b5995
migrate to using hook in testem
Aug 1, 2019
95ca5c9
switch to using testem hooks
Aug 1, 2019
6619e8b
fix most linking errors
Aug 1, 2019
c2c0404
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into devops/t…
Aug 1, 2019
dd71bb1
fix error in suite_implementation
Aug 1, 2019
964a698
change environment variable style
Aug 1, 2019
36a0042
fix failing query tests
Aug 1, 2019
925848c
first attempt at running query tests in-browser on circle-ci
Aug 1, 2019
c47b4ac
switch to curl instead of wget
Aug 1, 2019
bf03603
Using apt-get -f instead
Aug 1, 2019
0077659
attempt auto install of dependencies
Aug 1, 2019
3f4f8e4
switch to using public node image
Aug 1, 2019
de1cde3
de-derp
Aug 1, 2019
580a0cd
uncache node_modules
Aug 1, 2019
b3c79a0
try node 10.16
Aug 1, 2019
cf81bcd
remove xvfb
Aug 1, 2019
a7e4cd6
remove the need for multi-entry
Aug 1, 2019
64caacd
force invalidate eslintcache
Aug 1, 2019
5593011
upuse GL_JS_ENV environment variable instead
Aug 5, 2019
8ebd56f
better test result collection on circle-ci
Aug 5, 2019
142335e
address PR comments and simplify build folders
Aug 6, 2019
4f10a25
fix flow errors and fix a typo
Aug 6, 2019
18da05b
remove eslint and flow annotations from testem
Aug 6, 2019
9c56096
switch to using custom json diff with epsilon checking
Aug 7, 2019
d80bd42
actually add epsilon checking
Aug 7, 2019
9f97f16
cleanup and remove unused packages
Aug 7, 2019
8c59c36
add comments
Aug 8, 2019
481c27e
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into devops/t…
Aug 8, 2019
7b4ec5b
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into devops/t…
Aug 26, 2019
1415b4c
Remove unecessary `mapbox-gl-test.js` build, using `gl-dev` build dir…
Aug 27, 2019
7352d3b
add build watchers for convenient local debugging
Aug 29, 2019
a41873c
fix circle integration
Aug 29, 2019
758822a
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into devops/t…
Aug 29, 2019
ebcc44b
Fix linting
Aug 29, 2019
a70055b
Revert whitespace change in rollup_plugins.js
Aug 29, 2019
3d49d95
Remove unused env-var flow definition
Aug 29, 2019
62a5a2a
Add prettified HTML reporter for tap output
Sep 5, 2019
657f211
revert intentionally broken test
Sep 5, 2019
f926ef2
Add persisting of testem test-page to disk for reporting on CI
Sep 6, 2019
614e795
Lock circleci to use `debian-stretch`
Sep 6, 2019
688f177
address CR comments: move testem config file and update circle yml
Sep 7, 2019
fc0feec
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into devops/t…
Sep 20, 2019
d1acb15
Add env var to disable build notifications
Sep 23, 2019
f3e2574
- Move tap-parser to devDependencies
Sep 23, 2019
a631a9c
Add documentation to the readme
Sep 23, 2019
53f87a6
fix aggresive fixture watcher, and silence warnings from rollup build…
Sep 25, 2019
bc7e46b
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into devops/t…
Oct 1, 2019
521363d
Merge branch 'master' of github.com:mapbox/mapbox-gl-js into devops/t…
Oct 10, 2019
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
24 changes: 12 additions & 12 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ workflows:

defaults: &defaults
docker:
- image: mbgl/80dbb7f452:linux
- image: circleci/node:10.16-browsers
working_directory: ~/mapbox-gl-js

jobs:
Expand All @@ -99,10 +99,10 @@ jobs:
- checkout
- restore_cache:
keys:
- v2-yarn-{{ checksum "yarn.lock" }}
- run: yarn
- v3-yarn-{{ checksum "yarn.lock" }}
- run: sudo npm install -g yarn & yarn install
asheemmamoowala marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

Why sudo? Docker builds typically run as the root user anyway.

- save_cache:
key: v2-yarn-{{ checksum "yarn.lock" }}
key: v3-yarn-{{ checksum "yarn.lock" }}
paths:
- '~/.yarn'
- 'node_modules'
Expand All @@ -118,13 +118,13 @@ jobs:
at: .
- restore_cache:
keys:
- v1-lint-{{ .Branch }}
- v1-lint
- v2-lint-{{ .Branch }}
- v2-lint
- run: yarn run lint
- run: yarn run lint-docs
- run: yarn run lint-css
- save_cache:
key: v1-lint-{{ .Branch }}-{{ .Revision }}
key: v2-lint-{{ .Branch }}-{{ .Revision }}
paths:
- '.eslintcache'

Expand Down Expand Up @@ -163,14 +163,14 @@ jobs:
steps:
- attach_workspace:
at: .
- run: xvfb-run --server-args="-screen 0 1024x768x24" npm run test-unit
- run: yarn run test-unit

test-render:
<<: *defaults
steps:
- attach_workspace:
at: .
- run: xvfb-run --server-args="-screen 0 1024x768x24" npm run test-render
- run: yarn run test-render
- store_artifacts:
path: "test/integration/render-tests/index.html"

Expand All @@ -179,9 +179,9 @@ jobs:
steps:
- attach_workspace:
at: .
- run: xvfb-run --server-args="-screen 0 1024x768x24" npm run test-query
- store_artifacts:
path: "test/integration/query-tests/index.html"
- run: yarn run test-query-browser-ci
- store_test_results:
path: test/integration/query-tests

test-expressions:
<<: *defaults
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ test/integration/**/index*.html
test/integration/**/actual.png
test/integration/**/actual.json
test/integration/**/diff.png
test/integration/**/test-results.xml
test/integration/dist/**/*.js
test/integration/dist/**/*.json
.eslintcache
src/style-spec/dist/index.js
_batfish_site
Expand Down
38 changes: 20 additions & 18 deletions build/rollup_plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,26 @@ import { createFilter } from 'rollup-pluginutils';
// Common set of plugins/transformations shared across different rollup
// builds (main mapboxgl bundle, style-spec package, benchmarks bundle)

export const plugins = (minified, production) => [
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Seems like no change in this file (other than whitespace)

flow(),
minifyStyleSpec(),
json(),
glsl('./src/shaders/*.glsl', production),
buble({transforms: {dangerousForOf: true}, objectAssign: "Object.assign"}),
minified ? terser() : false,
production ? unassert() : false,
resolve({
browser: true,
preferBuiltins: false
}),
commonjs({
// global keyword handling causes Webpack compatibility issues, so we disabled it:
// https://github.com/mapbox/mapbox-gl-js/pull/6956
ignoreGlobal: true
})
].filter(Boolean);
export const plugins = (minified, production) => {
return [
flow(),
minifyStyleSpec(),
json(),
glsl('./src/shaders/*.glsl', production),
buble({transforms: {dangerousForOf: true}, objectAssign: "Object.assign"}),
minified ? terser() : false,
production ? unassert() : false,
resolve({
browser: true,
preferBuiltins: false
}),
commonjs({
// global keyword handling causes Webpack compatibility issues, so we disabled it:
// https://github.com/mapbox/mapbox-gl-js/pull/6956
ignoreGlobal: true
})
].filter(Boolean);
}

// Using this instead of rollup-plugin-flow due to
// https://github.com/leebyron/rollup-plugin-flow/issues/5
Expand Down
10 changes: 10 additions & 0 deletions build/test/build-tape.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const browserify = require('browserify');
const fs = require('fs');


const b = browserify(require.resolve('../../test/util/tape_config.js'), { standalone: 'tape' })
.bundle((err, buff) => {
if(err) { throw err; }

fs.writeFileSync('test/integration/dist/tape.js', buff, { encoding: 'utf8'});
});
2 changes: 2 additions & 0 deletions flow-typed/environment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @flow strict
declare var GL_JS_ENV: 'production' | 'development' |'test';
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Not seeing this used anywhere

12 changes: 10 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
"@octokit/rest": "^15.15.1",
"babel-eslint": "^10.0.1",
"benchmark": "^2.1.4",
"browserify": "^16.2.3",
"browserify": "^16.3.0",
"d3": "^4.12.0",
"diff": "^4.0.1",
"documentation": "~9.1.1",
"ejs": "^2.5.7",
"eslint": "^5.15.3",
Expand Down Expand Up @@ -104,7 +105,10 @@
"st": "^1.2.2",
"stylelint": "^9.10.1",
"stylelint-config-standard": "^18.2.0",
"tap": "~12.4.1"
"tap": "~12.4.1",
"tape": "^4.11.0",
"tape-filter": "^1.0.4",
"testem": "^2.17.0"
},
"browser": {
"./src/shaders/index.js": "./src/shaders/shaders.js",
Expand All @@ -118,6 +122,9 @@
"build-prod": "rollup -c --environment BUILD:production",
"build-prod-min": "rollup -c --environment BUILD:production,MINIFY:true",
"build-csp": "rollup -c rollup.config.csp.js",
"build-query-suite": "rollup -c rollup.config.test.js",
"build-test": "rollup -c --environment BUILD:test",
"build-tape": "node build/test/build-tape.js",
"build-flow-types": "cp build/mapbox-gl.js.flow dist/mapbox-gl.js.flow && cp build/mapbox-gl.js.flow dist/mapbox-gl-dev.js.flow",
"build-css": "postcss -o dist/mapbox-gl.css src/css/mapbox-gl.css",
"build-style-spec": "cd src/style-spec && npm run build && cd ../.. && mkdir -p dist/style-spec && cp src/style-spec/dist/* dist/style-spec",
Expand Down Expand Up @@ -145,6 +152,7 @@
"test-build": "build/run-tap --no-coverage test/build/**/*.test.js",
"test-render": "node --max-old-space-size=2048 test/render.test.js",
"test-query": "node test/query.test.js",
"test-query-browser-ci": "testem ci -R xunit > test/integration/query-tests/test-results.xml",
"test-expressions": "build/run-node test/expression.test.js",
"test-flow": "build/run-node build/generate-flow-typed-style-spec && flow .",
"test-cov": "nyc --require=@mapbox/flow-remove-types/register --reporter=text-summary --reporter=lcov --cache run-s test-unit test-expressions test-query test-render",
Expand Down
20 changes: 17 additions & 3 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,23 @@ import banner from './build/banner';
const {BUILD, MINIFY} = process.env;
const minified = MINIFY === 'true';
const production = BUILD === 'production';
const outputFile =
!production ? 'dist/mapbox-gl-dev.js' :
minified ? 'dist/mapbox-gl.js' : 'dist/mapbox-gl-unminified.js';
const test = BUILD === 'test';

const outputFile = (function() {
if(production) {
if (minified){
return 'dist/mapbox-gl.js';
}else{
return 'dist/mapbox-gl-unminified.js';
}
}

if(test) {
return 'test/integration/dist/mapbox-gl-test.js';
}

return 'dist/mapbox-gl-dev.js';
})();

export default [{
// First, use code splitting to bundle GL JS into three "chunks":
Expand Down
15 changes: 15 additions & 0 deletions rollup.config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {plugins} from './build/rollup_plugins';


export default {
input: 'test/integration/lib/query-browser.js',
output: {
name: 'queryTests',
format: 'iife',
sourcemap: 'inline',
indent: false,
file: 'test/integration/dist/query-test.js'
},
plugins: plugins(false, false),
external: [ 'test', 'mapboxgl' ]
}
Empty file added test/integration/dist/.gitkeep
Empty file.
98 changes: 98 additions & 0 deletions test/integration/lib/generate-fixture-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* eslint-disable import/no-commonjs */
const path = require('path');
const fs = require('fs');
const glob = require('glob');
const localizeURLs = require('./localize-urls');

const OUTPUT_FILE = 'fixtures.json';

/**
* Analyzes the contents of the specified `directory` ,and inlines
* the contents into a single json file which can then be imported and built into a bundle
* to be shipped to the browser.
*
* @param {string} directory
*/
module.exports = function (directory) {
const basePath = directory;
const jsonPaths = path.join(basePath, '/**/*.json');
const imagePaths = path.join(basePath, '/**/*.png');
//Extract the filedata into a flat dictionary
const allFiles = {};
const allPaths = glob.sync(jsonPaths).concat(glob.sync(imagePaths));

//A Set that stores test names that are malformed so they can be removed later
const malformedTests = {};

for (const fixturePath of allPaths) {
const testName = path.dirname(fixturePath);
const fileName = path.basename(fixturePath);
const extension = path.extname(fixturePath);
try {
if (extension === '.json') {
let json = parseJsonFromFile(fixturePath);

//Special case for style json which needs some preprocessing
if (fileName === 'style.json') {
json = processStyle(testName, json);
}

allFiles[fixturePath] = json;
} else if (extension === '.png') {
allFiles[fixturePath] = pngToBase64Str(fixturePath);
} else {
throw new Error(`${extension} is incompatible , file path ${fixturePath}`);
}
} catch (e) {
console.log(`Error parsing file: ${fixturePath}`);
malformedTests[testName] = true;
}
}

// Re-nest by directory path, each directory path defines a testcase.
const result = {};
for (const fullPath in allFiles) {
const testName = path.dirname(fullPath).replace('test/integration/', '');
//Skip if test is malformed
if (malformedTests[testName]) { continue; }

//Lazily initaialize an object to store each file wihin a particular testName
if (result[testName] == null) {
result[testName] = {};
}
//Trim extension from filename
const fileName = path.basename(fullPath, path.extname(fullPath));
result[testName][fileName] = allFiles[fullPath];
}

const outputStr = JSON.stringify(result, null, 4);
const outputPath = path.join('test/integration/dist', OUTPUT_FILE);

fs.writeFileSync(outputPath, outputStr, { encoding: 'utf8'});
};

function parseJsonFromFile(filePath) {
return JSON.parse(fs.readFileSync(filePath, { encoding: 'utf8' }));
}

function pngToBase64Str(filePath) {
return fs.readFileSync(filePath).toString('base64');
}

function processStyle(testName, style) {
const clone = JSON.parse(JSON.stringify(style));
// 7357 is testem's default port
localizeURLs(clone, 7357);

clone.metadata = clone.metadata || {};
clone.metadata.test = Object.assign({
testName,
width: 512,
height: 512,
pixelRatio: 1,
recycleMap: false,
allowed: 0.00015
}, clone.metadata.test);

return clone;
}
37 changes: 37 additions & 0 deletions test/integration/lib/json-diff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import diff from 'diff';

export function generateDiffLog(expected, actual) {
return diff.diffJson(expected, actual).map((hunk) => {
if (hunk.added) {
return `+ ${hunk.value}`;
} else if (hunk.removed) {
return `- ${hunk.value}`;
} else {
return ` ${hunk.value}`;
}
}).join('');
}

export function deepEqual(a, b) {
if (typeof a !== typeof b)
return false;
if (typeof a === 'number')
return Math.abs(a - b) < 1e-10;
if (a === null || typeof a !== 'object')
return a === b;

const ka = Object.keys(a);
const kb = Object.keys(b);

if (ka.length !== kb.length)
return false;

ka.sort();
kb.sort();

for (let i = 0; i < ka.length; i++)
if (ka[i] !== kb[i] || !deepEqual(a[ka[i]], b[ka[i]]))
return false;

return true;
}
Loading