-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #866 from OpenGeoscience/example-tests
Add more support for testing examples.
- Loading branch information
Showing
8 changed files
with
251 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,61 @@ | ||
// Run after the DOM loads | ||
$(function () { | ||
'use strict'; | ||
|
||
// Create a map object with the OpenStreetMaps base layer. | ||
var map = geo.map({ | ||
node: '#map', | ||
center: { | ||
x: -157.965, | ||
y: 21.482 | ||
}, | ||
zoom: 11 | ||
}); | ||
// Create a map object with the OpenStreetMaps base layer. | ||
var map = geo.map({ | ||
node: '#map', | ||
center: { | ||
x: -157.965, | ||
y: 21.482 | ||
}, | ||
zoom: 11 | ||
}); | ||
|
||
// Add a faint osm layer | ||
map.createLayer('osm', {opacity: 0.5}); | ||
// Add a faint osm layer | ||
map.createLayer('osm', {opacity: 0.5}); | ||
|
||
// Create a feature layer that supports contours | ||
var isolineLayer = map.createLayer('feature', { | ||
features: ['isoline'] | ||
}); | ||
// Create a feature layer that supports contours | ||
var isolineLayer = map.createLayer('feature', { | ||
features: ['isoline'] | ||
}); | ||
|
||
// Load the data | ||
$.get('../../data/oahu-dense.json').done(function (data) { | ||
// Create an isoline feature | ||
var iso = isolineLayer.createFeature('isoline', { | ||
isoline: { | ||
// Specify our grid data | ||
gridWidth: data.gridWidth, | ||
gridHeight: data.gridHeight, | ||
x0: data.x0, | ||
y0: data.y0, | ||
dx: data.dx, | ||
dy: data.dy, | ||
// Don't plot any values less than zero | ||
min: 0, | ||
// Create a contour line every 50 meters | ||
spacing: 50, | ||
// Make every 4th line heavier and every 4*5 = 20th line heavier yet | ||
levels: [4, 5] | ||
}, | ||
style: { | ||
// The data uses -9999 to represent no value; modify it to return null | ||
// instead. | ||
value: function (d) { return d > -9999 ? d : null; }, | ||
// level relates to the isoline importance, with 0 being the most | ||
// common and, using the levels specified, a level of 1 being every | ||
// fourth, and 2 every twentieth line. Color the lines differently | ||
// depending on the level | ||
strokeColor: function (v, vi, d) { | ||
return ['grey', 'mediumblue', 'blue'][d.level]; | ||
} | ||
// Load the data | ||
$.get('../../data/oahu-dense.json').done(function (data) { | ||
// Create an isoline feature | ||
var iso = isolineLayer.createFeature('isoline', { | ||
isoline: { | ||
// Specify our grid data | ||
gridWidth: data.gridWidth, | ||
gridHeight: data.gridHeight, | ||
x0: data.x0, | ||
y0: data.y0, | ||
dx: data.dx, | ||
dy: data.dy, | ||
// Don't plot any values less than zero | ||
min: 0, | ||
// Create a contour line every 50 meters | ||
spacing: 50, | ||
// Make every 4th line heavier and every 4*5 = 20th line heavier yet | ||
levels: [4, 5] | ||
}, | ||
style: { | ||
// The data uses -9999 to represent no value; modify it to return null | ||
// instead. | ||
value: function (d) { return d > -9999 ? d : null; }, | ||
// level relates to the isoline importance, with 0 being the most | ||
// common and, using the levels specified, a level of 1 being every | ||
// fourth, and 2 every twentieth line. Color the lines differently | ||
// depending on the level | ||
strokeColor: function (v, vi, d) { | ||
return ['grey', 'mediumblue', 'blue'][d.level]; | ||
} | ||
}).data(data.values).draw(); | ||
// Make some values available in the global context so curious people can | ||
// play with them. | ||
window.example = { | ||
map: map, | ||
isolineLayer: isolineLayer, | ||
iso: iso | ||
}; | ||
}); | ||
} | ||
}).data(data.values).draw(); | ||
|
||
// Make some values available in the global context to aid exploration and | ||
// automated tests. | ||
window.example = { | ||
ready: true, | ||
map: map, | ||
isolineLayer: isolineLayer, | ||
iso: iso | ||
}; | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* In each examples/<path>/example.json, if there is a top-level key called | ||
* "tests", this will run a test on that example. This key is an array of | ||
* tests, each of which is an object with the following optional values: | ||
* Partial example: | ||
* "tests": [{ | ||
* "description": "test name", // a description of the test | ||
* "htmlvideo": false, // if true, the test browser must support | ||
* // video, or the test is skipped. | ||
* "idle": [ // a list of idle functions or deferreds | ||
* "map.onIdle" // an example idle function that will be | ||
* ], // passed a function to call when idle | ||
* "wait": [ // a list of expressions that will block | ||
* // until they don't throw errors and | ||
* // evaluate to truthy | ||
* "map.layers().length >= 1" // an example wait expression | ||
* ], | ||
* "tests": [ // a list of expressions that must evaluate | ||
* // to truthy for the tests to pass. | ||
* "map.layers()[0] instanceof geo.tileLayer" // an example of a test | ||
* ] | ||
* }] | ||
*/ | ||
|
||
/* Find all examples. */ | ||
var examples = require.context('../../examples', true, /\/example.json$/); | ||
|
||
describe('examples', function () { | ||
'use strict'; | ||
|
||
var $ = require('jquery'); | ||
|
||
var imageTest = require('../image-test'); | ||
|
||
beforeEach(function () { | ||
imageTest.prepareIframeTest(); | ||
}); | ||
|
||
/* Test each example */ | ||
examples.keys().forEach(function (examplePath) { | ||
var example; | ||
try { | ||
example = $.ajax({url: '/examples/' + examplePath, dataType: 'json', async: false}).responseJSON; | ||
} catch (err) { | ||
return; | ||
} | ||
if (!example || !example.tests) { | ||
return; | ||
} | ||
var exampleName = examplePath.split('/')[1]; | ||
example.tests.forEach(function (test, idx) { | ||
describe('Test ' + exampleName, function () { | ||
/* Load the example in the test iframe */ | ||
beforeEach(function (done) { | ||
sinon.stub(console, 'warn', function () {}); | ||
$('#map').one('load', function () { | ||
/* allow logging to percolate through to our test environment */ | ||
$('iframe#map')[0].contentWindow.console = console; | ||
window.setTimeout(done, 1); | ||
}); | ||
$('#map').attr('src', '/examples/' + exampleName + '/index.html' + (test.query ? '?' + test.query : '')); | ||
}, 150000); | ||
afterEach(function () { | ||
console.warn.restore(); | ||
}); | ||
it(test.description || ('Test ' + idx), function (done) { | ||
/* Never complain if there are no explicit expect statements */ | ||
expect().nothing(); | ||
/* If a test requires html video and the current browser doesn't | ||
* support video, skip the test. */ | ||
if (test.htmlvideo && !$('iframe#map')[0].contentWindow.HTMLVideoElement) { | ||
done(); | ||
return; | ||
} | ||
var exampleWindow = $('iframe#map')[0].contentWindow, | ||
ex$ = exampleWindow.$, | ||
deferreds = []; | ||
/* Description of the current example and test. */ | ||
var desc = $('iframe#map')[0].contentWindow.document.title + (test.description ? ' - ' + test.description : ''); | ||
/* Evaluate and wait for each idle function and promises. */ | ||
(test.idle || []).forEach(function (idleFunc) { | ||
var defer = ex$.Deferred(); | ||
deferreds.push(defer); | ||
var idle = exampleWindow.eval(idleFunc); | ||
if (!ex$.isFunction(idle)) { | ||
idle = idle.then || idle.done; | ||
} | ||
idle(function () { | ||
defer.resolve(); | ||
}); | ||
}); | ||
(test.wait || []).forEach(function (waitCondition) { | ||
var defer = ex$.Deferred(); | ||
deferreds.push(defer); | ||
var interval; | ||
interval = exampleWindow.setInterval(function () { | ||
var result; | ||
try { | ||
result = exampleWindow.eval(waitCondition); | ||
} catch (err) { } | ||
if (result) { | ||
exampleWindow.clearInterval(interval); | ||
defer.resolve(); | ||
} | ||
}, 10); | ||
}); | ||
/* When all idle functions and wait conditions have resolved, | ||
* evaluate each test in the tests list. */ | ||
ex$.when.apply(ex$, deferreds).then(function () { | ||
var subtestDeferreds = []; | ||
(test.tests || []).forEach(function (testExp) { | ||
/* The test expression can return a value or a promise. We | ||
* use jQuery's when to generically get the results in a | ||
* resolution function. A rejection is a failure. */ | ||
try { | ||
var testResult = exampleWindow.eval(testExp); | ||
} catch (err) { | ||
fail(desc + ' -> raised an error: ' + err); | ||
return; | ||
} | ||
var subtestDefer = ex$.when(testResult).then(function (result) { | ||
/* If the result isn't truthy, make sure our expect has a | ||
* description telling which test block and specific test | ||
* failed. */ | ||
expect(result).toBeTruthy(desc + ' -> ' + testExp); | ||
}, function () { | ||
fail(desc + ' promise failed -> ' + testExp); | ||
}); | ||
subtestDeferreds.push(subtestDefer); | ||
}); | ||
ex$.when.apply(ex$, subtestDeferreds).then(done); | ||
}, function () { | ||
fail(desc + ' -> idle functions were rejected'); | ||
}); | ||
}, 150000); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters