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);
//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 ) {
if ( testLog.hasOwnProperty( i ) && testLog[i].push ) {
//Tile.tiledImage creates circular reference, copy object to avoid and allow JSON serialization
const tileCircularStructureReplacer = function (key, value) {
if (value instanceof OpenSeadragon.Tile) {
var instance = {};
// Circular reference removal
const osdCircularStructureReplacer = function (key, value) {
for (let ClassType in circularOSDReferences) {
if (value instanceof OpenSeadragon[ClassType]) {
const instance = {};
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;
};
@ -195,7 +217,7 @@
testConsole[i] = ( function ( arr ) {
return function () {
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] );

View File

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