Fix circular references in JSON test log serialization.

This commit is contained in:
Aiosa 2024-03-04 10:49:05 +01:00
parent 52ef8156c0
commit 47419a090a
3 changed files with 39 additions and 26 deletions

View File

@ -2107,8 +2107,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
} }
this._setTileLoaded(tile, data, null, tileRequest, dataType); this._setTileLoaded(tile, data, null, tileRequest, dataType);
//TODO aiosa missing timeout might damage the cache system
}, },
/** /**

View File

@ -180,14 +180,36 @@
} }
}; };
// 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',
'World': 'viewer',
'DrawerBase': ['viewer', 'viewport'],
'CanvasDrawer': ['viewer', 'viewport'],
'WebGLDrawer': ['viewer', 'viewport'],
'TiledImage': ['viewer', '_drawer'],
};
for ( var i in testLog ) { for ( var i in testLog ) {
if ( testLog.hasOwnProperty( i ) && testLog[i].push ) { if ( testLog.hasOwnProperty( i ) && testLog[i].push ) {
//Tile.tiledImage creates circular reference, copy object to avoid and allow JSON serialization // Circular reference removal
const tileCircularStructureReplacer = function (key, value) { const osdCircularStructureReplacer = function (key, value) {
if (value instanceof OpenSeadragon.Tile) { for (let ClassType in circularOSDReferences) {
var instance = {}; if (value instanceof OpenSeadragon[ClassType]) {
const instance = {};
Object.assign(instance, value); Object.assign(instance, value);
delete value.tiledImage;
let circProps = circularOSDReferences[ClassType];
if (!Array.isArray(circProps)) circProps = [circProps];
for (let prop of circProps) {
instance[prop] = '__circular_reference__';
}
return instance;
}
} }
return value; return value;
}; };
@ -195,7 +217,7 @@
testConsole[i] = ( function ( arr ) { testConsole[i] = ( function ( arr ) {
return function () { return function () {
var args = Array.prototype.slice.call( arguments, 0 ); // Coerce to true Array var args = Array.prototype.slice.call( arguments, 0 ); // Coerce to true Array
arr.push( JSON.stringify( args, tileCircularStructureReplacer ) ); // Store as JSON to avoid tedious array-equality tests arr.push( JSON.stringify( args, osdCircularStructureReplacer ) ); // Store as JSON to avoid tedious array-equality tests
}; };
} )( testLog[i] ); } )( testLog[i] );

View File

@ -8,7 +8,7 @@
var DYNAMIC_URL = ""; var DYNAMIC_URL = "";
var viewer = null; var viewer = null;
var OriginalAjax = OpenSeadragon.makeAjaxRequest; var OriginalAjax = OpenSeadragon.makeAjaxRequest;
var OriginalTile = OpenSeadragon.Tile; var OriginalTileGetUrl = OpenSeadragon.Tile.prototype.getUrl;
// These variables allow tracking when the first request for data has finished // These variables allow tracking when the first request for data has finished
var firstUrlPromise = null; var firstUrlPromise = null;
var isFirstUrlPromiseResolved = false; var isFirstUrlPromiseResolved = false;
@ -115,22 +115,15 @@
return request; return request;
}; };
// Override Tile to ensure getUrl is called successfully. // Override Tile::getUrl to ensure getUrl is called successfully.
var Tile = function(...params) { OpenSeadragon.Tile.prototype.getUrl = function () {
OriginalTile.apply(this, params);
};
OpenSeadragon.extend( Tile.prototype, OpenSeadragon.Tile.prototype, {
getUrl: function() {
// if ASSERT is still truthy, call ASSERT.ok. If the viewer // if ASSERT is still truthy, call ASSERT.ok. If the viewer
// has already been destroyed and ASSERT has set to null, ignore this // has already been destroyed and ASSERT has set to null, ignore this
if (ASSERT) { if (ASSERT) {
ASSERT.ok(true, 'Tile.getUrl called'); ASSERT.ok(true, 'Tile.getUrl called');
} }
return OriginalTile.prototype.getUrl.apply(this); return OriginalTileGetUrl.apply(this, arguments);
} };
});
OpenSeadragon.Tile = Tile;
}, },
afterEach: function () { afterEach: function () {
@ -143,7 +136,7 @@
viewer = null; viewer = null;
OpenSeadragon.makeAjaxRequest = OriginalAjax; OpenSeadragon.makeAjaxRequest = OriginalAjax;
OpenSeadragon.Tile = OriginalTile; OpenSeadragon.Tile.prototype.getUrl = OriginalTileGetUrl;
} }
}); });