Merge pull request #6953 from tschaub/tests
Run tests in real browsers with Karma
1
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
/build/
|
||||
/node_modules/
|
||||
/dist/
|
||||
/coverage/
|
||||
|
||||
36
.travis.yml
@@ -1,33 +1,19 @@
|
||||
sudo: false
|
||||
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "6.1"
|
||||
|
||||
addons:
|
||||
firefox: "52.0"
|
||||
|
||||
- '8'
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
env:
|
||||
- DISPLAY=:99.0
|
||||
|
||||
before_install:
|
||||
- "npm prune"
|
||||
|
||||
- node_modules
|
||||
before_script:
|
||||
- "rm src/ol/renderer/webgl/*shader.js"
|
||||
- "sh -e /etc/init.d/xvfb start"
|
||||
- "npm ls || true"
|
||||
|
||||
script: "make ci"
|
||||
|
||||
after_success:
|
||||
- "make test-coverage"
|
||||
- "cat coverage/lcov.info | ./node_modules/.bin/coveralls"
|
||||
|
||||
- rm src/ol/renderer/webgl/*shader.js
|
||||
script: make ci
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- master
|
||||
addons:
|
||||
sauce_connect:
|
||||
username: openlayers
|
||||
jwt:
|
||||
# This is the encrypted SAUCE_ACCESS_KEY
|
||||
secure: bb2Ibzu9RLe6ZlIG7JVcuH7IoLMxa/i3LTM7t8mbsPjVOGs5ycyJ7M9MbvqB/F2EzbeV4XB2c9ufI4TkaLYceY5kdWjfZVN8iasr+GFqKMv1uR4i6bpu8KmHJ+blxwfY1QOQ/cGwEx+fbeycMtpTc3Y3GyXaPlCQLhbZvesMg88=
|
||||
|
||||
48
Makefile
@@ -6,9 +6,6 @@ SRC_SHADER_JS := $(patsubst %shader.glsl,%shader.js,$(SRC_GLSL))
|
||||
SRC_JS := $(filter-out $(SRC_SHADER_JS),$(shell find src -name '*.js'))
|
||||
SRC_JSDOC = $(shell find src -type f -name '*.jsdoc')
|
||||
|
||||
SPEC_JS := $(shell find test/spec -type f -name '*.js')
|
||||
SPEC_RENDERING_JS := $(shell find test_rendering/spec -name '*.js')
|
||||
|
||||
EXAMPLES := $(shell find examples -type f)
|
||||
EXAMPLES_HTML := $(filter-out examples/index.html,$(shell find examples -maxdepth 1 -type f -name '*.html'))
|
||||
EXAMPLES_JS := $(patsubst %.html,%.js,$(EXAMPLES_HTML))
|
||||
@@ -56,7 +53,6 @@ help:
|
||||
@echo "Other less frequently used targets are:"
|
||||
@echo
|
||||
@echo "- build Build ol.js, ol-debug.js, ol.js.map and ol.css"
|
||||
@echo "- lint Check the code with the linter"
|
||||
@echo "- ci Run the full continuous integration process"
|
||||
@echo "- apidoc Build the API documentation using JSDoc"
|
||||
@echo "- cleanall Remove all the build artefacts"
|
||||
@@ -70,7 +66,7 @@ apidoc: build/timestamps/jsdoc-$(BRANCH)-timestamp
|
||||
build: build/ol.css build/ol.js build/ol-debug.js build/ol.js.map
|
||||
|
||||
.PHONY: check
|
||||
check: lint build/ol.js test
|
||||
check: build/ol.js test
|
||||
|
||||
.PHONY: check-examples
|
||||
check-examples: $(CHECK_EXAMPLE_TIMESTAMPS)
|
||||
@@ -86,21 +82,18 @@ check-deps:
|
||||
done ;\
|
||||
|
||||
.PHONY: ci
|
||||
ci: lint build test test-rendering package compile-examples check-examples apidoc
|
||||
ci: build test package compile-examples check-examples apidoc
|
||||
|
||||
.PHONY: compile-examples
|
||||
compile-examples: build/compiled-examples/all.combined.js
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f build/timestamps/eslint-timestamp
|
||||
rm -f build/timestamps/check-*-timestamp
|
||||
rm -f build/ol.css
|
||||
rm -f build/ol.js
|
||||
rm -f build/ol.js.map
|
||||
rm -f build/ol-debug.js
|
||||
rm -f build/test_requires.js
|
||||
rm -f build/test_rendering_requires.js
|
||||
rm -rf build/examples
|
||||
rm -rf build/compiled-examples
|
||||
rm -rf build/package
|
||||
@@ -119,9 +112,6 @@ examples: $(BUILD_EXAMPLES)
|
||||
.PHONY: install
|
||||
install: build/timestamps/node-modules-timestamp
|
||||
|
||||
.PHONY: lint
|
||||
lint: build/timestamps/eslint-timestamp
|
||||
|
||||
.PHONY: npm-install
|
||||
npm-install: build/timestamps/node-modules-timestamp
|
||||
|
||||
@@ -129,24 +119,12 @@ npm-install: build/timestamps/node-modules-timestamp
|
||||
shaders: $(SRC_SHADER_JS)
|
||||
|
||||
.PHONY: serve
|
||||
serve: build/test_requires.js build/test_rendering_requires.js
|
||||
serve:
|
||||
node tasks/serve.js
|
||||
|
||||
.PHONY: test
|
||||
test: build/timestamps/node-modules-timestamp build/test_requires.js
|
||||
node tasks/test.js
|
||||
|
||||
.PHONY: test-coverage
|
||||
test-coverage: build/timestamps/node-modules-timestamp
|
||||
node tasks/test-coverage.js
|
||||
|
||||
.PHONY: test-rendering
|
||||
test-rendering: build/timestamps/node-modules-timestamp \
|
||||
build/test_rendering_requires.js
|
||||
@rm -rf build/slimerjs-profile
|
||||
@mkdir -p build/slimerjs-profile
|
||||
@cp -r test_rendering/slimerjs-profile/* build/slimerjs-profile/
|
||||
node tasks/test-rendering.js
|
||||
test: build/timestamps/node-modules-timestamp
|
||||
npm test
|
||||
|
||||
.PHONY: host-examples
|
||||
host-examples: $(BUILD_HOSTED_EXAMPLES) \
|
||||
@@ -248,14 +226,6 @@ $(BUILD_HOSTED)/build/ol-deps.js: host-libraries
|
||||
--root_with_prefix "$(BUILD_HOSTED)/closure-library/third_party ../../third_party" \
|
||||
--output_file $@
|
||||
|
||||
build/timestamps/eslint-timestamp: $(SRC_JS) $(SPEC_JS) $(SPEC_RENDERING_JS) \
|
||||
$(TASKS_JS) $(EXAMPLES_JS) \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
@echo "Running eslint..."
|
||||
@./node_modules/.bin/eslint tasks test test_rendering src examples
|
||||
@touch $@
|
||||
|
||||
build/timestamps/node-modules-timestamp: package.json
|
||||
@mkdir -p $(@D)
|
||||
npm install
|
||||
@@ -291,14 +261,6 @@ build/ol-debug.js: config/ol-debug.json $(SRC_JS) $(SRC_SHADER_JS) \
|
||||
@$(STAT_COMPRESSED) /tmp/ol-debug.js.gz
|
||||
@rm /tmp/ol-debug.js.gz
|
||||
|
||||
build/test_requires.js: $(SPEC_JS) $(SRC_JS)
|
||||
@mkdir -p $(@D)
|
||||
@node tasks/generate-requires.js $^ > $@
|
||||
|
||||
build/test_rendering_requires.js: $(SPEC_RENDERING_JS)
|
||||
@mkdir -p $(@D)
|
||||
@node tasks/generate-requires.js $^ > $@
|
||||
|
||||
%shader.js: %shader.glsl src/ol/webgl/shader.mustache bin/pyglslunit.py build/timestamps/node-modules-timestamp
|
||||
@python bin/pyglslunit.py --input $< | ./node_modules/.bin/mustache - src/ol/webgl/shader.mustache > $@
|
||||
|
||||
|
||||
13
package.json
@@ -12,10 +12,12 @@
|
||||
"install": "node tasks/install.js",
|
||||
"postinstall": "closure-util update",
|
||||
"start": "node tasks/serve.js",
|
||||
"pretest": "eslint tasks test test_rendering src examples",
|
||||
"lint": "eslint tasks test src examples",
|
||||
"lint-package": "eslint --fix build/package",
|
||||
"test": "node tasks/test.js",
|
||||
"debug-server": "node tasks/serve-lib.js"
|
||||
"pretest": "npm run lint",
|
||||
"test": "npm run karma -- --single-run",
|
||||
"debug-server": "node tasks/serve-lib.js",
|
||||
"karma": "node tasks/test.js start test/karma.config.js"
|
||||
},
|
||||
"main": "dist/ol.js",
|
||||
"repository": {
|
||||
@@ -61,6 +63,11 @@
|
||||
"istanbul": "0.4.5",
|
||||
"jquery": "3.2.1",
|
||||
"jscodeshift": "^0.3.30",
|
||||
"karma": "^1.7.0",
|
||||
"karma-chrome-launcher": "^2.1.1",
|
||||
"karma-firefox-launcher": "^1.0.1",
|
||||
"karma-mocha": "^1.3.0",
|
||||
"karma-sauce-launcher": "^1.1.0",
|
||||
"marked": "0.3.6",
|
||||
"metalsmith": "2.3.0",
|
||||
"metalsmith-layouts": "1.8.1",
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
var fs = require('fs-extra');
|
||||
|
||||
// The number of files that we need to generate goog.require's for.
|
||||
var numFiles = process.argv.length - 1;
|
||||
|
||||
/**
|
||||
* Object used a set of found goog.provide's.
|
||||
* @type {Object.<string, boolean>}
|
||||
*/
|
||||
var requires = {};
|
||||
|
||||
process.argv.forEach(function(val, index, array) {
|
||||
|
||||
if (index === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
fs.readFile(val, function(err, data) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
var re = new RegExp('goog\\.provide\\(\'(.*)\'\\);');
|
||||
|
||||
data.toString().split('\n').forEach(function(line) {
|
||||
var match = line.match(re);
|
||||
if (match) {
|
||||
requires[match[1]] = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (--numFiles === 0) {
|
||||
Object.keys(requires).sort().forEach(function(key) {
|
||||
process.stdout.write('goog.require(\'' + key + '\');\n');
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,210 +0,0 @@
|
||||
/**
|
||||
* This task instruments our source code with istanbul, runs the test suite
|
||||
* on the instrumented source and collects the coverage data. It then creates
|
||||
* test coverage reports.
|
||||
*
|
||||
* TODO This can be improved in style. We should possibly rewrite it and use
|
||||
* async.waterfall.
|
||||
*/
|
||||
|
||||
var fs = require('fs-extra');
|
||||
var istanbul = require('istanbul');
|
||||
var path = require('path');
|
||||
var glob = require('glob');
|
||||
|
||||
var runTestsuite = require('./test').runTests;
|
||||
|
||||
// setup some paths
|
||||
var dir = path.join(__dirname, '../src');
|
||||
var backupDir = path.join(__dirname, '../src-backup');
|
||||
var instrumentedDir = path.join(__dirname, '../src-instrumented');
|
||||
var coverageDir = path.join(__dirname, '../coverage');
|
||||
|
||||
fs.mkdirSync(coverageDir);
|
||||
|
||||
// The main players in the coverage generation via istanbul
|
||||
var instrumenter = new istanbul.Instrumenter();
|
||||
var reporter = new istanbul.Reporter(false, coverageDir);
|
||||
var collector = new istanbul.Collector();
|
||||
|
||||
// General options used for the resource shuffling / directory copying
|
||||
var copyOpts = {
|
||||
// Overwrite existing file or directory
|
||||
clobber: true,
|
||||
// Preserve the mtime and atime when copying files
|
||||
preserveTimestamps: true
|
||||
};
|
||||
|
||||
/**
|
||||
* A small utility method printing out log messages.
|
||||
* @param {string} msg The message.
|
||||
*/
|
||||
var log = function(msg) {
|
||||
process.stdout.write(msg + '\n');
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates folders for backup and instrumentation and copies the contents of the
|
||||
* current src folder into them.
|
||||
*/
|
||||
var setupBackupAndInstrumentationDir = function() {
|
||||
if (!fs.existsSync(backupDir)) {
|
||||
log('• create directory for backup of src: ' + backupDir);
|
||||
fs.mkdirSync(backupDir);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(instrumentedDir)) {
|
||||
log('• create directory for instrumented src: ' + instrumentedDir);
|
||||
fs.mkdirSync(instrumentedDir);
|
||||
}
|
||||
|
||||
log('• copy src files to backup folder');
|
||||
fs.copySync(dir, backupDir, copyOpts);
|
||||
log('• copy src files to instrumentation folder');
|
||||
fs.copySync(dir, instrumentedDir, copyOpts);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reverts the changes done in setupBackupAndInstrumentationDir, copies the
|
||||
* backup over the src directory and removes the instrumentation and backup
|
||||
* directory.
|
||||
*/
|
||||
var revertBackupAndInstrumentationDir = function() {
|
||||
log('• copy original src back to src folder');
|
||||
fs.copySync(backupDir, dir, copyOpts);
|
||||
log('• delete backup directory');
|
||||
fs.removeSync(backupDir);
|
||||
log('• delete instrumentation directory');
|
||||
fs.removeSync(instrumentedDir);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for when runTestsuite() has finished.
|
||||
*/
|
||||
var collectAndWriteCoverageData = function() {
|
||||
log('• collect data from coverage *.json files');
|
||||
|
||||
var coverageFiles = [
|
||||
path.join(__dirname, '..', 'coverage', 'coverage.json'),
|
||||
path.join(__dirname, '..', 'coverage', 'coverage-rendering.json')
|
||||
];
|
||||
coverageFiles.forEach(function(coverageFile) {
|
||||
if (fs.existsSync(coverageFile)) {
|
||||
log(' • collect data from ' + path.basename(coverageFile));
|
||||
var coverageJson = JSON.parse(fs.readFileSync(coverageFile, 'utf8'));
|
||||
collector.add(coverageJson);
|
||||
}
|
||||
});
|
||||
|
||||
reporter.addAll(['lcovonly', 'html']);
|
||||
|
||||
revertBackupAndInstrumentationDir();
|
||||
|
||||
log('• write report from collected data');
|
||||
reporter.write(collector, true, function() {
|
||||
process.exit(0);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs the rendering test by spawning a call to `make test-rendering`. The
|
||||
* `make`-call sets up certain things so that the rendering tests can actually
|
||||
* run, which is why we call it this way.
|
||||
*
|
||||
* @param {Function} callback The callback to invoke once `make` has exited.
|
||||
* Will receive the exit code.
|
||||
*/
|
||||
var runRenderingTestsuite = function(callback) {
|
||||
var spawn = require('child_process').spawn;
|
||||
var child = spawn('make', ['test-rendering'], {stdio: 'inherit'});
|
||||
child.on('exit', function(code) {
|
||||
callback(code);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive output file name from input file name, by replacing the *last*
|
||||
* occurrence of `/src/` by `/src-instrumented/`
|
||||
*
|
||||
* @param {String} file The input filename.
|
||||
* @return {String} file The output filename.
|
||||
*/
|
||||
var outputFilenameByFilename = function(file) {
|
||||
var search = '/src/';
|
||||
var replace = '/src-instrumented/';
|
||||
var re = new RegExp(search, 'g');
|
||||
var m, match;
|
||||
while ((m = re.exec(file)) !== null) {
|
||||
match = m;
|
||||
}
|
||||
var idx = match.index;
|
||||
var outfile = file.substr(0, idx) + replace +
|
||||
file.substr(idx + search.length);
|
||||
|
||||
return outfile;
|
||||
};
|
||||
|
||||
/**
|
||||
* Will instrument all JavaScript files that are passed as second parameter.
|
||||
* This is the callback to the glob call.
|
||||
* @param {Error} err Any error.
|
||||
* @param {Array.<string>} files List of file paths.
|
||||
*/
|
||||
var foundAllJavaScriptSourceFiles = function(err, files) {
|
||||
if (err) {
|
||||
process.stderr.write(err.message + '\n');
|
||||
process.exit(1);
|
||||
}
|
||||
log('• instrumenting every src file');
|
||||
var cnt = 0;
|
||||
files.forEach(function(file) {
|
||||
cnt++;
|
||||
var content = fs.readFileSync(file, 'utf-8');
|
||||
var outfile = outputFilenameByFilename(file);
|
||||
var instrumented = instrumenter.instrumentSync(content, file);
|
||||
fs.writeFileSync(outfile, instrumented);
|
||||
if (cnt % 10 === 0) {
|
||||
log(' • instrumented ' + cnt + ' files');
|
||||
}
|
||||
});
|
||||
log(' • done. ' + cnt + ' files instrumented');
|
||||
log('• copy instrumented src back to src folder');
|
||||
|
||||
fs.copySync(instrumentedDir, dir, copyOpts);
|
||||
|
||||
log('• run test suites on instrumented code');
|
||||
|
||||
log(' • run rendering test suite');
|
||||
runRenderingTestsuite(function(codeRendering) {
|
||||
if (codeRendering === 0) {
|
||||
log(' • run standard test suite');
|
||||
runTestsuite({coverage: true, reporter: 'dot'}, function(code) {
|
||||
if (code === 0) {
|
||||
collectAndWriteCoverageData();
|
||||
} else {
|
||||
process.stderr.write('Trouble running the standard testsuite\n');
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
process.stderr.write('Trouble running the rendering testsuite\n');
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Our main method, first it sets up certain directory, and then it starts the
|
||||
* coverage process by gathering all JavaScript files and then instrumenting
|
||||
* them.
|
||||
*/
|
||||
var main = function() {
|
||||
setupBackupAndInstrumentationDir();
|
||||
glob(dir + '/**/*.js', {}, foundAllJavaScriptSourceFiles);
|
||||
};
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = main;
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* This task starts a dev server that provides a script loader for OpenLayers
|
||||
* and Closure Library and runs rendering tests in SlimerJS.
|
||||
*/
|
||||
|
||||
var path = require('path');
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
var slimerjs = require('slimerjs');
|
||||
|
||||
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: 'pipe'});
|
||||
child.stdout.on('data', function(data) {
|
||||
process.stdout.write(data);
|
||||
});
|
||||
child.on('exit', function(code) {
|
||||
process.exit(code);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
165
tasks/test.js
@@ -1,95 +1,102 @@
|
||||
/**
|
||||
* This task starts a dev server that provides a script loader for OpenLayers
|
||||
* and Closure Library and runs tests in PhantomJS.
|
||||
*/
|
||||
const Server = require('karma').Server;
|
||||
const closure = require('closure-util');
|
||||
const path = require('path');
|
||||
const processCliArgs = require('karma/lib/cli').process;
|
||||
|
||||
var path = require('path');
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
var phantomjs = require('phantomjs-prebuilt');
|
||||
|
||||
var serve = require('./serve');
|
||||
|
||||
/**
|
||||
* Try listening for incoming connections on a range of ports.
|
||||
* @param {number} min Minimum port to try.
|
||||
* @param {number} max Maximum port to try.
|
||||
* @param {http.Server} server The server.
|
||||
* @param {function(Error)} callback Callback called with any error.
|
||||
*/
|
||||
function listen(min, max, server, callback) {
|
||||
function _listen(port) {
|
||||
server.once('error', function(err) {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
++port;
|
||||
if (port < max) {
|
||||
_listen(port);
|
||||
} else {
|
||||
callback(new Error('Could not find an open port'));
|
||||
}
|
||||
} else {
|
||||
callback(err);
|
||||
function insertDependencies(manager, files, previousLookup) {
|
||||
previousLookup = previousLookup || {};
|
||||
let firstIndex = NaN;
|
||||
const original = files.filter((obj, index) => {
|
||||
if (previousLookup[obj.pattern]) {
|
||||
if (isNaN(firstIndex)) {
|
||||
firstIndex = index;
|
||||
}
|
||||
});
|
||||
server.listen(port, '127.0.0.1');
|
||||
}
|
||||
server.once('listening', function() {
|
||||
callback(null);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
_listen(min);
|
||||
if (isNaN(firstIndex)) {
|
||||
firstIndex = 0;
|
||||
}
|
||||
const lookup = {};
|
||||
const dependencies = manager.getDependencies().map(script => {
|
||||
lookup[script.path] = true;
|
||||
return {
|
||||
pattern: script.path,
|
||||
included: true,
|
||||
served: true,
|
||||
watched: false
|
||||
};
|
||||
});
|
||||
original.splice.apply(original, [firstIndex, 0].concat(dependencies));
|
||||
files.length = 0;
|
||||
files.push.apply(files, original);
|
||||
|
||||
return lookup;
|
||||
}
|
||||
|
||||
|
||||
function runTests(conf, callback) {
|
||||
var coverage = 'coverage' in conf ? conf.coverage : false;
|
||||
var reporter = 'reporter' in conf ? conf.reporter : 'spec';
|
||||
/**
|
||||
* Create the debug server and run tests.
|
||||
*/
|
||||
serve.createServer(function(err, server) {
|
||||
if (err) {
|
||||
process.stderr.write(err.message + '\n');
|
||||
process.exit(1);
|
||||
/**
|
||||
* Start Karma. This prepends the Karma `files` config with all library files
|
||||
* sorted in dependency order.
|
||||
* @param {Object} config Karma options.
|
||||
* @param {Manager} manager The dependency file manager.
|
||||
* @param {function(Error)} callback Called with any error.
|
||||
*/
|
||||
function serve(config, manager, callback) {
|
||||
function exit(code) {
|
||||
let error = null;
|
||||
if (code) {
|
||||
error = new Error(`Karma exited with ${code}`);
|
||||
error.code = code;
|
||||
}
|
||||
callback(error);
|
||||
}
|
||||
const server = new Server(config, exit);
|
||||
|
||||
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 args = [
|
||||
require.resolve('mocha-phantomjs-core'),
|
||||
url + '/test/index.html',
|
||||
reporter
|
||||
];
|
||||
var config = {
|
||||
ignoreResourceErrors: true,
|
||||
useColors: true
|
||||
};
|
||||
const files = server.get('config.files');
|
||||
|
||||
if (coverage) {
|
||||
config.hooks = path.join(__dirname, '../test/phantom_hooks.js');
|
||||
}
|
||||
let lookup = insertDependencies(manager, files);
|
||||
|
||||
args.push(JSON.stringify(config));
|
||||
// stop goog base.js from trying to load deps.js
|
||||
files.unshift({
|
||||
pattern: path.resolve(__dirname, '../test/no-deps.js'),
|
||||
included: true,
|
||||
served: true,
|
||||
watched: false
|
||||
});
|
||||
|
||||
var child = spawn(phantomjs.path, args, {stdio: 'inherit'});
|
||||
child.on('exit', function(code) {
|
||||
callback(code);
|
||||
});
|
||||
});
|
||||
manager.on('update', () => {
|
||||
lookup = insertDependencies(manager, files, lookup);
|
||||
server.refreshFiles();
|
||||
});
|
||||
|
||||
server.start();
|
||||
}
|
||||
|
||||
function main(config, callback) {
|
||||
const manager = new closure.Manager({
|
||||
lib: [
|
||||
'src/**/*.js',
|
||||
'build/ol.ext/*.js'
|
||||
]
|
||||
});
|
||||
|
||||
manager.on('error', callback);
|
||||
|
||||
manager.on('ready', () => {
|
||||
serve(config, manager, callback);
|
||||
});
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
runTests({coverage: false, reporter: 'spec'}, function(code) {
|
||||
process.exit(code);
|
||||
const config = processCliArgs();
|
||||
main(config, (err, manager) => {
|
||||
if (err) {
|
||||
process.stderr.write(err.message, () => process.exit(1));
|
||||
return;
|
||||
} else {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
runTests: runTests,
|
||||
listen: listen
|
||||
};
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
{
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"openlayers-internal/no-missing-requires": 0,
|
||||
"openlayers-internal/valid-provide": 0
|
||||
},
|
||||
"globals": {
|
||||
"IMAGE_TOLERANCE": false,
|
||||
"afterLoadText": false,
|
||||
"assertWebGL": false,
|
||||
"createMapDiv": true,
|
||||
"disposeMap": true,
|
||||
"resemble": true
|
||||
"expect": false,
|
||||
"expectResemble": false,
|
||||
"proj4": false,
|
||||
"resemble": false,
|
||||
"resembleCanvas": false,
|
||||
"sinon": false,
|
||||
"where": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,21 +14,37 @@ Install the test dependencies (from the root of the repository):
|
||||
|
||||
npm install
|
||||
|
||||
Run the tests once with PhantomJS:
|
||||
Run the tests once:
|
||||
|
||||
make test
|
||||
npm test
|
||||
|
||||
(Note that for `npm` users, this can also be run as `npm test`.)
|
||||
To run the tests continuously:
|
||||
|
||||
Run the tests in a browser:
|
||||
npm run karma
|
||||
|
||||
make serve
|
||||
After this, the test server is listening on http://localhost:9876/, and you can
|
||||
attach any number of browsers for testing (during development, tests will run
|
||||
in Chrome by default).
|
||||
|
||||
(Again for `npm` users, this is `npm start`.)
|
||||
# Rendering tests
|
||||
|
||||
Now visit http://localhost:3000/test/ in your browser. The tests will re-run
|
||||
any time one of the source or spec files changes.
|
||||
The `test/rendering` directory contains rendering tests which compare a rendered map with a
|
||||
reference image using [resemble.js](http://huddle.github.io/Resemble.js/).
|
||||
|
||||
Tip for TDD'ers: to make PhantomJS run the test suite continuously each time
|
||||
a spec file is changed you can use nosier (http://pypi.python.org/pypi/nosier)
|
||||
and do `nosier -p test -p src "make test"`.
|
||||
To run the tests in the browser, make sure the development server is running
|
||||
(`make 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 `make 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.
|
||||
|
||||
102
test/karma.config.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/* eslint-env node, es6 */
|
||||
|
||||
const path = require('path');
|
||||
const pkg = require('../package.json');
|
||||
|
||||
/**
|
||||
* The config below is not enough to run Karma. In addition, we need to add
|
||||
* all library files in dependency order. This could be done with a plugin if
|
||||
* Karma supported async plugins (there may be other alternatives as well). But
|
||||
* for now we start Karma with the `tasks/test.js` script. This script
|
||||
* sorts dependencies and adds files to the Karma config below.
|
||||
*/
|
||||
|
||||
module.exports = function(karma) {
|
||||
karma.set({
|
||||
frameworks: ['mocha'],
|
||||
client: {
|
||||
runInParent: true
|
||||
},
|
||||
files: [
|
||||
{
|
||||
pattern: path.resolve(__dirname, require.resolve('jquery/dist/jquery.js')),
|
||||
watched: false
|
||||
}, {
|
||||
pattern: path.resolve(__dirname, require.resolve('expect.js/index.js')),
|
||||
watched: false
|
||||
}, {
|
||||
pattern: path.resolve(__dirname, require.resolve('sinon/pkg/sinon.js')),
|
||||
watched: false
|
||||
}, {
|
||||
pattern: path.resolve(__dirname, require.resolve('proj4/dist/proj4.js')),
|
||||
watched: false
|
||||
}, {
|
||||
pattern: path.resolve(__dirname, require.resolve('resemblejs/resemble.js')),
|
||||
watched: false
|
||||
}, {
|
||||
pattern: path.resolve(__dirname, './test-extensions.js')
|
||||
}, {
|
||||
pattern: '**/*.test.js'
|
||||
}, {
|
||||
pattern: '**/*',
|
||||
included: false,
|
||||
watched: false
|
||||
}
|
||||
],
|
||||
proxies: {
|
||||
'/rendering/': '/base/rendering/',
|
||||
'/spec/': '/base/spec/'
|
||||
}
|
||||
});
|
||||
|
||||
if (process.env.TRAVIS) {
|
||||
const testName = process.env.TRAVIS_PULL_REQUEST ?
|
||||
`https://github.com/openlayers/openlayers/pull/${process.env.TRAVIS_PULL_REQUEST}` :
|
||||
`${pkg.name}@${pkg.version} (${process.env.TRAVIS_COMMIT})`;
|
||||
|
||||
// see https://wiki.saucelabs.com/display/DOCS/Platform+Configurator
|
||||
// for platform and browserName options (Selenium API, node.js code)
|
||||
const customLaunchers = {
|
||||
SL_Chrome: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'chrome'
|
||||
},
|
||||
SL_Firefox: {
|
||||
base: 'SauceLabs',
|
||||
browserName: 'firefox'
|
||||
// },
|
||||
// SL_Edge: {
|
||||
// base: 'SauceLabs',
|
||||
// platform: 'Windows 10',
|
||||
// browserName: 'MicrosoftEdge'
|
||||
// },
|
||||
// SL_Safari: {
|
||||
// base: 'SauceLabs',
|
||||
// platform: 'macos 10.12',
|
||||
// browserName: 'safari'
|
||||
}
|
||||
};
|
||||
karma.set({
|
||||
sauceLabs: {
|
||||
testName: testName,
|
||||
recordScreenshots: false,
|
||||
connectOptions: {
|
||||
port: 5757
|
||||
},
|
||||
startConnect: false,
|
||||
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
|
||||
username: 'openlayers',
|
||||
accessKey: process.env.SAUCE_ACCESS_KEY
|
||||
},
|
||||
reporters: ['dots', 'saucelabs'],
|
||||
captureTimeout: 240000,
|
||||
browserNoActivityTimeout: 240000,
|
||||
customLaunchers: customLaunchers,
|
||||
browsers: Object.keys(customLaunchers)
|
||||
});
|
||||
} else {
|
||||
karma.set({
|
||||
browsers: ['Chrome']
|
||||
});
|
||||
}
|
||||
};
|
||||
2
test/no-deps.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// TODO: get rid of this when we get rid of goog base.js
|
||||
var CLOSURE_NO_DEPS = true; // eslint-disable-line
|
||||
@@ -1,17 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
module.exports = {
|
||||
afterEnd: function(runner) {
|
||||
var fs = require('fs');
|
||||
var coverage = runner.page.evaluate(function() {
|
||||
return window.__coverage__;
|
||||
});
|
||||
|
||||
if (coverage) {
|
||||
console.log('Writing coverage to coverage/coverage.json');
|
||||
fs.write('coverage/coverage.json', JSON.stringify(coverage), 'w');
|
||||
} else {
|
||||
console.log('No coverage data generated');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 635 B |
|
Before Width: | Height: | Size: 838 B After Width: | Height: | Size: 838 B |
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 637 B |
|
Before Width: | Height: | Size: 950 B After Width: | Height: | Size: 950 B |
|
Before Width: | Height: | Size: 873 B After Width: | Height: | Size: 873 B |
|
Before Width: | Height: | Size: 966 B After Width: | Height: | Size: 966 B |
|
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 717 B |
|
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 396 B |
|
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 403 B |
|
Before Width: | Height: | Size: 792 B After Width: | Height: | Size: 792 B |
|
Before Width: | Height: | Size: 801 B After Width: | Height: | Size: 801 B |
|
Before Width: | Height: | Size: 615 B After Width: | Height: | Size: 615 B |
|
Before Width: | Height: | Size: 733 B After Width: | Height: | Size: 733 B |
|
Before Width: | Height: | Size: 639 B After Width: | Height: | Size: 639 B |
|
Before Width: | Height: | Size: 799 B After Width: | Height: | Size: 799 B |
@@ -57,7 +57,7 @@ describe('layer clipping', function() {
|
||||
it('clips to all parts of the MultiPolygon', function(done) {
|
||||
|
||||
var source = new ol.source.XYZ({
|
||||
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
|
||||
var layer = new ol.layer.Tile({
|
||||
@@ -100,7 +100,7 @@ describe('layer clipping', function() {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
expectResemble(map, 'spec/ol/layer/expected/multipolygon-clip.png', IMAGE_TOLERANCE, done);
|
||||
expectResemble(map, 'rendering/ol/layer/expected/multipolygon-clip.png', IMAGE_TOLERANCE, done);
|
||||
});
|
||||
|
||||
map.addLayer(layer);
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 806 B After Width: | Height: | Size: 806 B |
|
Before Width: | Height: | Size: 806 B After Width: | Height: | Size: 806 B |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 392 B |
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 504 B After Width: | Height: | Size: 504 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
@@ -11,13 +11,11 @@ goog.require('ol.tilegrid');
|
||||
|
||||
describe('ol.rendering.layer.Image', function() {
|
||||
|
||||
var target, map;
|
||||
var map;
|
||||
|
||||
function createMap(renderer) {
|
||||
target = createMapDiv(50, 50);
|
||||
|
||||
map = new ol.Map({
|
||||
target: target,
|
||||
target: createMapDiv(50, 50),
|
||||
renderer: renderer,
|
||||
view: new ol.View({
|
||||
center: ol.proj.transform(
|
||||
@@ -25,9 +23,15 @@ describe('ol.rendering.layer.Image', function() {
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
if (map) {
|
||||
disposeMap(map);
|
||||
}
|
||||
map = null;
|
||||
});
|
||||
|
||||
function waitForImages(sources, layerOptions, onImagesLoaded) {
|
||||
var imagesLoading = 0;
|
||||
var imagesLoaded = 0;
|
||||
@@ -63,30 +67,26 @@ describe('ol.rendering.layer.Image', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
source = new ol.source.ImageStatic({
|
||||
url: 'spec/ol/data/tiles/osm/5/5/12.png',
|
||||
url: 'rendering/ol/data/tiles/osm/5/5/12.png',
|
||||
imageExtent: ol.tilegrid.createXYZ().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');
|
||||
createMap('canvas');
|
||||
waitForImages([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/image-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/image-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
waitForImages([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/image-webgl.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/image-webgl.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -97,20 +97,16 @@ describe('ol.rendering.layer.Image', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
source = new ol.source.ImageStatic({
|
||||
url: 'spec/ol/data/tiles/osm/5/5/12.png',
|
||||
url: 'rendering/ol/data/tiles/osm/5/5/12.png',
|
||||
imageExtent: ol.proj.transformExtent(
|
||||
[-123, 37, -122, 38], 'EPSG:4326', 'EPSG:3857')
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('renders correctly', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
waitForImages([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/image-scaled.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/image-scaled.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -17,15 +17,14 @@ goog.require('ol.tilegrid');
|
||||
|
||||
describe('ol.rendering.layer.Tile', function() {
|
||||
|
||||
var target, map;
|
||||
var map;
|
||||
|
||||
function createMap(renderer, opt_center, opt_size, opt_pixelRatio, opt_resolutions) {
|
||||
var size = opt_size !== undefined ? opt_size : [50, 50];
|
||||
target = createMapDiv(size[0], size[1]);
|
||||
|
||||
map = new ol.Map({
|
||||
pixelRatio: opt_pixelRatio || 1,
|
||||
target: target,
|
||||
target: createMapDiv(size[0], size[1]),
|
||||
renderer: renderer,
|
||||
view: new ol.View({
|
||||
center: opt_center !== undefined ? opt_center : ol.proj.transform(
|
||||
@@ -34,9 +33,15 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
if (map) {
|
||||
disposeMap(map);
|
||||
}
|
||||
map = null;
|
||||
});
|
||||
|
||||
function waitForTiles(sources, layerOptions, onTileLoaded) {
|
||||
var tilesLoading = 0;
|
||||
var tileLoaded = 0;
|
||||
@@ -72,27 +77,23 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
source = new ol.source.XYZ({
|
||||
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('tests the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
waitForTiles([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/osm-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/osm-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
waitForTiles([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/osm-webgl.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/osm-webgl.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -103,30 +104,26 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
source1 = new ol.source.XYZ({
|
||||
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
source2 = new ol.source.XYZ({
|
||||
url: 'spec/ol/data/tiles/stamen-labels/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/stamen-labels/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('tests the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
waitForTiles([source1, source2], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/2-layers-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
waitForTiles([source1, source2], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/2-layers-webgl.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/2-layers-webgl.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -139,35 +136,35 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
}
|
||||
|
||||
it('tests canvas layer extent clipping', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/2-layers-canvas-extent.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tests canvas layer extent clipping with rotation', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
map.getView().setRotation(Math.PI / 2);
|
||||
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-rotate.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/2-layers-canvas-extent-rotate.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tests canvas layer extent clipping (HiDPI)', function(done) {
|
||||
map = createMap('canvas', undefined, undefined, 2);
|
||||
createMap('canvas', undefined, undefined, 2);
|
||||
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-hidpi.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/2-layers-canvas-extent-hidpi.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tests canvas layer extent clipping with rotation (HiDPI)', function(done) {
|
||||
map = createMap('canvas', undefined, undefined, 2);
|
||||
createMap('canvas', undefined, undefined, 2);
|
||||
map.getView().setRotation(Math.PI / 2);
|
||||
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-rotate-hidpi.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/2-layers-canvas-extent-rotate-hidpi.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -179,27 +176,23 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
source = new ol.source.XYZ({
|
||||
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('tests the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
waitForTiles([source], {opacity: 0.2}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/opacity-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/opacity-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
waitForTiles([source], {opacity: 0.2}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/opacity-webgl.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/opacity-webgl.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -209,53 +202,49 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
|
||||
function createSource(tileSize) {
|
||||
return new ol.source.TileImage({
|
||||
url: 'spec/ol/data/tiles/' + tileSize + '/{z}/{x}/{y}.png',
|
||||
url: 'rendering/ol/data/tiles/' + tileSize + '/{z}/{x}/{y}.png',
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
tileSize: tileSize.split('x')
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('512x256 renders correcly using the canvas renderer', function(done) {
|
||||
var source = createSource('512x256');
|
||||
map = createMap('canvas', [-10997148, 4569099]);
|
||||
createMap('canvas', [-10997148, 4569099]);
|
||||
waitForTiles([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/512x256-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/512x256-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('512x256 renders correcly using the webgl renderer', function(done) {
|
||||
where('WebGL').it('512x256 renders correcly using the webgl renderer', function(done) {
|
||||
assertWebGL();
|
||||
var source = createSource('512x256');
|
||||
map = createMap('webgl', [-10997148, 4569099]);
|
||||
createMap('webgl', [-10997148, 4569099]);
|
||||
waitForTiles([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/512x256-webgl.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/512x256-webgl.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('192x256 renders correcly using the canvas renderer', function(done) {
|
||||
var source = createSource('192x256');
|
||||
map = createMap('canvas', [-11271098, 3747248], [100, 100], undefined,
|
||||
createMap('canvas', [-11271098, 3747248], [100, 100], undefined,
|
||||
source.getTileGrid().getResolutions());
|
||||
waitForTiles([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/192x256-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/192x256-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('192x256 renders correcly using the webgl renderer', function(done) {
|
||||
where('WebGL').it('192x256 renders correcly using the webgl renderer', function(done) {
|
||||
assertWebGL();
|
||||
var source = createSource('192x256');
|
||||
map = createMap('webgl', [-11271098, 3747248], [100, 100], undefined,
|
||||
createMap('webgl', [-11271098, 3747248], [100, 100], undefined,
|
||||
source.getTileGrid().getResolutions());
|
||||
waitForTiles([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/192x256-webgl.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/192x256-webgl.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -266,7 +255,7 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
source = new ol.source.XYZ({
|
||||
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
onAddLayer = function(evt) {
|
||||
evt.element.on('render', function(e) {
|
||||
@@ -282,15 +271,11 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('works with the canvas renderer', function(done) {
|
||||
map = createMap('canvas', undefined, [100, 100]);
|
||||
createMap('canvas', undefined, [100, 100]);
|
||||
map.getLayers().on('add', onAddLayer);
|
||||
waitForTiles([source], {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/render-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/render-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -16,23 +16,27 @@ goog.require('ol.style.Style');
|
||||
|
||||
describe('ol.rendering.layer.Vector', function() {
|
||||
|
||||
var center, target, map;
|
||||
var center = [1825927.7316762917, 6143091.089223046];
|
||||
|
||||
var map;
|
||||
function createMap(renderer) {
|
||||
target = createMapDiv(80, 80);
|
||||
center = [1825927.7316762917, 6143091.089223046];
|
||||
|
||||
map = new ol.Map({
|
||||
target: target,
|
||||
target: createMapDiv(80, 80),
|
||||
renderer: renderer,
|
||||
view: new ol.View({
|
||||
center: center,
|
||||
zoom: 13
|
||||
})
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
if (map) {
|
||||
disposeMap(map);
|
||||
}
|
||||
map = null;
|
||||
});
|
||||
|
||||
var source;
|
||||
|
||||
function addCircle(r) {
|
||||
@@ -67,12 +71,8 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
source = new ol.source.Vector();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('renders opacity correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
var smallLine = new ol.Feature(new ol.geom.LineString([
|
||||
[center[0], center[1] - 1],
|
||||
[center[0], center[1] + 1]
|
||||
@@ -92,13 +92,13 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
source: source
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vector-canvas.png',
|
||||
17, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders transparent layers correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
var smallLine = new ol.Feature(new ol.geom.LineString([
|
||||
[center[0], center[1] - 1],
|
||||
[center[0], center[1] + 1]
|
||||
@@ -131,13 +131,13 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
opacity: 0.5
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas-transparent.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-transparent.png',
|
||||
7, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders rotation correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
map.getView().setRotation(Math.PI + Math.PI / 4);
|
||||
addPolygon(300);
|
||||
addCircle(500);
|
||||
@@ -151,13 +151,13 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
})
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas-rotated.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-rotated.png',
|
||||
1.7, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders fill/stroke batches correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
source = new ol.source.Vector({
|
||||
overlaps: false
|
||||
});
|
||||
@@ -177,13 +177,13 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
})
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas-opaque.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-opaque.png',
|
||||
24.34, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders stroke batches correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
source = new ol.source.Vector({
|
||||
overlaps: false
|
||||
});
|
||||
@@ -201,13 +201,13 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
})
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas-stroke.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-stroke.png',
|
||||
7, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('interrupts fill/stroke batches correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
var color;
|
||||
function createSource(overlaps) {
|
||||
color = '#3399CC';
|
||||
@@ -252,15 +252,15 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
var referenceImage = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
|
||||
// now render the same with `overlaps: false`
|
||||
layer.setSource(createSource(false));
|
||||
// result should be exactly the same as with `overlaps: true`
|
||||
// result should be similar to `overlaps: true`
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, referenceImage, 0, done);
|
||||
expectResemble(map, referenceImage, 2, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('interrupts stroke batches correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
var color;
|
||||
function createSource(overlaps) {
|
||||
color = '#3399CC';
|
||||
@@ -313,9 +313,9 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
|
||||
describe('polygon rendering', function() {
|
||||
|
||||
var map;
|
||||
var map2;
|
||||
beforeEach(function() {
|
||||
map = new ol.Map({
|
||||
map2 = new ol.Map({
|
||||
target: createMapDiv(128, 128),
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
@@ -325,7 +325,8 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
disposeMap(map2);
|
||||
map2 = null;
|
||||
});
|
||||
|
||||
it('renders a feature that spans the world', function(done) {
|
||||
@@ -359,10 +360,10 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
})
|
||||
});
|
||||
|
||||
map.addLayer(layer);
|
||||
map2.addLayer(layer);
|
||||
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/inverted-star.png', 1, done);
|
||||
map2.once('postrender', function() {
|
||||
expectResemble(map2, 'rendering/ol/layer/expected/inverted-star.png', 1, done);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -371,7 +372,7 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
|
||||
describe('Polygon simplification', function() {
|
||||
|
||||
var layer, map;
|
||||
var layer, map3;
|
||||
|
||||
beforeEach(function() {
|
||||
var src = new ol.source.Vector({
|
||||
@@ -402,7 +403,7 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
projection: 'EPSG:4326'
|
||||
});
|
||||
|
||||
map = new ol.Map({
|
||||
map3 = new ol.Map({
|
||||
layers: [layer],
|
||||
target: createMapDiv(100, 100),
|
||||
view: view
|
||||
@@ -410,7 +411,8 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
disposeMap(map3);
|
||||
map3 = null;
|
||||
});
|
||||
|
||||
it('renders partially out-of-view polygons with a fill and stroke', function(done) {
|
||||
@@ -423,8 +425,8 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
color: [255, 0, 0, 1]
|
||||
})
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas-simplified.png',
|
||||
map3.once('postrender', function() {
|
||||
expectResemble(map3, 'rendering/ol/layer/expected/vector-canvas-simplified.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -435,8 +437,8 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
color: [0, 0, 0, 1]
|
||||
})
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas-simplified-fill.png',
|
||||
map3.once('postrender', function() {
|
||||
expectResemble(map3, 'rendering/ol/layer/expected/vector-canvas-simplified-fill.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -448,8 +450,8 @@ describe('ol.rendering.layer.Vector', function() {
|
||||
width: 2
|
||||
})
|
||||
}));
|
||||
map.once('postrender', function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vector-canvas-simplified-stroke.png',
|
||||
map3.once('postrender', function() {
|
||||
expectResemble(map3, 'rendering/ol/layer/expected/vector-canvas-simplified-stroke.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
@@ -11,23 +11,25 @@ goog.require('ol.tilegrid');
|
||||
|
||||
describe('ol.rendering.layer.VectorTile', function() {
|
||||
|
||||
var target, map;
|
||||
var map;
|
||||
|
||||
function createMap(renderer, opt_pixelRatio) {
|
||||
target = createMapDiv(50, 50);
|
||||
|
||||
map = new ol.Map({
|
||||
pixelRatio: opt_pixelRatio,
|
||||
target: target,
|
||||
target: createMapDiv(50, 50),
|
||||
renderer: renderer,
|
||||
view: new ol.View({
|
||||
center: [1825927.7316762917, 6143091.089223046],
|
||||
zoom: 14
|
||||
})
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
map = null;
|
||||
});
|
||||
|
||||
function waitForTiles(source, layerOptions, onTileLoaded) {
|
||||
var tilesLoading = 0;
|
||||
var tileLoaded = 0;
|
||||
@@ -64,44 +66,40 @@ describe('ol.rendering.layer.VectorTile', function() {
|
||||
format: new ol.format.MVT(),
|
||||
tileGrid: ol.tilegrid.createXYZ(),
|
||||
tilePixelRatio: 16,
|
||||
url: 'spec/ol/data/tiles/mvt/{z}-{x}-{y}.vector.pbf'
|
||||
url: 'rendering/ol/data/tiles/mvt/{z}-{x}-{y}.vector.pbf'
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('renders correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
waitForTiles(source, {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vectortile-canvas.png',
|
||||
11.7, done);
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vectortile-canvas.png',
|
||||
22, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders rotated view correctly with the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
map.getView().setRotation(Math.PI / 4);
|
||||
waitForTiles(source, {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vectortile-canvas-rotated.png',
|
||||
13.4, done);
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vectortile-canvas-rotated.png',
|
||||
14, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders correctly with the canvas renderer (HiDPI)', function(done) {
|
||||
map = createMap('canvas', 2);
|
||||
createMap('canvas', 2);
|
||||
waitForTiles(source, {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vectortile-canvas-hidpi.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vectortile-canvas-hidpi.png',
|
||||
11.3, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders rotated view correctly with the canvas renderer (HiDPI)', function(done) {
|
||||
map = createMap('canvas', 2);
|
||||
createMap('canvas', 2);
|
||||
map.getView().setRotation(Math.PI / 4);
|
||||
waitForTiles(source, {}, function() {
|
||||
expectResemble(map, 'spec/ol/layer/expected/vectortile-canvas-rotated-hidpi.png',
|
||||
expectResemble(map, 'rendering/ol/layer/expected/vectortile-canvas-rotated-hidpi.png',
|
||||
14.8, done);
|
||||
});
|
||||
});
|
||||
@@ -10,11 +10,8 @@ goog.require('ol.source.Vector');
|
||||
|
||||
describe('ol.rendering.Map', function() {
|
||||
|
||||
var target, map;
|
||||
|
||||
var map;
|
||||
function createMap(renderer) {
|
||||
target = createMapDiv(50, 50);
|
||||
|
||||
var vectorLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [new ol.Feature({
|
||||
@@ -24,7 +21,7 @@ describe('ol.rendering.Map', function() {
|
||||
});
|
||||
|
||||
map = new ol.Map({
|
||||
target: target,
|
||||
target: createMapDiv(50, 50),
|
||||
renderer: renderer,
|
||||
layers: [vectorLayer],
|
||||
view: new ol.View({
|
||||
@@ -33,34 +30,19 @@ describe('ol.rendering.Map', function() {
|
||||
resolution: 1
|
||||
})
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
describe('#updateSize()', function() {
|
||||
var map, target;
|
||||
|
||||
function createMap(renderer) {
|
||||
target = document.createElement('div');
|
||||
document.body.appendChild(target);
|
||||
map = new ol.Map({
|
||||
renderer: renderer,
|
||||
controls: [],
|
||||
target: target,
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
return map;
|
||||
afterEach(function() {
|
||||
if (map) {
|
||||
disposeMap(map);
|
||||
}
|
||||
map = null;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
map.setTarget(null);
|
||||
document.body.removeChild(target);
|
||||
});
|
||||
describe('#updateSize()', function() {
|
||||
|
||||
it('tests the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
map.once('postrender', function() {
|
||||
var initialSize = map.getSize();
|
||||
map.updateSize();
|
||||
@@ -69,9 +51,9 @@ describe('ol.rendering.Map', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
map.once('postrender', function() {
|
||||
var initialSize = map.getSize();
|
||||
map.updateSize();
|
||||
@@ -82,88 +64,76 @@ describe('ol.rendering.Map', function() {
|
||||
});
|
||||
|
||||
describe('#render()', function() {
|
||||
afterEach(function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
it('tests the canvas renderer', function(done) {
|
||||
map = createMap('canvas');
|
||||
createMap('canvas');
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/render-canvas.png', IMAGE_TOLERANCE, done);
|
||||
map, 'rendering/ol/expected/render-canvas.png', IMAGE_TOLERANCE, done);
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/render-webgl.png', IMAGE_TOLERANCE, done);
|
||||
map, 'rendering/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');
|
||||
createMap('canvas');
|
||||
map.getView().setCenter([10, 10]);
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/pan-canvas.png', IMAGE_TOLERANCE, done);
|
||||
map, 'rendering/ol/expected/pan-canvas.png', IMAGE_TOLERANCE, done);
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
map.getView().setCenter([10, 10]);
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/pan-webgl.png', IMAGE_TOLERANCE, done);
|
||||
map, 'rendering/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');
|
||||
createMap('canvas');
|
||||
map.getView().setRotation(90);
|
||||
map.getView().setCenter([10, 10]);
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/rotate-canvas.png', 2.8, done);
|
||||
map, 'rendering/ol/expected/rotate-canvas.png', 2.8, done);
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
map.getView().setRotation(90);
|
||||
map.getView().setCenter([10, 10]);
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/rotate-webgl.png', IMAGE_TOLERANCE, done);
|
||||
map, 'rendering/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');
|
||||
createMap('canvas');
|
||||
map.getView().setCenter([10, 10]);
|
||||
map.getView().setResolution(2);
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/zoom-canvas.png', IMAGE_TOLERANCE, done);
|
||||
map, 'rendering/ol/expected/zoom-canvas.png', IMAGE_TOLERANCE, done);
|
||||
});
|
||||
|
||||
it('tests the WebGL renderer', function(done) {
|
||||
where('WebGL').it('tests the WebGL renderer', function(done) {
|
||||
assertWebGL();
|
||||
map = createMap('webgl');
|
||||
createMap('webgl');
|
||||
map.getView().setCenter([10, 10]);
|
||||
map.getView().setResolution(2);
|
||||
expectResemble(
|
||||
map, 'spec/ol/expected/zoom-webgl.png', IMAGE_TOLERANCE, done);
|
||||
map, 'rendering/ol/expected/zoom-webgl.png', IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -11,24 +11,22 @@ goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
function getContext() {
|
||||
return document.createElement('canvas').getContext('2d');
|
||||
}
|
||||
|
||||
describe('ol.render', function() {
|
||||
|
||||
var context;
|
||||
|
||||
beforeEach(function() {
|
||||
context = document.createElement('canvas').getContext('2d');
|
||||
});
|
||||
|
||||
describe('ol.render.toContext()', function() {
|
||||
|
||||
it('creates a vector context from a Canvas 2d context', function() {
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
var vectorContext = ol.render.toContext(getContext(), {size: [100, 100]});
|
||||
expect(vectorContext).to.be.a(ol.render.VectorContext);
|
||||
expect(vectorContext).to.be.a(ol.render.canvas.Immediate);
|
||||
});
|
||||
|
||||
it('can be used to render a point geometry', function(done) {
|
||||
var context = getContext();
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
|
||||
var style = new ol.style.Style({
|
||||
@@ -44,11 +42,12 @@ describe('ol.render', function() {
|
||||
vectorContext.drawGeometry(new ol.geom.Point([50, 50]));
|
||||
|
||||
resembleCanvas(context.canvas,
|
||||
'spec/ol/expected/render-point.png', IMAGE_TOLERANCE, done);
|
||||
'rendering/ol/expected/render-point.png', IMAGE_TOLERANCE, done);
|
||||
|
||||
});
|
||||
|
||||
it('can be used to render a linestring geometry', function(done) {
|
||||
var context = getContext();
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
|
||||
var style = new ol.style.Style({
|
||||
@@ -64,11 +63,12 @@ describe('ol.render', function() {
|
||||
]));
|
||||
|
||||
resembleCanvas(context.canvas,
|
||||
'spec/ol/expected/render-linestring.png', IMAGE_TOLERANCE, done);
|
||||
'rendering/ol/expected/render-linestring.png', IMAGE_TOLERANCE, done);
|
||||
|
||||
});
|
||||
|
||||
it('respects lineCap for linestring', function(done) {
|
||||
var context = getContext();
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
|
||||
var style = new ol.style.Style({
|
||||
@@ -85,11 +85,12 @@ describe('ol.render', function() {
|
||||
]));
|
||||
|
||||
resembleCanvas(context.canvas,
|
||||
'spec/ol/expected/render-linestring-butt.png', IMAGE_TOLERANCE, done);
|
||||
'rendering/ol/expected/render-linestring-butt.png', IMAGE_TOLERANCE, done);
|
||||
|
||||
});
|
||||
|
||||
it('respects lineJoin for linestring', function(done) {
|
||||
var context = getContext();
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
|
||||
var style = new ol.style.Style({
|
||||
@@ -106,11 +107,12 @@ describe('ol.render', function() {
|
||||
]));
|
||||
|
||||
resembleCanvas(context.canvas,
|
||||
'spec/ol/expected/render-linestring-bevel.png', IMAGE_TOLERANCE, done);
|
||||
'rendering/ol/expected/render-linestring-bevel.png', IMAGE_TOLERANCE, done);
|
||||
|
||||
});
|
||||
|
||||
it('can be used to render a polygon geometry', function(done) {
|
||||
var context = getContext();
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
|
||||
var style = new ol.style.Style({
|
||||
@@ -131,11 +133,12 @@ describe('ol.render', function() {
|
||||
]));
|
||||
|
||||
resembleCanvas(context.canvas,
|
||||
'spec/ol/expected/render-polygon.png', IMAGE_TOLERANCE, done);
|
||||
'rendering/ol/expected/render-polygon.png', IMAGE_TOLERANCE, done);
|
||||
|
||||
});
|
||||
|
||||
it('supports lineDash styles', function(done) {
|
||||
var context = getContext();
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
|
||||
var style = new ol.style.Style({
|
||||
@@ -152,11 +155,12 @@ describe('ol.render', function() {
|
||||
]));
|
||||
|
||||
resembleCanvas(context.canvas,
|
||||
'spec/ol/expected/render-polygon-linedash.png', IMAGE_TOLERANCE, done);
|
||||
'rendering/ol/expected/render-polygon-linedash.png', IMAGE_TOLERANCE, done);
|
||||
|
||||
});
|
||||
|
||||
it('supports lineDashOffset', function(done) {
|
||||
var context = getContext();
|
||||
var vectorContext = ol.render.toContext(context, {size: [100, 100]});
|
||||
|
||||
var style = new ol.style.Style({
|
||||
@@ -174,7 +178,7 @@ describe('ol.render', function() {
|
||||
]));
|
||||
|
||||
resembleCanvas(context.canvas,
|
||||
'spec/ol/expected/render-polygon-linedashoffset.png', IMAGE_TOLERANCE, done);
|
||||
'rendering/ol/expected/render-polygon-linedashoffset.png', IMAGE_TOLERANCE, done);
|
||||
|
||||
});
|
||||
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
@@ -38,7 +38,7 @@ describe('ol.rendering.reproj.Image', function() {
|
||||
describe('image reprojections from EPSG:3857', function() {
|
||||
beforeEach(function() {
|
||||
source = new ol.source.ImageStatic({
|
||||
url: 'spec/ol/data/tiles/osm/5/5/12.png',
|
||||
url: 'rendering/ol/data/tiles/osm/5/5/12.png',
|
||||
imageExtent: ol.tilegrid.createXYZ().getTileCoordExtent([5, 5, -13]),
|
||||
projection: ol.proj.get('EPSG:3857')
|
||||
});
|
||||
@@ -48,7 +48,7 @@ describe('ol.rendering.reproj.Image', function() {
|
||||
testSingleImage(source, 'EPSG:3857',
|
||||
ol.tilegrid.createXYZ().getTileCoordExtent([5, 5, -13]),
|
||||
2 * ol.proj.EPSG3857.HALF_SIZE / (256 * (1 << 5)), 1,
|
||||
'spec/ol/data/tiles/osm/5/5/12.png', done);
|
||||
'rendering/ol/data/tiles/osm/5/5/12.png', done);
|
||||
});
|
||||
|
||||
it('to EPSG:4326', function(done) {
|
||||
@@ -56,7 +56,7 @@ describe('ol.rendering.reproj.Image', function() {
|
||||
ol.tilegrid.createForProjection('EPSG:4326').
|
||||
getTileCoordExtent([6, 10, -10]),
|
||||
360 / (256 * (1 << 4)), 1,
|
||||
'spec/ol/reproj/expected/image-3857-to-4326.png', done);
|
||||
'rendering/ol/reproj/expected/image-3857-to-4326.png', done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -41,19 +41,19 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
beforeEach(function() {
|
||||
source = new ol.source.XYZ({
|
||||
projection: 'EPSG:3857',
|
||||
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
it('works for identity reprojection', function(done) {
|
||||
testSingleTile(source, 'EPSG:3857', source.getTileGrid(), 5, 5, -13, 1,
|
||||
'spec/ol/data/tiles/osm/5/5/12.png', 1, done);
|
||||
'rendering/ol/data/tiles/osm/5/5/12.png', 1, done);
|
||||
});
|
||||
|
||||
it('to EPSG:4326', function(done) {
|
||||
var tileGrid = ol.tilegrid.createForProjection('EPSG:4326', 7, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:4326', tileGrid, 7, 21, -20, 1,
|
||||
'spec/ol/reproj/expected/osm4326.png', 1, done);
|
||||
'rendering/ol/reproj/expected/osm4326.png', 1, done);
|
||||
});
|
||||
|
||||
it('to EPSG:5070', function(done) {
|
||||
@@ -65,7 +65,7 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
|
||||
var tileGrid = ol.tilegrid.createForProjection('EPSG:5070', 5, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:5070', tileGrid, 5, 13, -15, 1,
|
||||
'spec/ol/reproj/expected/osm5070.png', 1, done);
|
||||
'rendering/ol/reproj/expected/osm5070.png', 1, done);
|
||||
});
|
||||
|
||||
it('to ESRI:54009', function(done) {
|
||||
@@ -76,7 +76,7 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
|
||||
var tileGrid = ol.tilegrid.createForProjection('ESRI:54009', 7, [64, 64]);
|
||||
testSingleTile(source, 'ESRI:54009', tileGrid, 7, 27, -16, 1,
|
||||
'spec/ol/reproj/expected/osm54009.png', 1, done);
|
||||
'rendering/ol/reproj/expected/osm54009.png', 1, done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -84,14 +84,14 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
beforeEach(function() {
|
||||
source = new ol.source.XYZ({
|
||||
projection: 'EPSG:3857',
|
||||
url: 'spec/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
it('to EPSG:4326', function(done) {
|
||||
var tileGrid = ol.tilegrid.createForProjection('EPSG:4326', 7, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:4326', tileGrid, 7, 23, -21, 1,
|
||||
'spec/ol/reproj/expected/stitch-osm4326.png', 2, done);
|
||||
'rendering/ol/reproj/expected/stitch-osm4326.png', 2, done);
|
||||
});
|
||||
|
||||
it('to EPSG:3740', function(done) {
|
||||
@@ -103,7 +103,7 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
|
||||
var tileGrid = ol.tilegrid.createForProjection('EPSG:3740', 4, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:3740', tileGrid, 4, 4, -13, 1,
|
||||
'spec/ol/reproj/expected/stitch-osm3740.png', 4, done);
|
||||
'rendering/ol/reproj/expected/stitch-osm3740.png', 4, done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -112,19 +112,19 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
source = new ol.source.XYZ({
|
||||
projection: 'EPSG:4326',
|
||||
maxZoom: 0,
|
||||
url: 'spec/ol/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
it('works for identity reprojection', function(done) {
|
||||
testSingleTile(source, 'EPSG:4326', source.getTileGrid(), 0, 0, -1, 1,
|
||||
'spec/ol/data/tiles/4326/0/0/0.png', 1, done);
|
||||
'rendering/ol/data/tiles/4326/0/0/0.png', 1, done);
|
||||
});
|
||||
|
||||
it('to EPSG:3857', function(done) {
|
||||
var tileGrid = ol.tilegrid.createForProjection('EPSG:3857', 0, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:3857', tileGrid, 0, 0, -1, 1,
|
||||
'spec/ol/reproj/expected/4326-to-3857.png', 1, done);
|
||||
'rendering/ol/reproj/expected/4326-to-3857.png', 1, done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -132,20 +132,20 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
beforeEach(function() {
|
||||
source = new ol.source.XYZ({
|
||||
projection: 'EPSG:3857',
|
||||
url: 'spec/ol/data/tiles/osm-512x256/{z}/{x}/{y}.png',
|
||||
url: 'rendering/ol/data/tiles/osm-512x256/{z}/{x}/{y}.png',
|
||||
tileSize: [512, 256]
|
||||
});
|
||||
});
|
||||
|
||||
it('works for identity reprojection', function(done) {
|
||||
testSingleTile(source, 'EPSG:3857', source.getTileGrid(), 5, 3, -13, 1,
|
||||
'spec/ol/data/tiles/osm-512x256/5/3/12.png', 1, done);
|
||||
'rendering/ol/data/tiles/osm-512x256/5/3/12.png', 1, done);
|
||||
});
|
||||
|
||||
it('to 64x128 EPSG:4326', function(done) {
|
||||
var tileGrid = ol.tilegrid.createForProjection('EPSG:4326', 7, [64, 128]);
|
||||
testSingleTile(source, 'EPSG:4326', tileGrid, 7, 27, -10, 1,
|
||||
'spec/ol/reproj/expected/512x256-to-64x128.png', 1, done);
|
||||
'rendering/ol/reproj/expected/512x256-to-64x128.png', 1, done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -154,7 +154,7 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
source = new ol.source.XYZ({
|
||||
projection: 'EPSG:4326',
|
||||
maxZoom: 0,
|
||||
url: 'spec/ol/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
url: 'rendering/ol/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
@@ -165,7 +165,7 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
|
||||
var tileGrid = ol.tilegrid.createForProjection('merc_180', 0, [64, 64]);
|
||||
testSingleTile(source, 'merc_180', tileGrid, 0, 0, -1, 1,
|
||||
'spec/ol/reproj/expected/dateline-merc-180.png', 2, done);
|
||||
'rendering/ol/reproj/expected/dateline-merc-180.png', 2, done);
|
||||
});
|
||||
|
||||
it('displays north pole correctly (EPSG:3413)', function(done) {
|
||||
@@ -176,7 +176,7 @@ describe('ol.rendering.reproj.Tile', function() {
|
||||
|
||||
var tileGrid = ol.tilegrid.createForProjection('EPSG:3413', 0, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:3413', tileGrid, 0, 0, -1, 1,
|
||||
'spec/ol/reproj/expected/dateline-pole.png', 2, done);
|
||||
'rendering/ol/reproj/expected/dateline-pole.png', 2, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |