mirror of
https://github.com/openseadragon/openseadragon.git
synced 2025-02-12 04:49:23 +03:00
Update tests, fix async cache bug - first convert to supported format, then process. Record drawer ID in the internal cache type.
This commit is contained in:
parent
226a44c498
commit
03b7c5b9a6
@ -225,21 +225,17 @@
|
|||||||
prepareForRendering(drawer) {
|
prepareForRendering(drawer) {
|
||||||
const supportedTypes = drawer.getRequiredDataFormats();
|
const supportedTypes = drawer.getRequiredDataFormats();
|
||||||
|
|
||||||
if (drawer.options.usePrivateCache && drawer.options.preloadCache) {
|
let selfPromise;
|
||||||
return this.prepareInternalCacheAsync(drawer).then(_ => {
|
|
||||||
// if not internal copy and we have no data, or we are ready to render, exit
|
|
||||||
if (!this.loaded || supportedTypes.includes(this.type)) {
|
|
||||||
return this.await();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.transformTo(supportedTypes);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.loaded || supportedTypes.includes(this.type)) {
|
if (!this.loaded || supportedTypes.includes(this.type)) {
|
||||||
return this.await();
|
selfPromise = this.await();
|
||||||
|
} else {
|
||||||
|
selfPromise = this.transformTo(supportedTypes);
|
||||||
}
|
}
|
||||||
return this.transformTo(supportedTypes);
|
|
||||||
|
if (drawer.options.usePrivateCache && drawer.options.preloadCache) {
|
||||||
|
return selfPromise.then(_ => this.prepareInternalCacheAsync(drawer));
|
||||||
|
}
|
||||||
|
return selfPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -265,7 +261,9 @@
|
|||||||
$.console.assert(this._tRef, "Data Create called from invalidation routine needs tile reference!");
|
$.console.assert(this._tRef, "Data Create called from invalidation routine needs tile reference!");
|
||||||
const transformedData = drawer.dataCreate(this, this._tRef);
|
const transformedData = drawer.dataCreate(this, this._tRef);
|
||||||
$.console.assert(transformedData !== undefined, "[DrawerBase.dataCreate] must return a value if usePrivateCache is enabled!");
|
$.console.assert(transformedData !== undefined, "[DrawerBase.dataCreate] must return a value if usePrivateCache is enabled!");
|
||||||
internalCache = this[DRAWER_INTERNAL_CACHE][drawer.getId()] = new $.InternalCacheRecord(transformedData, (data) => drawer.dataFree(data));
|
const drawerID = drawer.getId();
|
||||||
|
internalCache = this[DRAWER_INTERNAL_CACHE][drawerID] = new $.InternalCacheRecord(transformedData,
|
||||||
|
drawerID, (data) => drawer.dataFree(data));
|
||||||
return internalCache.await();
|
return internalCache.await();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +288,10 @@
|
|||||||
$.console.assert(this._tRef, "Data Create called from drawing loop needs tile reference!");
|
$.console.assert(this._tRef, "Data Create called from drawing loop needs tile reference!");
|
||||||
const transformedData = drawer.dataCreate(this, this._tRef);
|
const transformedData = drawer.dataCreate(this, this._tRef);
|
||||||
$.console.assert(transformedData !== undefined, "[DrawerBase.dataCreate] must return a value if usePrivateCache is enabled!");
|
$.console.assert(transformedData !== undefined, "[DrawerBase.dataCreate] must return a value if usePrivateCache is enabled!");
|
||||||
internalCache = this[DRAWER_INTERNAL_CACHE][drawer.getId()] = new $.InternalCacheRecord(transformedData, (data) => drawer.dataFree(data));
|
|
||||||
|
const drawerID = drawer.getId();
|
||||||
|
internalCache = this[DRAWER_INTERNAL_CACHE][drawerID] = new $.InternalCacheRecord(transformedData,
|
||||||
|
drawerID, (data) => drawer.dataFree(data));
|
||||||
return internalCache;
|
return internalCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,9 +677,10 @@
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
$.InternalCacheRecord = class {
|
$.InternalCacheRecord = class {
|
||||||
constructor(data, onDestroy) {
|
constructor(data, type, onDestroy) {
|
||||||
this.tstamp = $.now();
|
this.tstamp = $.now();
|
||||||
this._ondestroy = onDestroy;
|
this._ondestroy = onDestroy;
|
||||||
|
this._type = type;
|
||||||
|
|
||||||
if (data instanceof $.Promise) {
|
if (data instanceof $.Promise) {
|
||||||
this._promise = data;
|
this._promise = data;
|
||||||
@ -706,7 +708,7 @@
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
get type() {
|
get type() {
|
||||||
return "__internal_cache__";
|
return this._type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1167,11 +1169,15 @@
|
|||||||
*/
|
*/
|
||||||
clearDrawerInternalCache(drawer) {
|
clearDrawerInternalCache(drawer) {
|
||||||
const drawerId = drawer.getId();
|
const drawerId = drawer.getId();
|
||||||
for (let zombie in this._zombiesLoaded) {
|
for (let zombie of this._zombiesLoaded) {
|
||||||
this._zombiesLoaded[zombie].destroyInternalCache(drawerId);
|
if (zombie) {
|
||||||
|
zombie.destroyInternalCache(drawerId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (let cache in this._tilesLoaded) {
|
for (let cache of this._cachesLoaded) {
|
||||||
this._tilesLoaded[cache].destroyInternalCache(drawerId);
|
if (cache) {
|
||||||
|
cache.destroyInternalCache(drawerId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,21 +92,6 @@
|
|||||||
this.testEvents = new OpenSeadragon.EventSource();
|
this.testEvents = new OpenSeadragon.EventSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
getType() {
|
|
||||||
return "test-cache-drawer";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make test use private cache
|
|
||||||
get defaultOptions() {
|
|
||||||
return {
|
|
||||||
usePrivateCache: true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getSupportedDataFormats() {
|
|
||||||
return [T_C, T_E];
|
|
||||||
}
|
|
||||||
|
|
||||||
static isSupported() {
|
static isSupported() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -128,12 +113,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataFree(data) {
|
||||||
|
this.testEvents.raiseEvent('free-data');
|
||||||
|
}
|
||||||
|
|
||||||
canRotate() {
|
canRotate() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
//noop
|
this.destroyInternalCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
setImageSmoothingEnabled(imageSmoothingEnabled){
|
setImageSmoothingEnabled(imageSmoothingEnabled){
|
||||||
@ -149,6 +138,60 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenSeadragon.SyncInternalCacheDrawer = class extends OpenSeadragon.TestCacheDrawer {
|
||||||
|
|
||||||
|
getType() {
|
||||||
|
return "test-cache-drawer-sync";
|
||||||
|
}
|
||||||
|
|
||||||
|
getSupportedDataFormats() {
|
||||||
|
return [T_C, T_E];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make test use private cache
|
||||||
|
get defaultOptions() {
|
||||||
|
return {
|
||||||
|
usePrivateCache: true,
|
||||||
|
preloadCache: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
dataCreate(cache, tile) {
|
||||||
|
this.testEvents.raiseEvent('create-data');
|
||||||
|
return cache.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenSeadragon.AsnycInternalCacheDrawer = class extends OpenSeadragon.TestCacheDrawer {
|
||||||
|
|
||||||
|
getType() {
|
||||||
|
return "test-cache-drawer-async";
|
||||||
|
}
|
||||||
|
|
||||||
|
getSupportedDataFormats() {
|
||||||
|
return [T_A];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make test use private cache
|
||||||
|
get defaultOptions() {
|
||||||
|
return {
|
||||||
|
usePrivateCache: true,
|
||||||
|
preloadCache: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
dataCreate(cache, tile) {
|
||||||
|
this.testEvents.raiseEvent('create-data');
|
||||||
|
return cache.getDataAs(T_C, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFree(data) {
|
||||||
|
super.dataFree(data);
|
||||||
|
// Be nice and truly destroy the data copy
|
||||||
|
OpenSeadragon.convertor.destroy(data, T_C);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OpenSeadragon.EmptyTestT_ATileSource = class extends OpenSeadragon.TileSource {
|
OpenSeadragon.EmptyTestT_ATileSource = class extends OpenSeadragon.TileSource {
|
||||||
|
|
||||||
supports( data, url ){
|
supports( data, url ){
|
||||||
@ -184,14 +227,6 @@
|
|||||||
$('<div id="example"></div>').appendTo("#qunit-fixture");
|
$('<div id="example"></div>').appendTo("#qunit-fixture");
|
||||||
|
|
||||||
testLog.reset();
|
testLog.reset();
|
||||||
|
|
||||||
viewer = OpenSeadragon({
|
|
||||||
id: 'example',
|
|
||||||
prefixUrl: '/build/openseadragon/images/',
|
|
||||||
maxImageCacheCount: 200, //should be enough to fit test inside the cache
|
|
||||||
springStiffness: 100, // Faster animation = faster tests
|
|
||||||
drawer: 'test-cache-drawer',
|
|
||||||
});
|
|
||||||
OpenSeadragon.ImageLoader.prototype.addJob = originalJob;
|
OpenSeadragon.ImageLoader.prototype.addJob = originalJob;
|
||||||
|
|
||||||
// Reset counters
|
// Reset counters
|
||||||
@ -313,201 +348,234 @@
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
//Tile API and cache interaction
|
// Tile API and cache interaction
|
||||||
// QUnit.test('Tile: basic rendering & test setup', function(test) {
|
QUnit.test('Tile: basic rendering & test setup (sync drawer)', function(test) {
|
||||||
// const done = test.async();
|
const done = test.async();
|
||||||
//
|
|
||||||
// const tileCache = viewer.tileCache;
|
|
||||||
// const drawer = viewer.drawer;
|
|
||||||
//
|
|
||||||
// let testTileCalled = false;
|
|
||||||
// drawer.testEvents.addHandler('test-tile', e => {
|
|
||||||
// testTileCalled = true;
|
|
||||||
// test.ok(e.dataToDraw, "Tile data is ready to be drawn");
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// viewer.addHandler('open', async () => {
|
|
||||||
// await viewer.waitForFinishedJobsForTest();
|
|
||||||
// await sleep(1); // necessary to make space for a draw call
|
|
||||||
//
|
|
||||||
// test.ok(viewer.world.getItemAt(0).source instanceof OpenSeadragon.EmptyTestT_ATileSource, "Tests are done with empty test source type T_A.");
|
|
||||||
// test.ok(viewer.world.getItemAt(1).source instanceof OpenSeadragon.EmptyTestT_ATileSource, "Tests are done with empty test source type T_A.");
|
|
||||||
// test.ok(testTileCalled, "Drawer tested at least one tile.");
|
|
||||||
//
|
|
||||||
// test.ok(typeAtoB > 1, "At least one conversion was triggered.");
|
|
||||||
// test.equal(typeAtoB, typeBtoC, "A->B = B->C, since we need to move all data to T_C for the drawer.");
|
|
||||||
//
|
|
||||||
// for (let tile of tileCache._tilesLoaded) {
|
|
||||||
// const cache = tile.getCache();
|
|
||||||
// test.equal(cache.type, T_A, "Cache data was not affected, the drawer uses internal cache.");
|
|
||||||
//
|
|
||||||
// const internalCache = cache.getCacheForRendering(drawer, tile);
|
|
||||||
// test.equal(internalCache.type, T_C, "Conversion A->C ready, since there is no way to get to T_E.");
|
|
||||||
// test.ok(internalCache.loaded, "Internal cache ready.");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// done();
|
|
||||||
// });
|
|
||||||
// viewer.open([
|
|
||||||
// {isTestSource: true},
|
|
||||||
// {isTestSource: true},
|
|
||||||
// ]);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// QUnit.test('Tile & Invalidation API: basic conversion & preprocessing', function(test) {
|
viewer = OpenSeadragon({
|
||||||
// const done = test.async();
|
id: 'example',
|
||||||
//
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
// const tileCache = viewer.tileCache;
|
maxImageCacheCount: 200, //should be enough to fit test inside the cache
|
||||||
// const drawer = viewer.drawer;
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
//
|
drawer: 'test-cache-drawer-sync',
|
||||||
// let testTileCalled = false;
|
});
|
||||||
//
|
|
||||||
// let _currentTestVal = undefined;
|
const tileCache = viewer.tileCache;
|
||||||
// let previousTestValue = undefined;
|
const drawer = viewer.drawer;
|
||||||
// drawer.testEvents.addHandler('test-tile', e => {
|
|
||||||
// test.ok(e.dataToDraw, "Tile data is ready to be drawn");
|
let testTileCalled = false;
|
||||||
// if (_currentTestVal !== undefined) {
|
let countFreeCalled = 0;
|
||||||
// testTileCalled = true;
|
let countCreateCalled = 0;
|
||||||
// test.equal(e.dataToDraw, _currentTestVal, "Value is correct on the drawn data.");
|
drawer.testEvents.addHandler('test-tile', e => {
|
||||||
// }
|
testTileCalled = true;
|
||||||
// });
|
test.ok(e.dataToDraw, "Tile data is ready to be drawn");
|
||||||
//
|
});
|
||||||
// function testDrawingRoutine(value) {
|
drawer.testEvents.addHandler('create-data', e => {
|
||||||
// _currentTestVal = value;
|
countCreateCalled++;
|
||||||
// viewer.world.needsDraw();
|
});
|
||||||
// viewer.world.draw();
|
drawer.testEvents.addHandler('free-data', e => {
|
||||||
// previousTestValue = value;
|
countFreeCalled++;
|
||||||
// _currentTestVal = undefined;
|
});
|
||||||
// }
|
|
||||||
//
|
viewer.addHandler('open', async () => {
|
||||||
// viewer.addHandler('open', async () => {
|
await viewer.waitForFinishedJobsForTest();
|
||||||
// await viewer.waitForFinishedJobsForTest();
|
await sleep(1); // necessary to make space for a draw call
|
||||||
// await sleep(1); // necessary to make space for a draw call
|
|
||||||
//
|
test.ok(viewer.world.getItemAt(0).source instanceof OpenSeadragon.EmptyTestT_ATileSource, "Tests are done with empty test source type T_A.");
|
||||||
// // Test simple data set -> creates main cache
|
test.ok(viewer.world.getItemAt(1).source instanceof OpenSeadragon.EmptyTestT_ATileSource, "Tests are done with empty test source type T_A.");
|
||||||
//
|
test.ok(testTileCalled, "Drawer tested at least one tile.");
|
||||||
// let testHandler = async e => {
|
|
||||||
// // data comes in as T_A
|
test.ok(typeAtoB > 1, "At least one conversion was triggered.");
|
||||||
// test.equal(typeDtoA, 0, "No conversion needed to get type A.");
|
test.equal(typeAtoB, typeBtoC, "A->B = B->C, since we need to move all data to T_C for the drawer.");
|
||||||
// test.equal(typeCtoA, 0, "No conversion needed to get type A.");
|
|
||||||
//
|
for (let tile of tileCache._tilesLoaded) {
|
||||||
// const data = await e.getData(T_A);
|
const cache = tile.getCache();
|
||||||
// test.equal(data, 1, "Copy: creation of a working cache.");
|
test.equal(cache.type, T_C, "Cache data was affected, the drawer supports only T_C since there is no way to get to T_E.");
|
||||||
// e.tile.__TEST_PROCESSED = true;
|
|
||||||
//
|
const internalCache = cache.getDataForRendering(drawer, tile);
|
||||||
// // Test value 2 since we set T_C no need to convert
|
test.equal(internalCache.type, viewer.drawer.getId(), "Sync conversion routine means T_C is also internal since dataCreate only creates data. However, internal cache keeps type of the drawer ID.");
|
||||||
// await e.setData(2, T_C);
|
test.ok(internalCache.loaded, "Internal cache ready.");
|
||||||
// test.notOk(e.outdated(), "Event is still valid.");
|
}
|
||||||
// };
|
|
||||||
//
|
test.ok(countCreateCalled > 0, "Internal cache creation called.");
|
||||||
// viewer.addHandler('tile-invalidated', testHandler);
|
viewer.drawer.destroyInternalCache();
|
||||||
// await viewer.world.requestInvalidate(true);
|
test.equal(countCreateCalled, countFreeCalled, "Free called as many times as create.");
|
||||||
// await sleep(1); // necessary to make space for internal updates
|
|
||||||
// testDrawingRoutine(2);
|
done();
|
||||||
//
|
});
|
||||||
// //test for each level only single cache was processed
|
viewer.open([
|
||||||
// const processedLevels = {};
|
{isTestSource: true},
|
||||||
// for (let tile of tileCache._tilesLoaded) {
|
{isTestSource: true},
|
||||||
// const level = tile.level;
|
]);
|
||||||
//
|
});
|
||||||
// if (tile.__TEST_PROCESSED) {
|
|
||||||
// test.ok(!processedLevels[level], "Only single tile processed per level.");
|
QUnit.test('Tile & Invalidation API: basic conversion & preprocessing', function(test) {
|
||||||
// processedLevels[level] = true;
|
const done = test.async();
|
||||||
// delete tile.__TEST_PROCESSED;
|
|
||||||
// }
|
viewer = OpenSeadragon({
|
||||||
//
|
id: 'example',
|
||||||
// const origCache = tile.getCache(tile.originalCacheKey);
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
// test.equal(origCache.type, T_A, "Original cache data was not affected, the drawer uses internal cache.");
|
maxImageCacheCount: 200, //should be enough to fit test inside the cache
|
||||||
// test.equal(origCache.data, 0, "Original cache data was not affected, the drawer uses internal cache.");
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
//
|
drawer: 'test-cache-drawer-async',
|
||||||
// const cache = tile.getCache();
|
});
|
||||||
// test.equal(cache.type, T_C, "Main Cache Updated (suite 1)");
|
const tileCache = viewer.tileCache;
|
||||||
// test.equal(cache.data, previousTestValue, "Main Cache Updated (suite 1)");
|
const drawer = viewer.drawer;
|
||||||
//
|
|
||||||
// const internalCache = cache.getCacheForRendering(drawer, tile);
|
let testTileCalled = false;
|
||||||
// test.equal(T_C, internalCache.type, "Conversion A->C ready, since there is no way to get to T_E.");
|
|
||||||
// test.ok(internalCache.loaded, "Internal cache ready.");
|
let _currentTestVal = undefined;
|
||||||
// }
|
let previousTestValue = undefined;
|
||||||
//
|
drawer.testEvents.addHandler('test-tile', e => {
|
||||||
// // Test that basic scenario with reset data false starts from the main cache data of previous round
|
test.ok(e.dataToDraw, "Tile data is ready to be drawn");
|
||||||
// const modificationConstant = 50;
|
if (_currentTestVal !== undefined) {
|
||||||
// viewer.removeHandler('tile-invalidated', testHandler);
|
testTileCalled = true;
|
||||||
// testHandler = async e => {
|
test.equal(e.dataToDraw, _currentTestVal, "Value is correct on the drawn data.");
|
||||||
// const data = await e.getData(T_B);
|
}
|
||||||
// test.equal(data, previousTestValue + 2, "C -> A -> B conversion happened.");
|
});
|
||||||
// await e.setData(data + modificationConstant, T_B);
|
|
||||||
// console.log(data + modificationConstant);
|
function testDrawingRoutine(value) {
|
||||||
// test.notOk(e.outdated(), "Event is still valid.");
|
_currentTestVal = value;
|
||||||
// };
|
viewer.world.needsDraw();
|
||||||
// console.log(previousTestValue, modificationConstant)
|
viewer.world.draw();
|
||||||
//
|
_currentTestVal = undefined;
|
||||||
// viewer.addHandler('tile-invalidated', testHandler);
|
}
|
||||||
// await viewer.world.requestInvalidate(false);
|
|
||||||
// await sleep(1); // necessary to make space for a draw call
|
viewer.addHandler('open', async () => {
|
||||||
// // We set data as TB - there is T_C -> T_A -> T_B -> T_C conversion round
|
await viewer.waitForFinishedJobsForTest();
|
||||||
// let newValue = previousTestValue + modificationConstant + 3;
|
await sleep(1); // necessary to make space for a draw call
|
||||||
// testDrawingRoutine(newValue);
|
|
||||||
//
|
// Test simple data set -> creates main cache
|
||||||
// newValue--; // intenrla cache performed +1 conversion, but here we have main cache with one step less
|
|
||||||
// for (let tile of tileCache._tilesLoaded) {
|
let testHandler = async e => {
|
||||||
// const cache = tile.getCache();
|
// data comes in as T_A
|
||||||
// test.equal(cache.type, T_B, "Main Cache Updated (suite 2).");
|
test.equal(typeDtoA, 0, "No conversion needed to get type A.");
|
||||||
// test.equal(cache.data, newValue, "Main Cache Updated (suite 2).");
|
test.equal(typeCtoA, 0, "No conversion needed to get type A.");
|
||||||
// }
|
|
||||||
//
|
const data = await e.getData(T_A);
|
||||||
// // Now test whether data reset works, value 1 -> copy perfomed due to internal cache cration
|
test.equal(data, 1, "Copy: creation of a working cache.");
|
||||||
// viewer.removeHandler('tile-invalidated', testHandler);
|
e.tile.__TEST_PROCESSED = true;
|
||||||
// testHandler = async e => {
|
|
||||||
// const data = await e.getData(T_B);
|
// Test value 2 since we set T_C no need to convert
|
||||||
// test.equal(data, 1, "Copy: creation of a working cache.");
|
await e.setData(2, T_C);
|
||||||
// await e.setData(-8, T_E);
|
test.notOk(e.outdated(), "Event is still valid.");
|
||||||
// e.resetData();
|
};
|
||||||
// };
|
|
||||||
// viewer.addHandler('tile-invalidated', testHandler);
|
viewer.addHandler('tile-invalidated', testHandler);
|
||||||
// await viewer.world.requestInvalidate(true);
|
await viewer.world.requestInvalidate(true);
|
||||||
// await sleep(1); // necessary to make space for a draw call
|
|
||||||
// testDrawingRoutine(2); // Value +2 rendering from original data
|
//test for each level only single cache was processed
|
||||||
//
|
const processedLevels = {};
|
||||||
// for (let tile of tileCache._tilesLoaded) {
|
for (let tile of tileCache._tilesLoaded) {
|
||||||
// const origCache = tile.getCache(tile.originalCacheKey);
|
const level = tile.level;
|
||||||
// test.ok(tile.getCache() === origCache, "Main cache is now original cache.");
|
|
||||||
// }
|
if (tile.__TEST_PROCESSED) {
|
||||||
//
|
test.ok(!processedLevels[level], "Only single tile processed per level.");
|
||||||
// // Now force main cache creation that differs
|
processedLevels[level] = true;
|
||||||
// viewer.removeHandler('tile-invalidated', testHandler);
|
delete tile.__TEST_PROCESSED;
|
||||||
// testHandler = async e => {
|
}
|
||||||
// await e.setData(41, T_B);
|
|
||||||
// };
|
const origCache = tile.getCache(tile.originalCacheKey);
|
||||||
// viewer.addHandler('tile-invalidated', testHandler);
|
test.equal(origCache.type, T_A, "Original cache data was not affected, the drawer uses internal cache.");
|
||||||
// await viewer.world.requestInvalidate(true);
|
test.equal(origCache.data, 0, "Original cache data was not affected, the drawer uses internal cache.");
|
||||||
//
|
|
||||||
// // Now test whether data reset works, even with non-original data
|
const cache = tile.getCache();
|
||||||
// viewer.removeHandler('tile-invalidated', testHandler);
|
test.equal(cache.type, T_A, "Main Cache Converted T_C -> T_A (drawer supports type A) (suite 1)");
|
||||||
// testHandler = async e => {
|
test.equal(cache.data, 3, "Conversion step increases plugin-stored value 2 to 3");
|
||||||
// const data = await e.getData(T_B);
|
|
||||||
// test.equal(data, 42, "Copy: 41 + 1.");
|
const internalCache = cache.getDataForRendering(drawer, tile);
|
||||||
// await e.setData(data, T_E);
|
test.equal(internalCache.type, viewer.drawer.getId(), "Internal cache has type of the drawer ID.");
|
||||||
// e.resetData();
|
test.ok(internalCache.loaded, "Internal cache ready.");
|
||||||
// };
|
}
|
||||||
// viewer.addHandler('tile-invalidated', testHandler);
|
// Internal cache will have value 5: main cache is 3, type is T_A,
|
||||||
// await viewer.world.requestInvalidate(false);
|
testDrawingRoutine(5); // internal cache transforms to T_C: two steps, TA->TB->TC 3+2
|
||||||
// await sleep(1); // necessary to make space for a draw call
|
|
||||||
// testDrawingRoutine(42);
|
// Test that basic scenario with reset data false starts from the main cache data of previous round
|
||||||
//
|
const modificationConstant = 50;
|
||||||
// for (let tile of tileCache._tilesLoaded) {
|
viewer.removeHandler('tile-invalidated', testHandler);
|
||||||
// const origCache = tile.getCache(tile.originalCacheKey);
|
testHandler = async e => {
|
||||||
// test.equal(origCache.type, T_A, "Original cache data was not affected, the drawer uses main cache even after refresh.");
|
const data = await e.getData(T_B);
|
||||||
// test.equal(origCache.data, 0, "Original cache data was not affected, the drawer uses main cache even after refresh.");
|
test.equal(data, 4, "A -> B conversion happened, we started from value 3 in the main cache.");
|
||||||
// }
|
await e.setData(data + modificationConstant, T_B);
|
||||||
//
|
test.notOk(e.outdated(), "Event is still valid.");
|
||||||
// test.ok(testTileCalled, "Drawer tested at least one tile.");
|
};
|
||||||
// done();
|
|
||||||
// });
|
viewer.addHandler('tile-invalidated', testHandler);
|
||||||
// viewer.open([
|
await viewer.world.requestInvalidate(false);
|
||||||
// {isTestSource: true},
|
|
||||||
// {isTestSource: true},
|
// We set data as TB - there is required T_A: T_B -> T_C -> T_A conversion round on the main cache
|
||||||
// ]);
|
let newValue = modificationConstant + 4 + 2;
|
||||||
// });
|
// and there is still requirement of T_C on internal data, +2 steps
|
||||||
|
testDrawingRoutine(newValue + 2);
|
||||||
|
|
||||||
|
for (let tile of tileCache._tilesLoaded) {
|
||||||
|
const cache = tile.getCache();
|
||||||
|
test.equal(cache.type, T_A, "Main Cache Updated (suite 2).");
|
||||||
|
test.equal(cache.data, newValue, "Main Cache Updated (suite 2).");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now test whether data reset works, value 1 -> copy perfomed due to internal cache cration
|
||||||
|
viewer.removeHandler('tile-invalidated', testHandler);
|
||||||
|
testHandler = async e => {
|
||||||
|
const data = await e.getData(T_B);
|
||||||
|
test.equal(data, 1, "Copy: creation of a working cache.");
|
||||||
|
await e.setData(-8, T_E);
|
||||||
|
e.resetData();
|
||||||
|
};
|
||||||
|
viewer.addHandler('tile-invalidated', testHandler);
|
||||||
|
await viewer.world.requestInvalidate(true);
|
||||||
|
await sleep(1); // necessary to make space for a draw call
|
||||||
|
testDrawingRoutine(2); // Value +2 rendering from original data
|
||||||
|
|
||||||
|
for (let tile of tileCache._tilesLoaded) {
|
||||||
|
const origCache = tile.getCache(tile.originalCacheKey);
|
||||||
|
test.ok(tile.getCache() === origCache, "Main cache is now original cache.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now force main cache creation that differs
|
||||||
|
viewer.removeHandler('tile-invalidated', testHandler);
|
||||||
|
testHandler = async e => {
|
||||||
|
await e.setData(41, T_B);
|
||||||
|
};
|
||||||
|
viewer.addHandler('tile-invalidated', testHandler);
|
||||||
|
await viewer.world.requestInvalidate(true);
|
||||||
|
|
||||||
|
// Now test whether data reset works, even with non-original data
|
||||||
|
viewer.removeHandler('tile-invalidated', testHandler);
|
||||||
|
testHandler = async e => {
|
||||||
|
const data = await e.getData(T_B);
|
||||||
|
test.equal(data, 44, "Copy: 41 +2 (previous request invalidate ends at T_A) + 1 (we request type B).");
|
||||||
|
await e.setData(data, T_E); // there is no way to convert T_E -> T_A, this would throw an error
|
||||||
|
e.resetData(); // reset data will revert to original cache
|
||||||
|
};
|
||||||
|
viewer.addHandler('tile-invalidated', testHandler);
|
||||||
|
|
||||||
|
// The data will be 45 since no change has been made:
|
||||||
|
// last main cache set was 41 T_B, supported T_A = +2
|
||||||
|
// and internal requirement T_C = +2
|
||||||
|
const checkNotCalled = e => {
|
||||||
|
test.ok(false, "Create data must not be called when there is no change!");
|
||||||
|
};
|
||||||
|
drawer.testEvents.addHandler('create-data', checkNotCalled);
|
||||||
|
|
||||||
|
await viewer.world.requestInvalidate(false);
|
||||||
|
testDrawingRoutine(45);
|
||||||
|
|
||||||
|
for (let tile of tileCache._tilesLoaded) {
|
||||||
|
const origCache = tile.getCache(tile.originalCacheKey);
|
||||||
|
test.equal(origCache.type, T_A, "Original cache data was not affected, the drawer uses main cache even after refresh.");
|
||||||
|
test.equal(origCache.data, 0, "Original cache data was not affected, the drawer uses main cache even after refresh.");
|
||||||
|
}
|
||||||
|
|
||||||
|
test.ok(testTileCalled, "Drawer tested at least one tile.");
|
||||||
|
viewer.destroy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
viewer.open([
|
||||||
|
{isTestSource: true},
|
||||||
|
{isTestSource: true},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
//Tile API and cache interaction
|
//Tile API and cache interaction
|
||||||
QUnit.test('Tile API Cache Interaction', function(test) {
|
QUnit.test('Tile API Cache Interaction', function(test) {
|
||||||
@ -632,6 +700,14 @@
|
|||||||
QUnit.test('Zombie Cache', function(test) {
|
QUnit.test('Zombie Cache', function(test) {
|
||||||
const done = test.async();
|
const done = test.async();
|
||||||
|
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'example',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
maxImageCacheCount: 200, //should be enough to fit test inside the cache
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
drawer: 'test-cache-drawer-sync',
|
||||||
|
});
|
||||||
|
|
||||||
//test jobs by coverage: fail if cached coverage not fully re-stored without jobs
|
//test jobs by coverage: fail if cached coverage not fully re-stored without jobs
|
||||||
let jobCounter = 0, coverage = undefined;
|
let jobCounter = 0, coverage = undefined;
|
||||||
OpenSeadragon.ImageLoader.prototype.addJob = function (options) {
|
OpenSeadragon.ImageLoader.prototype.addJob = function (options) {
|
||||||
@ -711,6 +787,14 @@
|
|||||||
QUnit.test('Zombie Cache Replace Item', function(test) {
|
QUnit.test('Zombie Cache Replace Item', function(test) {
|
||||||
const done = test.async();
|
const done = test.async();
|
||||||
|
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'example',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
maxImageCacheCount: 200, //should be enough to fit test inside the cache
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
drawer: 'test-cache-drawer-sync',
|
||||||
|
});
|
||||||
|
|
||||||
let jobCounter = 0, coverage = undefined;
|
let jobCounter = 0, coverage = undefined;
|
||||||
OpenSeadragon.ImageLoader.prototype.addJob = function (options) {
|
OpenSeadragon.ImageLoader.prototype.addJob = function (options) {
|
||||||
jobCounter++;
|
jobCounter++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user