Skip to content

Commit

Permalink
Enable unit tests for canvas-based layers (#3226)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress committed Jun 11, 2019
1 parent a4d1634 commit 0e679cc
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 75 deletions.
53 changes: 33 additions & 20 deletions modules/layers/src/text-layer/text-layer.js
Expand Up @@ -213,33 +213,46 @@ export default class TextLayer extends CompositeLayer {

_getAccessor(accessor) {
if (typeof accessor === 'function') {
return x => accessor(x.object);
const objectInfo = {
data: this.props.data,
target: []
};
return x => {
objectInfo.index = x.objectIndex;
return accessor(x.object, objectInfo);
};
}
return accessor;
}

getAnchorXFromTextAnchor(getTextAnchor) {
return x => {
const textAnchor =
typeof getTextAnchor === 'function' ? getTextAnchor(x.object) : getTextAnchor;
if (!TEXT_ANCHOR.hasOwnProperty(textAnchor)) {
throw new Error(`Invalid text anchor parameter: ${textAnchor}`);
}
return TEXT_ANCHOR[textAnchor];
};
if (typeof getTextAnchor === 'function') {
const objectInfo = {
data: this.props.data,
target: []
};
return x => {
objectInfo.index = x.objectIndex;
const textAnchor = getTextAnchor(x.object, objectInfo);
return TEXT_ANCHOR[textAnchor] || 0;
};
}
return () => TEXT_ANCHOR[getTextAnchor] || 0;
}

getAnchorYFromAlignmentBaseline(getAlignmentBaseline) {
return x => {
const alignmentBaseline =
typeof getAlignmentBaseline === 'function'
? getAlignmentBaseline(x.object)
: getAlignmentBaseline;
if (!ALIGNMENT_BASELINE.hasOwnProperty(alignmentBaseline)) {
throw new Error(`Invalid alignment baseline parameter: ${alignmentBaseline}`);
}
return ALIGNMENT_BASELINE[alignmentBaseline];
};
if (typeof getAlignmentBaseline === 'function') {
const objectInfo = {
data: this.props.data,
target: []
};
return x => {
objectInfo.index = x.objectIndex;
const alignmentBaseline = getAlignmentBaseline(x.object, objectInfo);
return ALIGNMENT_BASELINE[alignmentBaseline] || 0;
};
}
return () => ALIGNMENT_BASELINE[getAlignmentBaseline] || 0;
}

renderLayers() {
Expand Down Expand Up @@ -272,7 +285,7 @@ export default class TextLayer extends CompositeLayer {
iconAtlas,
iconMapping,

getPosition: d => getPosition(d.object),
getPosition: this._getAccessor(getPosition),
getColor: this._getAccessor(getColor),
getSize: this._getAccessor(getSize),
getAngle: this._getAccessor(getAngle),
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -46,6 +46,7 @@
"babel-plugin-inline-webgl-constants": "^1.0.0",
"babel-plugin-remove-glsl-comments": "^0.1.0",
"babel-preset-minify": "^0.5.0",
"canvas": "^2.6.0",
"coveralls": "^3.0.0",
"eslint-config-prettier": "^4.1.0",
"eslint-config-uber-jsx": "^3.3.3",
Expand Down
13 changes: 12 additions & 1 deletion test/modules/index.js
Expand Up @@ -29,12 +29,23 @@ import './json';
import './react';
import './jupyter-widget';

// TODO - Tests currently only work in browser
if (typeof document !== 'undefined') {
// Tests currently only work in browser
require('./react/deckgl.spec');
require('./json/json-render.spec');

require('./main/bundle');
require('./aggregation-layers/utils/gpu-grid-aggregator.spec');
require('./aggregation-layers/utils/grid-aggregation-utils.spec');
require('./core/lib/pick-layers.spec');
} else if (typeof global !== 'undefined') {
// Running in Node
const {JSDOM} = require('jsdom');
const dom = new JSDOM(`<!DOCTYPE html>`);
// These globals are required by @jupyter-widgets/base
/* global global */
global.window = dom.window;
global.navigator = dom.window.navigator;
global.document = dom.window.document;
global.Element = dom.window.Element;
}
32 changes: 2 additions & 30 deletions test/modules/json/json-converter.spec.js
@@ -1,11 +1,10 @@
import test from 'tape-catch';
import {Deck} from '@deck.gl/core';
import {_JSONConverter as JSONConverter} from '@deck.gl/json';

import {COORDINATE_SYSTEM} from '@deck.gl/core';
import GL from '@luma.gl/constants';

const configuration = {
export const configuration = {
// a map of all layers that should be exposes as JSONLayers
layers: Object.assign({}, require('@deck.gl/layers')),
// Any non-standard views
Expand All @@ -18,7 +17,7 @@ const configuration = {
}
};

const JSON_DATA = {
export const JSON_DATA = {
initialViewState: {
longitude: -122.45,
latitude: 37.8,
Expand Down Expand Up @@ -57,30 +56,3 @@ test('JSONConverter#convert', t => {
t.ok(deckProps, 'JSONConverter converted correctly');
t.end();
});

test('JSONConverter#render', t => {
if (typeof document === 'undefined') {
t.comment('test only available in browser');
t.end();
return;
}

const jsonConverter = new JSONConverter({configuration});
t.ok(jsonConverter, 'JSONConverter created');

const deckProps = jsonConverter.convertJsonToDeckProps(JSON_DATA);
t.ok(deckProps, 'JSONConverter converted correctly');

const jsonDeck = new Deck(
Object.assign(
{
onAfterRender: () => {
t.ok(jsonDeck, 'JSONConverter rendered');
jsonDeck.finalize();
t.end();
}
},
deckProps
)
);
});
26 changes: 26 additions & 0 deletions test/modules/json/json-render.spec.js
@@ -0,0 +1,26 @@
import test from 'tape-catch';
import {Deck} from '@deck.gl/core';
import {_JSONConverter as JSONConverter} from '@deck.gl/json';

import {configuration, JSON_DATA} from './json-converter.spec';

test('JSONConverter#render', t => {
const jsonConverter = new JSONConverter({configuration});
t.ok(jsonConverter, 'JSONConverter created');

const deckProps = jsonConverter.convertJsonToDeckProps(JSON_DATA);
t.ok(deckProps, 'JSONConverter converted correctly');

const jsonDeck = new Deck(
Object.assign(
{
onAfterRender: () => {
t.ok(jsonDeck, 'JSONConverter rendered');
jsonDeck.finalize();
t.end();
}
},
deckProps
)
);
});
25 changes: 1 addition & 24 deletions test/modules/jupyter-widget/index.spec.js
@@ -1,34 +1,11 @@
import test from 'tape-catch';

function getDeckModel(state) {
let polyfilled = false;
/* global global */
if (typeof document === 'undefined' && typeof global !== 'undefined') {
// Running in Node
const {JSDOM} = require('jsdom');
const dom = new JSDOM(`<!DOCTYPE html>`);
// These globals are required prior to importing @jupyter-widgets/base
global.window = dom.window;
global.navigator = dom.window.navigator;
global.document = dom.window.document;
global.Element = dom.window.Element;

polyfilled = true;
}

// Require at runtime, after the environment is polyfilled
const {DeckGLModel} = require('@deck.gl/jupyter-widget');
const {createTestModel} = require('./utils.spec');

const model = createTestModel(DeckGLModel, state);

if (polyfilled) {
// Reset to avoid polluting the environment for other tests
delete global.window;
delete global.navigator;
delete global.document;
delete global.Element;
}

return model;
}

Expand Down
1 change: 1 addition & 0 deletions test/modules/layers/index.js
Expand Up @@ -31,4 +31,5 @@ import './path-layer/path-layer-vertex.spec';
import './icon-manager.spec';
import './text-layer/font-atlas-utils.spec';
import './text-layer/lru-cache.spec';
import './text-layer/text-layer.spec';
import './column-geometry.spec';
27 changes: 27 additions & 0 deletions test/modules/layers/text-layer/text-layer.spec.js
@@ -0,0 +1,27 @@
import test from 'tape-catch';

import {TextLayer} from '@deck.gl/layers';
import * as FIXTURES from 'deck.gl-test/data';
import {testLayer, generateLayerTests} from '@deck.gl/test-utils';

test('TextLayer', t => {
const testCases = generateLayerTests({
Layer: TextLayer,
sampleProps: {
data: FIXTURES.points,
getText: d => d.ADDRESS,
getPosition: d => d.COORDINATES
},
assert: t.ok,
onBeforeUpdate: ({testCase}) => t.comment(testCase.title),
onAfterUpdate: ({layer, subLayer}) => {
if (layer.props.data.length) {
t.ok(layer.state.data.length, 'Creates sublayer data');
t.ok(subLayer, 'Renders sublayer');
}
}
});
testLayer({Layer: TextLayer, testCases, onError: t.notOk});

t.end();
});
39 changes: 39 additions & 0 deletions yarn.lock
Expand Up @@ -3058,6 +3058,15 @@ canvas-to-blob@0.0.0:
resolved "https://registry.yarnpkg.com/canvas-to-blob/-/canvas-to-blob-0.0.0.tgz#f1db4dd083ddc74a78fe5bce6a869786b59f51f3"
integrity sha1-8dtN0IPdx0p4/lvOaoaXhrWfUfM=

canvas@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.6.0.tgz#7a8f87b6148845d97e6ee30947fba1508bed4941"
integrity sha512-bEO9f1ThmbknLPxCa8Es7obPlN9W3stB1bo7njlhOFKIdUTldeTqXCh9YclCPAi2pSQs84XA0jq/QEZXSzgyMw==
dependencies:
nan "^2.14.0"
node-pre-gyp "^0.11.0"
simple-get "^3.0.3"

cardinal@~0.4.2:
version "0.4.4"
resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-0.4.4.tgz#ca5bb68a5b511b90fe93b9acea49bdee5c32bfe2"
Expand Down Expand Up @@ -7284,6 +7293,11 @@ mute-stream@~0.0.4:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==

nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==

nan@^2.6.2, nan@^2.9.2:
version "2.11.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099"
Expand Down Expand Up @@ -7489,6 +7503,22 @@ node-pre-gyp@^0.10.0:
semver "^5.3.0"
tar "^4"

node-pre-gyp@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054"
integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4"

node-releases@^1.1.3:
version "1.1.5"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.5.tgz#1dbee1380742125fe99e0476c456670bf3590b89"
Expand Down Expand Up @@ -9540,6 +9570,15 @@ simple-get@^2.7.0:
once "^1.3.1"
simple-concat "^1.0.0"

simple-get@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.0.3.tgz#924528ac3f9d7718ce5e9ec1b1a69c0be4d62efa"
integrity sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==
dependencies:
decompress-response "^3.3.0"
once "^1.3.1"
simple-concat "^1.0.0"

slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
Expand Down

0 comments on commit 0e679cc

Please sign in to comment.