Merge pull request #3470 from tsauerwein/rendering-tests

Add rendering tests
This commit is contained in:
Tobias Sauerwein
2015-04-06 13:49:51 +02:00
51 changed files with 1492 additions and 27 deletions
+4
View File
@@ -1,9 +1,13 @@
env:
- DISPLAY=:99.0
before_install: before_install:
- "sudo pip install -r requirements.txt" - "sudo pip install -r requirements.txt"
- "npm install -g npm && npm install" - "npm install -g npm && npm install"
before_script: before_script:
- "rm src/ol/renderer/webgl/*shader.js" - "rm src/ol/renderer/webgl/*shader.js"
- "sh -e /etc/init.d/xvfb start"
script: "./build.py ci" script: "./build.py ci"
+42 -15
View File
@@ -145,6 +145,10 @@ SPEC = [path
for path in ifind('test/spec') for path in ifind('test/spec')
if path.endswith('.js')] if path.endswith('.js')]
SPEC_RENDERING = [path
for path in ifind('test_rendering/spec')
if path.endswith('.js')]
TASKS = [path TASKS = [path
for path in ifind('tasks') for path in ifind('tasks')
if path.endswith('.js')] if path.endswith('.js')]
@@ -172,7 +176,7 @@ def report_sizes(t):
virtual('default', 'build') virtual('default', 'build')
virtual('ci', 'lint', 'build', 'test', virtual('ci', 'lint', 'build', 'test', 'test-rendering',
'build/examples/all.combined.js', 'check-examples', 'apidoc') 'build/examples/all.combined.js', 'check-examples', 'apidoc')
@@ -231,19 +235,28 @@ for glsl_src in GLSL_SRC:
shader_src_helper(glsl_src) shader_src_helper(glsl_src)
@target('build/test/requireall.js', SPEC) def build_requires(task):
def build_test_requireall_js(t):
requires = set() requires = set()
for dependency in t.dependencies: for dependency in task.dependencies:
for line in open(dependency, 'rU'): for line in open(dependency, 'rU'):
match = re.match(r'goog\.provide\(\'(.*)\'\);', line) match = re.match(r'goog\.provide\(\'(.*)\'\);', line)
if match: if match:
requires.add(match.group(1)) requires.add(match.group(1))
with open(t.name, 'wb') as f: with open(task.name, 'wb') as f:
for require in sorted(requires): for require in sorted(requires):
f.write('goog.require(\'%s\');\n' % (require,)) f.write('goog.require(\'%s\');\n' % (require,))
@target('build/test_requires.js', SPEC)
def build_test_requires(t):
build_requires(t)
@target('build/test_rendering_requires.js', SPEC_RENDERING)
def build_test_rendering_requires(t):
build_requires(t)
virtual('build-examples', 'examples', 'build/examples/all.combined.js', virtual('build-examples', 'examples', 'build/examples/all.combined.js',
EXAMPLES_COMBINED) EXAMPLES_COMBINED)
@@ -392,7 +405,8 @@ def examples_star_combined_js(name, match):
return Target(name, action=action, dependencies=dependencies) return Target(name, action=action, dependencies=dependencies)
@target('serve', 'examples', NPM_INSTALL) @target('serve', 'examples', 'build/test_requires.js', 'build/test_rendering_requires.js',
NPM_INSTALL)
def serve(t): def serve(t):
t.run('node', 'tasks/serve.js') t.run('node', 'tasks/serve.js')
@@ -401,7 +415,8 @@ virtual('lint', 'build/lint-timestamp', 'build/check-requires-timestamp',
'build/check-whitespace-timestamp', 'jshint') 'build/check-whitespace-timestamp', 'jshint')
@target('build/lint-timestamp', SRC, EXAMPLES_SRC, SPEC, precious=True) @target('build/lint-timestamp', SRC, EXAMPLES_SRC, SPEC, SPEC_RENDERING,
precious=True)
def build_lint_src_timestamp(t): def build_lint_src_timestamp(t):
t.run('%(GJSLINT)s', t.run('%(GJSLINT)s',
'--jslint_error=all', '--jslint_error=all',
@@ -412,8 +427,8 @@ def build_lint_src_timestamp(t):
virtual('jshint', 'build/jshint-timestamp') virtual('jshint', 'build/jshint-timestamp')
@target('build/jshint-timestamp', SRC, EXAMPLES_SRC, SPEC, TASKS, @target('build/jshint-timestamp', SRC, EXAMPLES_SRC, SPEC, SPEC_RENDERING,
NPM_INSTALL, precious=True) TASKS, NPM_INSTALL, precious=True)
def build_jshint_timestamp(t): def build_jshint_timestamp(t):
t.run(variables.JSHINT, '--verbose', t.newer(t.dependencies)) t.run(variables.JSHINT, '--verbose', t.newer(t.dependencies))
t.touch() t.touch()
@@ -442,7 +457,8 @@ def _strip_comments(lines):
yield lineno, line yield lineno, line
@target('build/check-requires-timestamp', SRC, EXAMPLES_SRC, SHADER_SRC, SPEC) @target('build/check-requires-timestamp', SRC, EXAMPLES_SRC, SHADER_SRC,
SPEC, SPEC_RENDERING)
def build_check_requires_timestamp(t): def build_check_requires_timestamp(t):
unused_count = 0 unused_count = 0
all_provides = set() all_provides = set()
@@ -583,7 +599,7 @@ def build_check_requires_timestamp(t):
@target('build/check-whitespace-timestamp', SRC, EXAMPLES_SRC, @target('build/check-whitespace-timestamp', SRC, EXAMPLES_SRC,
SPEC, JSDOC_SRC, precious=True) SPEC, SPEC_RENDERING, JSDOC_SRC, precious=True)
def build_check_whitespace_timestamp(t): def build_check_whitespace_timestamp(t):
CR_RE = re.compile(r'\r') CR_RE = re.compile(r'\r')
LEADING_WHITESPACE_RE = re.compile(r'\s+') LEADING_WHITESPACE_RE = re.compile(r'\s+')
@@ -723,7 +739,7 @@ def check_examples(t):
sys.exit(1) sys.exit(1)
@target('test', NPM_INSTALL, phony=True) @target('test', NPM_INSTALL, 'build/test_requires.js', phony=True)
def test(t): def test(t):
t.run('node', 'tasks/test.js') t.run('node', 'tasks/test.js')
@@ -733,6 +749,16 @@ def test_coverage(t):
t.run('node', 'tasks/test-coverage.js') t.run('node', 'tasks/test-coverage.js')
@target('test-rendering', 'build/test_rendering_requires.js',
NPM_INSTALL, phony=True)
def test_rendering(t):
# create a temp. profile to run the tests with WebGL
tmp_profile_dir = 'build/slimerjs-profile'
t.rm_rf(tmp_profile_dir)
t.cp_r('test_rendering/slimerjs-profile', tmp_profile_dir)
t.run('node', 'tasks/test-rendering.js')
@target('fixme', phony=True) @target('fixme', phony=True)
def find_fixme(t): def find_fixme(t):
regex = re.compile('FIXME|TODO') regex = re.compile('FIXME|TODO')
@@ -797,6 +823,7 @@ The most common targets are:
CSS. This is also the default build target which runs when CSS. This is also the default build target which runs when
no target is specified. no target is specified.
test - Runs the testsuite and displays the results. test - Runs the testsuite and displays the results.
test-rendering - Runs the rendering testsuite and displays the results.
check - Runs the lint-target, builds some OpenLayers files, and check - Runs the lint-target, builds some OpenLayers files, and
then runs test. Many developers call this target often then runs test. Many developers call this target often
while working on the code. while working on the code.
@@ -806,9 +833,9 @@ Other less frequently used targets are:
apidoc - Builds the API-Documentation using JSDoc3. apidoc - Builds the API-Documentation using JSDoc3.
ci - Builds all examples in various modes and usually takes a ci - Builds all examples in various modes and usually takes a
long time to finish. This target calls the following long time to finish. This target calls the following
targets: lint, build, build-all, test, build-examples, targets: lint, build, build-all, test, test-rendering,
check-examples and apidoc. This is the target run on build-examples, check-examples and apidoc. This is the
Travis CI. target run on Travis CI.
test-coverage - Generates a test coverage report in the coverage folder. test-coverage - Generates a test coverage report in the coverage folder.
reallyclean - Remove untracked files from the repository. reallyclean - Remove untracked files from the repository.
checkdeps - Checks whether all required development software is checkdeps - Checks whether all required development software is
+3 -1
View File
@@ -54,7 +54,9 @@
"mocha-phantomjs": "3.5.1", "mocha-phantomjs": "3.5.1",
"phantomjs": "1.9.10", "phantomjs": "1.9.10",
"proj4": "2.3.3", "proj4": "2.3.3",
"sinon": "1.10.3" "sinon": "1.10.3",
"slimerjs-edge": "0.10.0-pre-2",
"resemblejs": "1.2.0"
}, },
"ext": [ "ext": [
"rbush" "rbush"
+19 -7
View File
@@ -23,7 +23,10 @@ var createServer = exports.createServer = function(callback) {
lib: [ lib: [
'src/**/*.js', 'src/**/*.js',
'build/ol.ext/*.js', 'build/ol.ext/*.js',
'test/spec/**/*.test.js' 'test/spec/**/*.test.js',
'test_rendering/spec/**/*.test.js',
'build/test_requires.js',
'build/test_rendering_requires.js'
], ],
main: 'examples/*.js' main: 'examples/*.js'
}); });
@@ -41,12 +44,21 @@ var createServer = exports.createServer = function(callback) {
getMain: function(req) { getMain: function(req) {
var main; var main;
var query = url.parse(req.url, true).query; var query = url.parse(req.url, true).query;
if (query.id) { var referer = req.headers.referer;
var referer = req.headers.referer; var pathName = url.parse(referer).pathname;
if (referer) { if (pathName.indexOf('/test/') === 0) {
var from = path.join(process.cwd(), main = path.resolve(
path.dirname(url.parse(referer).pathname)); path.join(process.cwd(), 'build'), 'test_requires.js');
main = path.resolve(from, query.id + '.js'); } else if (pathName.indexOf('/test_rendering/') === 0) {
main = path.resolve(
path.join(process.cwd(), 'build'), 'test_rendering_requires.js');
} else {
if (query.id) {
if (referer) {
var from = path.join(process.cwd(),
path.dirname(url.parse(referer).pathname));
main = path.resolve(from, query.id + '.js');
}
} }
} }
return main; return main;
+1 -1
View File
@@ -13,7 +13,7 @@ var wrench = require('wrench');
var path = require('path'); var path = require('path');
var glob = require('glob'); var glob = require('glob');
var runTestsuite = require('./test'); var runTestsuite = require('./test').runTests;
// setup some pathes // setup some pathes
var dir = path.join(__dirname, '../src'); var dir = path.join(__dirname, '../src');
+65
View File
@@ -0,0 +1,65 @@
/**
* This task starts a dev server that provides a script loader for OpenLayers
* and Closure Library and runs rendering tests in SlimerJS.
*/
var fs = require('fs');
var path = require('path');
var spawn = require('child_process').spawn;
var slimerjs = require('slimerjs-edge');
var serve = require('./serve');
var listen = require('./test').listen;
/**
* Create the debug server and run tests.
*/
serve.createServer(function(err, server) {
if (err) {
process.stderr.write(err.message + '\n');
process.exit(1);
}
listen(3001, 3005, server, function(err) {
if (err) {
process.stderr.write('Server failed to start: ' + err.message + '\n');
process.exit(1);
}
var address = server.address();
var url = 'http://' + address.address + ':' + address.port;
var profile = path.join(__dirname, '../build/slimerjs-profile');
var args = [
'-profile',
profile,
path.join(__dirname,
'../test_rendering/test.js'),
url + '/test_rendering/index.html'
];
var child = spawn(slimerjs.path, args, {stdio: 'inherit'});
child.on('exit', function(code) {
// FIXME SlimerJS has a problem with returning the correct return
// code when using a custom profile, see
// https://github.com/laurentj/slimerjs/issues/333
// as a work-around we are currently reading the return code from
// a file created in the profile directory.
// if this issue is fixed we should use the npm package 'slimerjs'
// instead of the nightly build 'slimerjs-edge'.
var exitstatus = path.join(profile, 'exitstatus');
fs.readFile(exitstatus, {encoding: 'utf-8'}, function(err, data) {
if (err) {
process.stderr.write(
'Error getting the exit status of SlimerJS' + '\n');
process.stderr.write(err);
process.exit(1);
} else {
process.exit(data);
}
});
});
});
});
+4 -1
View File
@@ -81,6 +81,9 @@ if (require.main === module) {
}); });
} }
module.exports = runTests; module.exports = {
runTests: runTests,
listen: listen
};
+2 -1
View File
@@ -693,7 +693,8 @@ describe('ol.format.GeoJSON', function() {
var newPoint = format.readGeometry(geojson, { var newPoint = format.readGeometry(geojson, {
featureProjection: 'EPSG:3857' featureProjection: 'EPSG:3857'
}); });
expect(point.getCoordinates()[0]).to.eql(newPoint.getCoordinates()[0]); expect(point.getCoordinates()[0]).to.roughlyEqual(
newPoint.getCoordinates()[0], 1e-8);
expect( expect(
Math.abs(point.getCoordinates()[1] - newPoint.getCoordinates()[1])) Math.abs(point.getCoordinates()[1] - newPoint.getCoordinates()[1]))
.to.be.lessThan(0.0000001); .to.be.lessThan(0.0000001);
+108 -1
View File
@@ -1,8 +1,13 @@
// FIXME remove afterLoadXml as it uses the wrong XML parser on IE9 // FIXME remove afterLoadXml as it uses the wrong XML parser on IE9
// helper functions for async testing // helper functions for async testing and other utility functions.
(function(global) { (function(global) {
/**
* The default tolerance for image comparisons.
*/
global.IMAGE_TOLERANCE = 1.5;
function afterLoad(type, path, next) { function afterLoad(type, path, next) {
var client = new XMLHttpRequest(); var client = new XMLHttpRequest();
client.open('GET', path, true); client.open('GET', path, true);
@@ -326,5 +331,107 @@
return this; return this;
}; };
global.createMapDiv = function(width, height) {
var target = document.createElement('div');
var style = target.style;
style.position = 'absolute';
style.left = '-1000px';
style.top = '-1000px';
style.width = width + 'px';
style.height = height + 'px';
document.body.appendChild(target);
return target;
};
global.disposeMap = function(map) {
var target = map.getTarget();
map.setTarget(null);
goog.dispose(map);
document.body.removeChild(target);
};
global.assertWebGL = function(map) {
if(!ol.has.WEBGL) {
expect().fail('No WebGL support!');
}
};
function resembleCanvas(canvas, referenceImage, tolerance, done) {
if (window.showMap) {
document.getElementById('debug').appendChild(canvas);
}
resemble(referenceImage)
.compareTo(canvas.getContext('2d').getImageData(
0, 0, canvas.width, canvas.height))
.onComplete(function(data) {
if(!data.isSameDimensions) {
expect().fail(
'The dimensions of the reference image and ' +
'the test canvas are not the same.');
}
if (data.misMatchPercentage > tolerance) {
if (window.showDiff) {
var diffImage = new Image();
diffImage.src = data.getImageDataUrl();
document.getElementById('debug').appendChild(diffImage);
}
expect(data.misMatchPercentage).to.be.below(tolerance);
}
done();
});
};
function expectResembleCanvas(map, referenceImage, tolerance, done) {
map.render();
map.on('postcompose', function(event) {
var canvas = event.context.canvas;
resembleCanvas(canvas, referenceImage, tolerance, done);
});
};
function expectResembleWebGL(map, referenceImage, tolerance, done) {
map.render();
map.on('postcompose', function(event) {
if (event.frameState.animate) {
// make sure the tile-queue is empty
return;
}
var webglCanvas = event.glContext.getCanvas();
expect(webglCanvas).to.be.a(HTMLCanvasElement);
// draw the WebGL canvas on a new canvas, because we can not create
// a 2d context for that canvas because there is already a webgl context.
var canvas = document.createElement('canvas');
canvas.width = webglCanvas.width;
canvas.height = webglCanvas.height;
canvas.getContext('2d').drawImage(webglCanvas, 0, 0,
webglCanvas.width, webglCanvas.height);
resembleCanvas(canvas, referenceImage, tolerance, done);
});
};
/**
* Assert that the given map resembles a reference image.
*
* @param {ol.Map} map A map using the canvas renderer.
* @param {string} referenceImage Path to the reference image.
* @param {number} tolerance The accepted mismatch tolerance.
* @param {function} done A callback to indicate that the test is done.
*/
global.expectResemble = function(map, referenceImage, tolerance, done) {
if (map.getRenderer() instanceof ol.renderer.canvas.Map) {
expectResembleCanvas(map, referenceImage, tolerance, done);
} else if (map.getRenderer() instanceof ol.renderer.webgl.Map) {
expectResembleWebGL(map, referenceImage, tolerance, done);
} else {
expect().fail(
'resemble only works with the canvas and WebGL renderer.');
}
};
})(this); })(this);
+25
View File
@@ -0,0 +1,25 @@
# Rendering tests
This directory contains rendering tests which compare a rendered map with a
reference image using [resemble.js](http://huddle.github.io/Resemble.js/).
Similar to the unit tests, there are two ways to run the tests: directly in the
browser or using [SlimerJS](http://slimerjs.org/) from the command-line.
To run the tests in the browser, make sure the development server is running
(`./build.py serve`) and open the URL
[http://localhost:3000/test_rendering/index.html](http://localhost:3000/test_rendering/index.html).
From the command-line the tests can be run with the build target `./build.py test-rendering`.
## Adding new tests
When creating a new test case, a reference image has to be created. By appending `?generate`
to the URL, a canvas with the rendered map will be shown on the page when calling
`expectResemble`. Then the reference image can simply be created with a right-click
and "Save image as".
It is recommended to only run a single test case when generating the reference image.
## Image difference
When a test fails, an image showing the difference between the reference image and the
rendered map can be displayed by appending `?showdiff` to the URL.
+93
View File
@@ -0,0 +1,93 @@
<!DOCTYPE html>
<html>
<head>
<title>OL Rendering Test Runner</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="../node_modules/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script type="text/javascript" src="../node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="../node_modules/expect.js/index.js"></script>
<script type="text/javascript" src="../node_modules/sinon/pkg/sinon.js"></script>
<script type="text/javascript" src="../node_modules/mocha/mocha.js"></script>
<script type="text/javascript" src="../node_modules/proj4/dist/proj4.js"></script>
<script type="text/javascript" src="../node_modules/resemblejs/resemble.js"></script>
<script type="text/javascript" src="../test/test-extensions.js"></script>
<script>
mocha.setup({
ui: 'bdd',
bail: false
});
</script>
<!-- This script is provided by the debug server (start with `build.py serve`) -->
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
/**
* The goog.dom.ViewportSizeMonitor (used in map.js) creates a global leak
* by setting goog.UID_PROPERTY_ on the monitored window. In order to test
* that we don't have other global leaks, we preemptively set the property
* so Mocha can compare the global before and after our tests.
*
* In addition, calling goog.events.listen on the global object (as done
* in deviceorientation.js) creates a second leak by setting
* goog.events.LISTENER_MAP_PROP_ on the global object.
*
* We preemptively set both of these properties so Mocha can compare the
* global before and after tests. The call to goog.events.listen also
* calls goog.getUid.
*/
goog.events.listen(this, 'test', function() {});
var errors = [];
var runner = mocha.run(function(evt) {
if (window.callPhantom) {
window.callPhantom(errors);
}
});
window.showDiff = false;
if (window.location.search.indexOf('showdiff') >= 0) {
// show a difference image if '?showdiff' is in the URL
window.showDiff = true;
}
window.showMap = false;
if (window.location.search.indexOf('generate') >= 0) {
// show the canvas of the test map if '?generate' is in the URL
window.showMap = true;
}
if (window.console && console.log) {
// write stacks to the console for failed tests
runner.on('fail', function(test, err) {
if (test.duration > test._timeout) {
var titles = [];
for (var p = test; p; p = p.parent) {
if (p.title) {
titles.unshift(p.title);
}
}
console.log('Test timed out:', titles.join(' > '));
}
errors.push({
title: test.fullTitle(),
errorStack: test.err
});
console.log(test.fullTitle());
console.error(test.err.stack);
});
}
</script>
<!--
Tests should not depend on any specific markup and should instead create
whatever elements are needed (cleaning up when done).
-->
<div id="debug"></div>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
user_pref("webgl.force-enabled", true);
user_pref("webgl.disabled", false);
user_pref("webgl.msaa-force", true);
+3
View File
@@ -0,0 +1,3 @@
{
"created": 1427803527460
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

@@ -0,0 +1,94 @@
goog.provide('ol.test.rendering.layer.Image');
describe('ol.rendering.layer.Image', function() {
var target, map;
function createMap(renderer) {
target = createMapDiv(50, 50);
map = new ol.Map({
target: target,
renderer: renderer,
view: new ol.View({
center: ol.proj.transform(
[-122.416667, 37.783333], 'EPSG:4326', 'EPSG:3857'),
zoom: 5
})
});
return map;
}
function waitForImages(sources, layerOptions, onImagesLoaded) {
var imagesLoading = 0;
var imagesLoaded = 0;
var update = function() {
if (imagesLoading === imagesLoaded) {
onImagesLoaded();
}
};
goog.array.forEach(sources, function(source) {
source.on('imageloadstart', function(event) {
imagesLoading++;
});
source.on('imageloadend', function(event) {
imagesLoaded++;
update();
});
source.on('imageloaderror', function(event) {
expect().fail('Image failed to load');
});
var options = {
source: source
};
goog.object.extend(options, layerOptions);
map.addLayer(new ol.layer.Image(options));
});
}
describe('single image layer', function() {
var source;
beforeEach(function() {
source = new ol.source.ImageStatic({
url: 'spec/ol/data/tiles/osm/5/5/12.png',
imageExtent: new ol.tilegrid.XYZ({}).getTileCoordExtent(
[5, 5, -12 - 1]),
projection: ol.proj.get('EPSG:3857')
});
});
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
waitForImages([source], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/image-canvas.png',
IMAGE_TOLERANCE, done);
});
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
waitForImages([source], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/image-webgl.png',
IMAGE_TOLERANCE, done);
});
});
});
});
goog.require('goog.array');
goog.require('goog.object');
goog.require('ol.proj');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Image');
goog.require('ol.source.ImageStatic');
goog.require('ol.tilegrid.XYZ');
+155
View File
@@ -0,0 +1,155 @@
goog.provide('ol.test.rendering.layer.Tile');
describe('ol.rendering.layer.Tile', function() {
var target, map;
function createMap(renderer) {
target = createMapDiv(50, 50);
map = new ol.Map({
target: target,
renderer: renderer,
view: new ol.View({
center: ol.proj.transform(
[-122.416667, 37.783333], 'EPSG:4326', 'EPSG:3857'),
zoom: 5
})
});
return map;
}
function waitForTiles(sources, layerOptions, onTileLoaded) {
var tilesLoading = 0;
var tileLoaded = 0;
var update = function() {
if (tilesLoading === tileLoaded) {
onTileLoaded();
}
};
goog.array.forEach(sources, function(source) {
source.on('tileloadstart', function(event) {
tilesLoading++;
});
source.on('tileloadend', function(event) {
tileLoaded++;
update();
});
source.on('tileloaderror', function(event) {
expect().fail('Tile failed to load');
});
var options = {
source: source
};
goog.object.extend(options, layerOptions);
map.addLayer(new ol.layer.Tile(options));
});
}
describe('single tile layer', function() {
var source;
beforeEach(function() {
source = new ol.source.XYZ({
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
});
});
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
waitForTiles([source], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/osm-canvas.png',
IMAGE_TOLERANCE, done);
});
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
waitForTiles([source], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/osm-webgl.png',
IMAGE_TOLERANCE, done);
});
});
});
describe('two tile layers', function() {
var source1, source2;
beforeEach(function() {
source1 = new ol.source.XYZ({
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
});
source2 = new ol.source.XYZ({
url: 'spec/ol/data/tiles/stamen-labels/{z}/{x}/{y}.png'
});
});
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
waitForTiles([source1, source2], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas.png',
IMAGE_TOLERANCE, done);
});
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
waitForTiles([source1, source2], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/2-layers-webgl.png',
IMAGE_TOLERANCE, done);
});
});
});
describe('tile layer with opacity', function() {
var source;
beforeEach(function() {
source = new ol.source.XYZ({
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
});
});
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
waitForTiles([source], {opacity: 0.2}, function() {
expectResemble(map, 'spec/ol/layer/expected/opacity-canvas.png',
IMAGE_TOLERANCE, done);
});
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
waitForTiles([source], {opacity: 0.2}, function() {
expectResemble(map, 'spec/ol/layer/expected/opacity-webgl.png',
IMAGE_TOLERANCE, done);
});
});
});
});
goog.require('goog.array');
goog.require('goog.object');
goog.require('ol.proj');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Tile');
goog.require('ol.source.XYZ');
+124
View File
@@ -0,0 +1,124 @@
goog.provide('ol.test.rendering.Map');
describe('ol.rendering.Map', function() {
var target, map;
function createMap(renderer) {
target = createMapDiv(50, 50);
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [new ol.Feature({
geometry: new ol.geom.Point([0, 0])
})]
})
});
map = new ol.Map({
target: target,
renderer: renderer,
layers: [vectorLayer],
view: new ol.View({
projection: 'EPSG:4326',
center: [0, 0],
resolution: 1
})
});
return map;
}
describe('#render()', function() {
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
expectResemble(
map, 'spec/ol/expected/render-canvas.png', IMAGE_TOLERANCE, done);
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
expectResemble(
map, 'spec/ol/expected/render-webgl.png', IMAGE_TOLERANCE, done);
});
});
describe('#pan()', function() {
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
map.getView().setCenter([10, 10]);
expectResemble(
map, 'spec/ol/expected/pan-canvas.png', IMAGE_TOLERANCE, done);
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
map.getView().setCenter([10, 10]);
expectResemble(
map, 'spec/ol/expected/pan-webgl.png', IMAGE_TOLERANCE, done);
});
});
describe('#rotate()', function() {
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
map.getView().setRotation(90);
map.getView().setCenter([10, 10]);
expectResemble(
map, 'spec/ol/expected/rotate-canvas.png', IMAGE_TOLERANCE, done);
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
map.getView().setRotation(90);
map.getView().setCenter([10, 10]);
expectResemble(
map, 'spec/ol/expected/rotate-webgl.png', IMAGE_TOLERANCE, done);
});
});
describe('#zoom()', function() {
afterEach(function() {
disposeMap(map);
});
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
map.getView().setCenter([10, 10]);
map.getView().setResolution(2);
expectResemble(
map, 'spec/ol/expected/zoom-canvas.png', IMAGE_TOLERANCE, done);
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
map.getView().setCenter([10, 10]);
map.getView().setResolution(2);
expectResemble(
map, 'spec/ol/expected/zoom-webgl.png', IMAGE_TOLERANCE, done);
});
});
});
goog.require('goog.dispose');
goog.require('ol.Feature');
goog.require('ol.geom.Point');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
+201
View File
@@ -0,0 +1,201 @@
goog.provide('ol.test.rendering.style.Circle');
describe('ol.rendering.style.Circle', function() {
var target, map, vectorSource;
function createMap(renderer) {
target = createMapDiv(50, 50);
vectorSource = new ol.source.Vector();
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map = new ol.Map({
target: target,
renderer: renderer,
layers: [vectorLayer],
view: new ol.View({
projection: 'EPSG:4326',
center: [0, 0],
resolution: 1
})
});
return map;
}
describe('#render', function() {
afterEach(function() {
disposeMap(map);
});
function createFeatures() {
var feature;
feature = new ol.Feature({
geometry: new ol.geom.Point([-20, 18])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 2,
fill: new ol.style.Fill({
color: '#91E339'
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([-10, 18])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 4,
fill: new ol.style.Fill({
color: '#5447E6'
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([4, 18])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: '#92A8A6'
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([-20, 3])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 2,
fill: new ol.style.Fill({
color: '#91E339'
}),
stroke: new ol.style.Stroke({
color: '#000000',
width: 1
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([-10, 3])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 4,
fill: new ol.style.Fill({
color: '#5447E6'
}),
stroke: new ol.style.Stroke({
color: '#000000',
width: 2
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([4, 3])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: '#92A8A6'
}),
stroke: new ol.style.Stroke({
color: '#000000',
width: 3
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([-20, -15])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 2,
stroke: new ol.style.Stroke({
color: '#256308',
width: 1
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([-10, -15])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 4,
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.3)'
}),
stroke: new ol.style.Stroke({
color: '#256308',
width: 2
})
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([4, -15])
});
feature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: 'rgba(235, 45, 70, 0.6)'
}),
stroke: new ol.style.Stroke({
color: '#256308',
width: 3
})
})
}));
vectorSource.addFeature(feature);
}
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
createFeatures();
expectResemble(map, 'spec/ol/style/expected/circle-canvas.png',
6.0, done);
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
createFeatures();
expectResemble(map, 'spec/ol/style/expected/circle-webgl.png',
7.0, done);
});
});
});
goog.require('goog.dispose');
goog.require('ol.Feature');
goog.require('ol.geom.Point');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Style');
goog.require('ol.style.Stroke');
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+85
View File
@@ -0,0 +1,85 @@
goog.provide('ol.test.rendering.style.Icon');
describe('ol.rendering.style.Icon', function() {
var target, map, vectorSource;
function createMap(renderer) {
target = createMapDiv(50, 50);
vectorSource = new ol.source.Vector();
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map = new ol.Map({
target: target,
renderer: renderer,
layers: [vectorLayer],
view: new ol.View({
projection: 'EPSG:4326',
center: [0, 0],
resolution: 1
})
});
return map;
}
describe('#render', function() {
afterEach(function() {
disposeMap(map);
});
function createFeatures(callback) {
var feature;
feature = new ol.Feature({
geometry: new ol.geom.Point([0, 0])
});
var img = new Image();
img.onload = function() {
feature.setStyle(new ol.style.Style({
image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
scale: 0.5,
img: img,
imgSize: [32, 48]
}))
}));
vectorSource.addFeature(feature);
callback();
};
img.src = 'spec/ol/data/icon.png';
}
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
createFeatures(function() {
expectResemble(map, 'spec/ol/style/expected/icon-canvas.png',
IMAGE_TOLERANCE, done);
});
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
createFeatures(function() {
expectResemble(map, 'spec/ol/style/expected/icon-webgl.png',
IMAGE_TOLERANCE, done);
});
});
});
});
goog.require('goog.dispose');
goog.require('ol.Feature');
goog.require('ol.geom.Point');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Icon');
goog.require('ol.style.Style');
@@ -0,0 +1,102 @@
goog.provide('ol.test.rendering.style.LineString');
describe('ol.rendering.style.LineString', function() {
var target, map, vectorSource;
function createMap(renderer) {
target = createMapDiv(50, 50);
vectorSource = new ol.source.Vector();
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map = new ol.Map({
target: target,
renderer: renderer,
layers: [vectorLayer],
view: new ol.View({
projection: 'EPSG:4326',
center: [0, 0],
resolution: 1
})
});
return map;
}
describe('different strokes', function() {
afterEach(function() {
disposeMap(map);
});
function createFeatures() {
var feature;
feature = new ol.Feature({
geometry: new ol.geom.LineString(
[[-20, 20], [15, 20]]
)
});
feature.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({color: '#DE213A', width: 3})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.LineString(
[[-20, 15], [15, 15]]
)
});
feature.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({color: '#9696EB', width: 1})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.LineString(
[[-20, 10], [15, 10]]
)
});
feature.setStyle([new ol.style.Style({
stroke: new ol.style.Stroke({color: '#F2F211', width: 5})
}), new ol.style.Style({
stroke: new ol.style.Stroke({color: '#292921', width: 1})
})]);
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.LineString(
[[-20, -20], [-2, 0], [15, -20]]
)
});
feature.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#000000',
width: 2,
lineCap: 'square',
lineJoin: 'round'
})
}));
vectorSource.addFeature(feature);
}
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
createFeatures();
expectResemble(
map, 'spec/ol/style/expected/linestring-strokes-canvas.png',
3.0, done);
});
});
});
goog.require('goog.dispose');
goog.require('ol.Feature');
goog.require('ol.geom.LineString');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Style');
goog.require('ol.style.Stroke');
@@ -0,0 +1,200 @@
goog.provide('ol.test.rendering.style.Polygon');
describe('ol.rendering.style.Polygon', function() {
var target, map, vectorSource;
function createMap(renderer) {
target = createMapDiv(50, 50);
vectorSource = new ol.source.Vector();
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map = new ol.Map({
target: target,
renderer: renderer,
layers: [vectorLayer],
view: new ol.View({
projection: 'EPSG:4326',
center: [0, 0],
resolution: 1
})
});
return map;
}
describe('different types', function() {
afterEach(function() {
disposeMap(map);
});
function createFeatures() {
var fill = new ol.style.Fill({color: 'red'});
var feature;
// rectangle
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[-20, 10], [-20, 20], [-5, 20], [-5, 10], [-20, 10]]
])
});
feature.setStyle(new ol.style.Style({
fill: fill
}));
vectorSource.addFeature(feature);
// rectangle with 1 hole
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[0, 10], [0, 20], [15, 20], [15, 10], [0, 10]],
[[5, 13], [10, 13], [10, 17], [5, 17], [5, 13]]
])
});
feature.setStyle(new ol.style.Style({
fill: fill
}));
vectorSource.addFeature(feature);
// rectangle with 2 holes
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[-20, -20], [-20, 5], [15, 5], [15, -20], [-20, -20]],
[[-18, -18], [-12, -18], [-12, -12], [-18, -12], [-18, -18]],
[[5, -18], [12, -18], [12, -12], [5, -12], [5, -18]]
])
});
feature.setStyle(new ol.style.Style({
fill: fill
}));
vectorSource.addFeature(feature);
}
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
createFeatures();
expectResemble(map, 'spec/ol/style/expected/polygon-types-canvas.png',
IMAGE_TOLERANCE, done);
});
});
describe('z-index', function() {
afterEach(function() {
disposeMap(map);
});
function createFeatures() {
var feature;
// rectangle with z-index 2
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[-20, 10], [-20, 20], [-0, 20], [-0, 10], [-20, 10]]
])
});
feature.setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: '#E31E10'}),
zIndex: 2
}));
vectorSource.addFeature(feature);
// rectangle with z-index 3
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[-15, 5], [-15, 15], [5, 15], [5, 5], [-15, 5]]
])
});
feature.setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: '#1A5E42'}),
zIndex: 3
}));
vectorSource.addFeature(feature);
// rectangle with z-index 1
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[-10, 0], [-10, 10], [10, 10], [10, 0], [-10, 0]]
])
});
feature.setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: '#DEDE21'}),
zIndex: 1
}));
vectorSource.addFeature(feature);
}
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
createFeatures();
expectResemble(map, 'spec/ol/style/expected/polygon-zindex-canvas.png',
IMAGE_TOLERANCE, done);
});
});
describe('different fills and strokes', function() {
afterEach(function() {
disposeMap(map);
});
function createFeatures() {
var feature;
// rectangle
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[-20, 10], [-20, 20], [-5, 20], [-5, 10], [-20, 10]]
])
});
feature.setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: '#9696EB'}),
stroke: new ol.style.Stroke({color: '#9696EB', width: 1})
}));
vectorSource.addFeature(feature);
// rectangle with 1 hole
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[0, 10], [0, 20], [15, 20], [15, 10], [0, 10]]
])
});
feature.setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: 'rgba(255, 0, 0, 0.1)'}),
stroke: new ol.style.Stroke({color: '#DE213A', width: 3})
}));
vectorSource.addFeature(feature);
// rectangle with 2 holes
feature = new ol.Feature({
geometry: new ol.geom.Polygon([
[[-20, -20], [-20, 5], [15, 5], [15, -20], [-20, -20]]
])
});
feature.setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: 'rgba(18, 204, 105, 0.3)'}),
stroke: new ol.style.Stroke({color: '#032E17', width: 2})
}));
vectorSource.addFeature(feature);
}
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
createFeatures();
expectResemble(
map, 'spec/ol/style/expected/polygon-fill-and-strokes-canvas.png',
IMAGE_TOLERANCE, done);
});
});
});
goog.require('goog.dispose');
goog.require('ol.Feature');
goog.require('ol.geom.Polygon');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.Style');
goog.require('ol.style.Stroke');
@@ -0,0 +1,129 @@
goog.provide('ol.test.rendering.style.RegularShape');
describe('ol.rendering.style.RegularShape', function() {
var target, map, vectorSource;
function createMap(renderer) {
target = createMapDiv(50, 50);
vectorSource = new ol.source.Vector();
vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map = new ol.Map({
target: target,
renderer: renderer,
layers: [vectorLayer],
view: new ol.View({
projection: 'EPSG:4326',
center: [0, 0],
resolution: 1
})
});
return map;
}
describe('#render', function() {
afterEach(function() {
disposeMap(map);
});
function createFeatures() {
var stroke = new ol.style.Stroke({color: 'black', width: 2});
var fill = new ol.style.Fill({color: 'red'});
var feature;
feature = new ol.Feature({
geometry: new ol.geom.Point([-15, 15])
});
// square
feature.setStyle(new ol.style.Style({
image: new ol.style.RegularShape({
fill: fill,
stroke: stroke,
points: 4,
radius: 10,
angle: Math.PI / 4
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([8, 15])
});
// triangle
feature.setStyle(new ol.style.Style({
image: new ol.style.RegularShape({
fill: fill,
stroke: stroke,
points: 3,
radius: 10,
rotation: Math.PI / 4,
angle: 0
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([-10, -8])
});
// star
feature.setStyle(new ol.style.Style({
image: new ol.style.RegularShape({
fill: fill,
stroke: stroke,
points: 5,
radius: 10,
radius2: 4,
angle: 0
})
}));
vectorSource.addFeature(feature);
feature = new ol.Feature({
geometry: new ol.geom.Point([12, -8])
});
// cross
feature.setStyle(new ol.style.Style({
image: new ol.style.RegularShape({
fill: fill,
stroke: stroke,
points: 4,
radius: 10,
radius2: 0,
angle: 0
})
}));
vectorSource.addFeature(feature);
}
it('tests the canvas renderer', function(done) {
map = createMap('canvas');
createFeatures();
expectResemble(map, 'spec/ol/style/expected/regularshape-canvas.png',
6.0, done);
});
it('tests the WebGL renderer', function(done) {
assertWebGL();
map = createMap('webgl');
createFeatures();
expectResemble(map, 'spec/ol/style/expected/regularshape-webgl.png',
IMAGE_TOLERANCE, done);
});
});
});
goog.require('goog.dispose');
goog.require('ol.Feature');
goog.require('ol.geom.Point');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Fill');
goog.require('ol.style.RegularShape');
goog.require('ol.style.Style');
goog.require('ol.style.Stroke');
+30
View File
@@ -0,0 +1,30 @@
var url = phantom.args[0];
var page = require("webpage").create();
var v = slimer.geckoVersion;
console.log('Gecko: ' + v.major + '.' + v.minor + '.' + v.patch);
page.open(url).
then(function(status){
if (status == "success") {
page.onCallback = function(failedTests) {
if (failedTests.length > 0) {
for (var i = 0; i < failedTests.length; i++) {
var test = failedTests[i];
console.log(test.title);
console.error(test.errorStack);
console.log('');
}
console.error(failedTests.length + ' test(s) failed.');
} else {
console.log('All tests passed.');
}
page.close();
phantom.exit(failedTests.length === 0 ? 0 : 1);
}
} else {
console.error("The tests could not be started. Is the server running?");
page.close();
phantom.exit(1);
}
});