From e0f442209b2d86fc9043dc5457ca9fd3513f2822 Mon Sep 17 00:00:00 2001
From: Aiosa <469130@mail.muni.cz>
Date: Tue, 5 Mar 2024 10:48:07 +0100
Subject: [PATCH] Fix black viewport with testing filtering demo on webgl
renderer. Introduce managed mock getters for tests.
---
src/openseadragon.js | 2 +-
src/tile.js | 4 +-
src/tilecache.js | 5 +-
test/coverage.html | 1 +
test/helpers/mocks.js | 95 ++++++++++++++++++++++++
test/modules/tilecache.js | 128 ++++++++++----------------------
test/modules/tiledimage.js | 36 ++++-----
test/modules/type-conversion.js | 48 ++++--------
test/test.html | 1 +
9 files changed, 171 insertions(+), 149 deletions(-)
create mode 100644 test/helpers/mocks.js
diff --git a/src/openseadragon.js b/src/openseadragon.js
index d13fcfc8..0326b28f 100644
--- a/src/openseadragon.js
+++ b/src/openseadragon.js
@@ -2707,7 +2707,7 @@ function OpenSeadragon( options ){
if (newCache) {
newCache._updateStamp = tStamp;
} else {
- $.console.error("After an update, the tile %s has not cache data! Check handlers on 'tile-needs-update' evemt!", tile);
+ $.console.error("After an update, the tile %s has not cache data! Check handlers on 'tile-needs-update' event!", tile);
}
});
}
diff --git a/src/tile.js b/src/tile.js
index ce22ead4..258c62d6 100644
--- a/src/tile.js
+++ b/src/tile.js
@@ -598,8 +598,8 @@ $.Tile.prototype = {
ref.destroyInternalCache();
}
this._cKey = value;
- // when key changes the image probably needs re-render
- this.tiledImage.redraw();
+ // we do not trigger redraw, this is handled within cache
+ // as drawers request data for drawing
},
/**
diff --git a/src/tilecache.js b/src/tilecache.js
index 67aced6e..89bc4783 100644
--- a/src/tilecache.js
+++ b/src/tilecache.js
@@ -180,7 +180,8 @@
let internalCache = this[DRAWER_INTERNAL_CACHE];
if (keepInternalCopy && !internalCache) {
- this.prepareForRendering(supportedTypes, keepInternalCopy).then(() => this._triggerNeedsDraw);
+ this.prepareForRendering(supportedTypes, keepInternalCopy)
+ .then(() => this._triggerNeedsDraw());
return undefined;
}
@@ -198,7 +199,7 @@
if (!supportedTypes.includes(internalCache.type)) {
internalCache.transformTo(supportedTypes.length > 1 ? supportedTypes : supportedTypes[0])
- .then(() => this._triggerNeedsDraw);
+ .then(() => this._triggerNeedsDraw());
return undefined; // type is NOT compatible
}
diff --git a/test/coverage.html b/test/coverage.html
index e4046459..30b27ab2 100644
--- a/test/coverage.html
+++ b/test/coverage.html
@@ -58,6 +58,7 @@
+
diff --git a/test/helpers/mocks.js b/test/helpers/mocks.js
new file mode 100644
index 00000000..2958fe19
--- /dev/null
+++ b/test/helpers/mocks.js
@@ -0,0 +1,95 @@
+// Test-wide mocks for more test stability: tests might require calling functions that expect
+// presence of certain mock properties. It is better to include maintened mock props than to copy
+// over all the place
+
+window.MockSeadragon = {
+ /**
+ * Get mocked tile: loaded state, cutoff such that it is not kept in cache by force,
+ * level: 1, x: 0, y: 0, all coords: [x0 y0 w0 h0]
+ *
+ * Requires TiledImage referece (mock or real)
+ * @return {OpenSeadragon.Tile}
+ */
+ getTile(url, tiledImage, props={}) {
+ const dummyRect = new OpenSeadragon.Rect(0, 0, 0, 0, 0);
+ //default cutoof = 0 --> use level 1 to not to keep caches from unloading (cutoff = navigator data, kept in cache)
+ const dummyTile = new OpenSeadragon.Tile(1, 0, 0, dummyRect, true, url,
+ undefined, true, null, dummyRect, null, url);
+ dummyTile.tiledImage = tiledImage;
+ //by default set as ready
+ dummyTile.loaded = true;
+ dummyTile.loading = false;
+ //override anything we need
+ OpenSeadragon.extend(tiledImage, props);
+ return dummyTile;
+ },
+
+ /**
+ * Get mocked viewer: it has not all props that might be required. If your
+ * tests fails because they do not find some props on a viewer, add them here.
+ *
+ * Requires a drawer reference (mock or real). Automatically created if not provided.
+ * @return {OpenSeadragon.Viewer}
+ */
+ getViewer(drawer=null, props={}) {
+ drawer = drawer || this.getDrawer();
+ return OpenSeadragon.extend(new class extends OpenSeadragon.EventSource {
+ forceRedraw () {}
+ drawer = drawer
+ tileCache = new OpenSeadragon.TileCache()
+ }, props);
+ },
+
+ /**
+ * Get mocked viewer: it has not all props that might be required. If your
+ * tests fails because they do not find some props on a viewer, add them here.
+ * @return {OpenSeadragon.Viewer}
+ */
+ getDrawer(props={}) {
+ return OpenSeadragon.extend({
+ getType: function () {
+ return "mock";
+ }
+ }, props);
+ },
+
+ /**
+ * Get mocked tiled image: it has not all props that might be required. If your
+ * tests fails because they do not find some props on a tiled image, add them here.
+ *
+ * Requires viewer reference (mock or real). Automatically created if not provided.
+ * @return {OpenSeadragon.TiledImage}
+ */
+ getTiledImage(viewer=null, props={}) {
+ viewer = viewer || this.getViewer();
+ return OpenSeadragon.extend({
+ viewer: viewer,
+ source: OpenSeadragon.TileSource.prototype,
+ redraw: function() {},
+ _tileCache: viewer.tileCache
+ }, props);
+ },
+
+ /**
+ * Get mocked tile source
+ * @return {OpenSeadragon.TileSource}
+ */
+ getTileSource(props={}) {
+ return new OpenSeadragon.TileSource(OpenSeadragon.extend({
+ width: 1500,
+ height: 1000,
+ tileWidth: 200,
+ tileHeight: 150,
+ tileOverlap: 0
+ }, props));
+ },
+
+ /**
+ * Get mocked cache record
+ * @return {OpenSeadragon.CacheRecord}
+ */
+ getCacheRecord(props={}) {
+ return OpenSeadragon.extend(new OpenSeadragon.CacheRecord(), props);
+ }
+};
+
diff --git a/test/modules/tilecache.js b/test/modules/tilecache.js
index f06bea84..e5ebe519 100644
--- a/test/modules/tilecache.js
+++ b/test/modules/tilecache.js
@@ -18,17 +18,6 @@
}, 20);
}
- function createFakeTile(url, tiledImage, loading=false, loaded=true) {
- const dummyRect = new OpenSeadragon.Rect(0, 0, 0, 0, 0);
- //default cutoof = 0 --> use level 1 to not to keep caches from unloading (cutoff = navigator data, kept in cache)
- const dummyTile = new OpenSeadragon.Tile(1, 0, 0, dummyRect, true, url,
- undefined, true, null, dummyRect, null, url);
- dummyTile.tiledImage = tiledImage;
- dummyTile.loading = loading;
- dummyTile.loaded = loaded;
- return dummyTile;
- }
-
// Replace conversion with our own system and test: __TEST__ prefix must be used, otherwise
// other tests will interfere
let typeAtoB = 0, typeBtoC = 0, typeCtoA = 0, typeDtoA = 0, typeCtoE = 0;
@@ -122,28 +111,19 @@
// TODO: this used to be async
QUnit.test('basics', function(assert) {
const done = assert.async();
- const fakeViewer = {
- raiseEvent: function() {},
- drawer: {
+ const fakeViewer = MockSeadragon.getViewer(
+ MockSeadragon.getDrawer({
// tile in safe mode inspects the supported formats upon cache set
getSupportedDataFormats() {
return [T_A, T_B, T_C, T_D, T_E];
}
- }
- };
- const fakeTiledImage0 = {
- viewer: fakeViewer,
- source: OpenSeadragon.TileSource.prototype,
- redraw: function() {}
- };
- const fakeTiledImage1 = {
- viewer: fakeViewer,
- source: OpenSeadragon.TileSource.prototype,
- redraw: function() {}
- };
+ })
+ );
+ const fakeTiledImage0 = MockSeadragon.getTiledImage(fakeViewer);
+ const fakeTiledImage1 = MockSeadragon.getTiledImage(fakeViewer);
- const tile0 = createFakeTile('foo.jpg', fakeTiledImage0);
- const tile1 = createFakeTile('foo.jpg', fakeTiledImage1);
+ const tile0 = MockSeadragon.getTile('foo.jpg', fakeTiledImage0);
+ const tile1 = MockSeadragon.getTile('foo.jpg', fakeTiledImage1);
const cache = new OpenSeadragon.TileCache();
assert.equal(cache.numTilesLoaded(), 0, 'no tiles to begin with');
@@ -177,24 +157,18 @@
// ----------
QUnit.test('maxImageCacheCount', function(assert) {
const done = assert.async();
- const fakeViewer = {
- raiseEvent: function() {},
- drawer: {
+ const fakeViewer = MockSeadragon.getViewer(
+ MockSeadragon.getDrawer({
// tile in safe mode inspects the supported formats upon cache set
getSupportedDataFormats() {
return [T_A, T_B, T_C, T_D, T_E];
}
- }
- };
- const fakeTiledImage0 = {
- viewer: fakeViewer,
- source: OpenSeadragon.TileSource.prototype,
- draw: function() {}
- };
-
- const tile0 = createFakeTile('different.jpg', fakeTiledImage0);
- const tile1 = createFakeTile('same.jpg', fakeTiledImage0);
- const tile2 = createFakeTile('same.jpg', fakeTiledImage0);
+ })
+ );
+ const fakeTiledImage0 = MockSeadragon.getTiledImage(fakeViewer);
+ const tile0 = MockSeadragon.getTile('different.jpg', fakeTiledImage0);
+ const tile1 = MockSeadragon.getTile('same.jpg', fakeTiledImage0);
+ const tile2 = MockSeadragon.getTile('same.jpg', fakeTiledImage0);
const cache = new OpenSeadragon.TileCache({
maxImageCacheCount: 1
@@ -232,39 +206,28 @@
//Tile API and cache interaction
QUnit.test('Tile API: basic conversion', function(test) {
const done = test.async();
- const fakeViewer = {
- raiseEvent: function() {},
- drawer: {
+ const fakeViewer = MockSeadragon.getViewer(
+ MockSeadragon.getDrawer({
// tile in safe mode inspects the supported formats upon cache set
getSupportedDataFormats() {
return [T_A, T_B, T_C, T_D, T_E];
}
- }
- };
- const tileCache = new OpenSeadragon.TileCache();
- const fakeTiledImage0 = {
- viewer: fakeViewer,
- source: OpenSeadragon.TileSource.prototype,
- _tileCache: tileCache,
- redraw: function() {}
- };
- const fakeTiledImage1 = {
- viewer: fakeViewer,
- source: OpenSeadragon.TileSource.prototype,
- _tileCache: tileCache,
- redraw: function() {}
- };
+ })
+ );
+ const tileCache = fakeViewer.tileCache;
+ const fakeTiledImage0 = MockSeadragon.getTiledImage(fakeViewer);
+ const fakeTiledImage1 = MockSeadragon.getTiledImage(fakeViewer);
//load data
- const tile00 = createFakeTile('foo.jpg', fakeTiledImage0);
+ const tile00 = MockSeadragon.getTile('foo.jpg', fakeTiledImage0);
tile00.addCache(tile00.cacheKey, 0, T_A, false, false);
- const tile01 = createFakeTile('foo2.jpg', fakeTiledImage0);
+ const tile01 = MockSeadragon.getTile('foo2.jpg', fakeTiledImage0);
tile01.addCache(tile01.cacheKey, 0, T_B, false, false);
- const tile10 = createFakeTile('foo3.jpg', fakeTiledImage1);
+ const tile10 = MockSeadragon.getTile('foo3.jpg', fakeTiledImage1);
tile10.addCache(tile10.cacheKey, 0, T_C, false, false);
- const tile11 = createFakeTile('foo3.jpg', fakeTiledImage1);
+ const tile11 = MockSeadragon.getTile('foo3.jpg', fakeTiledImage1);
tile11.addCache(tile11.cacheKey, 0, T_C, false, false);
- const tile12 = createFakeTile('foo.jpg', fakeTiledImage1);
+ const tile12 = MockSeadragon.getTile('foo.jpg', fakeTiledImage1);
tile12.addCache(tile12.cacheKey, 0, T_A, false, false);
const collideGetSet = async (tile, type) => {
@@ -428,39 +391,28 @@
//Tile API and cache interaction
QUnit.test('Tile API Cache Interaction', function(test) {
const done = test.async();
- const fakeViewer = {
- raiseEvent: function() {},
- drawer: {
+ const fakeViewer = MockSeadragon.getViewer(
+ MockSeadragon.getDrawer({
// tile in safe mode inspects the supported formats upon cache set
getSupportedDataFormats() {
return [T_A, T_B, T_C, T_D, T_E];
}
- }
- };
- const tileCache = new OpenSeadragon.TileCache();
- const fakeTiledImage0 = {
- viewer: fakeViewer,
- source: OpenSeadragon.TileSource.prototype,
- _tileCache: tileCache,
- redraw: function() {}
- };
- const fakeTiledImage1 = {
- viewer: fakeViewer,
- source: OpenSeadragon.TileSource.prototype,
- _tileCache: tileCache,
- redraw: function() {}
- };
+ })
+ );
+ const tileCache = fakeViewer.tileCache;
+ const fakeTiledImage0 = MockSeadragon.getTiledImage(fakeViewer);
+ const fakeTiledImage1 = MockSeadragon.getTiledImage(fakeViewer);
//load data
- const tile00 = createFakeTile('foo.jpg', fakeTiledImage0);
+ const tile00 = MockSeadragon.getTile('foo.jpg', fakeTiledImage0);
tile00.addCache(tile00.cacheKey, 0, T_A, false, false);
- const tile01 = createFakeTile('foo2.jpg', fakeTiledImage0);
+ const tile01 = MockSeadragon.getTile('foo2.jpg', fakeTiledImage0);
tile01.addCache(tile01.cacheKey, 0, T_B, false, false);
- const tile10 = createFakeTile('foo3.jpg', fakeTiledImage1);
+ const tile10 = MockSeadragon.getTile('foo3.jpg', fakeTiledImage1);
tile10.addCache(tile10.cacheKey, 0, T_C, false, false);
- const tile11 = createFakeTile('foo3.jpg', fakeTiledImage1);
+ const tile11 = MockSeadragon.getTile('foo3.jpg', fakeTiledImage1);
tile11.addCache(tile11.cacheKey, 0, T_C, false, false);
- const tile12 = createFakeTile('foo.jpg', fakeTiledImage1);
+ const tile12 = MockSeadragon.getTile('foo.jpg', fakeTiledImage1);
tile12.addCache(tile12.cacheKey, 0, T_A, false, false);
//test set/get data in async env
diff --git a/test/modules/tiledimage.js b/test/modules/tiledimage.js
index 6c33b752..bbee01ce 100644
--- a/test/modules/tiledimage.js
+++ b/test/modules/tiledimage.js
@@ -558,17 +558,17 @@
});
QUnit.test('_getCornerTiles without wrapping', function(assert) {
- var tiledImageMock = {
+ var tiledImageMock = MockSeadragon.getTiledImage(null, {
wrapHorizontal: false,
wrapVertical: false,
- source: new OpenSeadragon.TileSource({
+ source: MockSeadragon.getTileSource({
width: 1500,
height: 1000,
tileWidth: 200,
tileHeight: 150,
tileOverlap: 1,
- }),
- };
+ })
+ });
var _getCornerTiles = OpenSeadragon.TiledImage.prototype._getCornerTiles.bind(tiledImageMock);
function assertCornerTiles(topLeftBound, bottomRightBound,
@@ -606,17 +606,13 @@
});
QUnit.test('_getCornerTiles with horizontal wrapping', function(assert) {
- var tiledImageMock = {
+ var tiledImageMock = MockSeadragon.getTiledImage(null, {
wrapHorizontal: true,
wrapVertical: false,
- source: new OpenSeadragon.TileSource({
- width: 1500,
- height: 1000,
- tileWidth: 200,
- tileHeight: 150,
- tileOverlap: 1,
- }),
- };
+ source: MockSeadragon.getTileSource({
+ tileOverlap: 1
+ })
+ });
var _getCornerTiles = OpenSeadragon.TiledImage.prototype._getCornerTiles.bind(tiledImageMock);
function assertCornerTiles(topLeftBound, bottomRightBound,
@@ -653,17 +649,13 @@
});
QUnit.test('_getCornerTiles with vertical wrapping', function(assert) {
- var tiledImageMock = {
+ var tiledImageMock = MockSeadragon.getTiledImage(null, {
wrapHorizontal: false,
wrapVertical: true,
- source: new OpenSeadragon.TileSource({
- width: 1500,
- height: 1000,
- tileWidth: 200,
- tileHeight: 150,
- tileOverlap: 1,
- }),
- };
+ source: MockSeadragon.getTileSource({
+ tileOverlap: 1
+ })
+ });
var _getCornerTiles = OpenSeadragon.TiledImage.prototype._getCornerTiles.bind(tiledImageMock);
function assertCornerTiles(topLeftBound, bottomRightBound,
diff --git a/test/modules/type-conversion.js b/test/modules/type-conversion.js
index 4882eadd..07fa1213 100644
--- a/test/modules/type-conversion.js
+++ b/test/modules/type-conversion.js
@@ -210,14 +210,8 @@
QUnit.test('Data Convertors via Cache object: testing conversion & destruction', function (test) {
const done = test.async();
-
- const dummyRect = new OpenSeadragon.Rect(0, 0, 0, 0, 0);
- const dummyTile = new OpenSeadragon.Tile(0, 0, 0, dummyRect, true, "",
- undefined, true, null, dummyRect, "", "key");
- dummyTile.tiledImage = {
- redraw: function () {}
- };
- const cache = new OpenSeadragon.CacheRecord();
+ const dummyTile = MockSeadragon.getTile("", MockSeadragon.getTiledImage(), {cacheKey: "key"});
+ const cache = MockSeadragon.getCacheRecord();
cache.addTile(dummyTile, "/test/data/A.png", "__TEST__url");
//load image object: url -> image
@@ -262,18 +256,14 @@
QUnit.test('Data Convertors via Cache object: testing set/get', function (test) {
const done = test.async();
- const dummyRect = new OpenSeadragon.Rect(0, 0, 0, 0, 0);
- const dummyTile = new OpenSeadragon.Tile(0, 0, 0, dummyRect, true, "",
- undefined, true, null, dummyRect, "", "key");
- dummyTile.tiledImage = {
- redraw: function () {}
- };
- const cache = new OpenSeadragon.CacheRecord();
- cache.testGetSet = async function(type) {
- const value = await cache.getDataAs(type, false);
- await cache.setDataAs(value, type);
- return value;
- }
+ const dummyTile = MockSeadragon.getTile("", MockSeadragon.getTiledImage(), {cacheKey: "key"});
+ const cache = MockSeadragon.getCacheRecord({
+ testGetSet: async function(type) {
+ const value = await cache.getDataAs(type, false);
+ await cache.setDataAs(value, type);
+ return value;
+ }
+ });
cache.addTile(dummyTile, "/test/data/A.png", "__TEST__url");
//load image object: url -> image
@@ -332,13 +322,8 @@
longConversionDestroy++;
});
- const dummyRect = new OpenSeadragon.Rect(0, 0, 0, 0, 0);
- const dummyTile = new OpenSeadragon.Tile(0, 0, 0, dummyRect, true, "",
- undefined, true, null, dummyRect, "", "key");
- dummyTile.tiledImage = {
- redraw: function () {}
- };
- const cache = new OpenSeadragon.CacheRecord();
+ const dummyTile = MockSeadragon.getTile("", MockSeadragon.getTiledImage(), {cacheKey: "key"});
+ const cache = MockSeadragon.getCacheRecord();
cache.addTile(dummyTile, "/test/data/A.png", "__TEST__url");
cache.getDataAs("__TEST__longConversionProcessForTesting").then(convertedData => {
test.equal(longConversionDestroy, 1, "Copy already destroyed.");
@@ -377,13 +362,8 @@
destructionHappened = true;
});
- const dummyRect = new OpenSeadragon.Rect(0, 0, 0, 0, 0);
- const dummyTile = new OpenSeadragon.Tile(0, 0, 0, dummyRect, true, "",
- undefined, true, null, dummyRect, "", "key");
- dummyTile.tiledImage = {
- redraw: function () {}
- };
- const cache = new OpenSeadragon.CacheRecord();
+ const dummyTile = MockSeadragon.getTile("", MockSeadragon.getTiledImage(), {cacheKey: "key"});
+ const cache = MockSeadragon.getCacheRecord();
cache.addTile(dummyTile, "/test/data/A.png", "__TEST__url");
cache.transformTo("__TEST__longConversionProcessForTesting").then(_ => {
test.ok(conversionHappened, "Interrupted conversion finished.");
diff --git a/test/test.html b/test/test.html
index 9baa6c1f..5da55417 100644
--- a/test/test.html
+++ b/test/test.html
@@ -24,6 +24,7 @@
+