mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-12-02 01:56:08 +03:00
269 lines
9.8 KiB
JavaScript
269 lines
9.8 KiB
JavaScript
/* global $, QUnit, Util */
|
|
|
|
(function () {
|
|
|
|
// ----------
|
|
window.Util = {
|
|
// ----------
|
|
simulateViewerClickWithDrag: function ( args ) {
|
|
// args = { viewer, widthFactor, heightFactor, dragCount, dragDx, dragDy }
|
|
|
|
if ( args.hasOwnProperty( 'dragCount' ) ) {
|
|
args.dragDx = args.dragDx || 1;
|
|
args.dragDy = args.dragDy || 1;
|
|
}
|
|
else {
|
|
args.dragCount = 0;
|
|
}
|
|
|
|
if ( args.widthFactor === undefined ) {
|
|
args.widthFactor = 0.5;
|
|
}
|
|
|
|
//TODO Redefine to be the middle by default
|
|
if ( args.heightFactor === undefined ) {
|
|
args.heightFactor = 0.5;
|
|
}
|
|
|
|
args.widthFactor = Math.min( 1, Math.max( 0, args.widthFactor ) );
|
|
//TODO Fix this. The max height should be 1/AR
|
|
args.heightFactor = Math.min( 1, Math.max( 0, args.heightFactor ) );
|
|
|
|
var $canvas = $( args.viewer.element ).find( '.openseadragon-canvas' ).not( '.navigator .openseadragon-canvas' );
|
|
var offset = $canvas.offset();
|
|
var event = {
|
|
clientX: offset.left + Math.floor( $canvas.width() * args.widthFactor ),
|
|
clientY: offset.top + Math.floor( $canvas.height() * args.heightFactor )
|
|
};
|
|
|
|
$canvas
|
|
.simulate( 'mouseenter', event )
|
|
.simulate( 'mousedown', event );
|
|
for ( var i = 0; i < args.dragCount; i++ ) {
|
|
event.clientX += args.dragDx;
|
|
event.clientY += args.dragDy;
|
|
$canvas
|
|
.simulate( "mousemove", event );
|
|
}
|
|
$canvas
|
|
.simulate( 'mouseup', event )
|
|
.simulate( 'mouseleave', event );
|
|
},
|
|
|
|
// ----------
|
|
initializeTestDOM: function () {
|
|
$( "#qunit-fixture" )
|
|
.append( '<div><div id="example"></div><div id="exampleNavigator"></div></div>' )
|
|
.append( '<div id="wideexample"></div>' )
|
|
.append( '<div id="tallexample"></div>' );
|
|
},
|
|
|
|
// ----------
|
|
equalsWithVariance: function ( value1, value2, variance ) {
|
|
return Math.abs( value1 - value2 ) <= variance;
|
|
},
|
|
|
|
// ----------
|
|
assessNumericValue: function ( assert, value1, value2, variance, message ) {
|
|
assert.ok( Util.equalsWithVariance( value1, value2, variance ), message + " Expected:" + value1 + " Found: " + value2 + " Variance: " + variance );
|
|
},
|
|
|
|
// ----------
|
|
assertPointsEquals: function (assert, pointA, pointB, precision, message) {
|
|
Util.assessNumericValue(assert, pointA.x, pointB.x, precision, message + " x: ");
|
|
Util.assessNumericValue(assert, pointA.y, pointB.y, precision, message + " y: ");
|
|
},
|
|
|
|
// ----------
|
|
assertRectangleEquals: function (assert, rectA, rectB, precision, message) {
|
|
Util.assessNumericValue(assert, rectA.x, rectB.x, precision, message + " x: ");
|
|
Util.assessNumericValue(assert, rectA.y, rectB.y, precision, message + " y: ");
|
|
Util.assessNumericValue(assert, rectA.width, rectB.width, precision,
|
|
message + " width: ");
|
|
Util.assessNumericValue(assert, rectA.height, rectB.height, precision,
|
|
message + " height: ");
|
|
Util.assessNumericValue(assert, rectA.degrees, rectB.degrees, precision,
|
|
message + " degrees: ");
|
|
},
|
|
|
|
// ----------
|
|
timeWatcher: function ( assert, time ) {
|
|
var done = assert.async();
|
|
time = time || 2000;
|
|
var finished = false;
|
|
|
|
setTimeout( function () {
|
|
if ( !finished ) {
|
|
finished = true;
|
|
assert.ok( false, 'finishes in ' + time + 'ms' );
|
|
done();
|
|
}
|
|
}, time );
|
|
|
|
return {
|
|
done: function () {
|
|
if ( !finished ) {
|
|
finished = true;
|
|
done();
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
// ----------
|
|
spyOnce: function(obj, functionName, callback) {
|
|
var original = obj[functionName];
|
|
obj[functionName] = function() {
|
|
obj[functionName] = original;
|
|
var result = callback.apply(this, arguments);
|
|
if (result === undefined) {
|
|
result = original.apply(this, arguments);
|
|
}
|
|
return result;
|
|
};
|
|
},
|
|
|
|
// ----------
|
|
testDeprecation: function(assert, obj0, member0, obj1, member1) {
|
|
var called = false;
|
|
var errored = false;
|
|
|
|
if (obj1 && member1) {
|
|
this.spyOnce(obj1, member1, function() {
|
|
called = true;
|
|
return false;
|
|
});
|
|
} else {
|
|
called = true;
|
|
}
|
|
|
|
this.spyOnce(OpenSeadragon.console, 'error', function(message) {
|
|
if (/deprecated/.test(message)) {
|
|
errored = true;
|
|
}
|
|
});
|
|
|
|
obj0[member0]();
|
|
assert.equal(called, true, 'called through for ' + member0);
|
|
assert.equal(errored, true, 'errored for ' + member0);
|
|
},
|
|
};
|
|
|
|
// Log the name of the currently running test when it starts. Uses console.log rather than
|
|
// $.console.log so that the message is printed even after the $.console is diverted (see below).
|
|
QUnit.testStart((details) => {
|
|
console.log(`Starting test ${details.module}.${details.name}`);
|
|
});
|
|
|
|
/*
|
|
Test console log capture
|
|
|
|
1. Only the OpenSeadragon.console logger is touched
|
|
2. All log messages are stored in window.testLog in arrays keyed on the logger name (e.g. log,
|
|
warning, error, etc.) as JSON-serialized strings to simplify comparisons
|
|
3. The captured log arrays have a custom contains() method for ease of testing
|
|
4. testLog.reset() will clear all of the message arrays, intended for use in test setup routines
|
|
*/
|
|
var testConsole = window.testConsole = {},
|
|
testLog = window.testLog = {
|
|
log: [],
|
|
debug: [],
|
|
info: [],
|
|
warn: [],
|
|
error: [],
|
|
reset: function () {
|
|
for ( var i in testLog ) {
|
|
if ( testLog.hasOwnProperty( i ) && 'length' in testLog[i] && 'push' in testLog[i] ) {
|
|
testLog[i].length = 0;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// OSD has circular references, if a console log tries to serialize
|
|
// certain object, remove these references from a clone (do not delete prop
|
|
// on the original object).
|
|
// NOTE: this does not work if someone replaces the original class with
|
|
// a mock object! Try to mock functions only, or ensure mock objects
|
|
// do not hold circular references.
|
|
const circularOSDReferences = {
|
|
'Tile': 'tiledImage',
|
|
'CacheRecord': ['_tRef', '_tiles'],
|
|
'World': 'viewer',
|
|
'DrawerBase': ['viewer', 'viewport'],
|
|
'CanvasDrawer': ['viewer', 'viewport'],
|
|
'WebGLDrawer': ['viewer', 'viewport'],
|
|
'TiledImage': ['viewer', '_drawer'],
|
|
};
|
|
for ( var i in testLog ) {
|
|
if ( testLog.hasOwnProperty( i ) && testLog[i].push ) {
|
|
// Circular reference removal
|
|
const osdCircularStructureReplacer = function (key, value) {
|
|
for (let ClassType in circularOSDReferences) {
|
|
if (value instanceof OpenSeadragon[ClassType]) {
|
|
const instance = {};
|
|
Object.assign(instance, value);
|
|
|
|
let circProps = circularOSDReferences[ClassType];
|
|
if (!Array.isArray(circProps)) circProps = [circProps];
|
|
for (let prop of circProps) {
|
|
instance[prop] = '__circular_reference__';
|
|
}
|
|
return instance;
|
|
}
|
|
}
|
|
return value;
|
|
};
|
|
|
|
testConsole[i] = ( function ( arr ) {
|
|
return function () {
|
|
var args = Array.prototype.slice.call( arguments, 0 ); // Coerce to true Array
|
|
arr.push( JSON.stringify( args, osdCircularStructureReplacer ) ); // Store as JSON to avoid tedious array-equality tests
|
|
};
|
|
} )( testLog[i] );
|
|
|
|
testLog[i].contains = function ( needle ) {
|
|
for ( var i = 0; i < this.length; i++ ) {
|
|
if ( this[i] == needle ) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
}
|
|
}
|
|
|
|
testConsole.assert = function(condition, message) {
|
|
if (condition) {
|
|
testConsole.error(message);
|
|
}
|
|
};
|
|
|
|
OpenSeadragon.console = testConsole;
|
|
|
|
OpenSeadragon.getBuiltInDrawersForTest = function() {
|
|
const drawers = [];
|
|
for (let property in OpenSeadragon) {
|
|
const drawer = OpenSeadragon[ property ],
|
|
proto = drawer.prototype;
|
|
if( proto &&
|
|
proto instanceof OpenSeadragon.DrawerBase &&
|
|
$.isFunction( proto.getType )){
|
|
drawers.push(proto.getType.call( drawer ));
|
|
}
|
|
}
|
|
return drawers;
|
|
};
|
|
|
|
OpenSeadragon.Viewer.prototype.waitForFinishedJobsForTest = function () {
|
|
let finish;
|
|
let int = setInterval(() => {
|
|
if (this.imageLoader.jobsInProgress < 1) {
|
|
finish();
|
|
}
|
|
}, 50);
|
|
return new OpenSeadragon.Promise((resolve) => finish = resolve);
|
|
};
|
|
} )();
|
|
|