Skip to content

Commit

Permalink
Allow translator tests to assert a detected item type (#19)
Browse files Browse the repository at this point in the history
This allows for expected-fail tests (detectedItemType: false) and tests for
translators that don't get enough information from the page to detect a specific
type accurately (like library translators that always detect 'book').
  • Loading branch information
AbeJellinek authored Mar 13, 2023
1 parent c1cc3bd commit fcb7b8a
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 24 deletions.
19 changes: 10 additions & 9 deletions src/translation/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -1680,21 +1680,20 @@ Zotero.Translate.Base.prototype = {
/**
* Begins running detect code for a translator, first loading it
*/
"_detect":function() {
_detect: async function() {
// there won't be any translators if we need an RPC call
if(!this._potentialTranslators.length) {
this.complete(true);
return;
return null;
}

let lab = this._potentialTranslators[0].label;
this._loadTranslator(this._potentialTranslators[0])
.then(function() {
return this._detectTranslatorLoaded();
}.bind(this))
.catch(function (e) {
try {
await this._loadTranslator(this._potentialTranslators[0]);
return await this._detectTranslatorLoaded();
}
catch (e) {
this.complete(false, e);
}.bind(this));
}
},

/**
Expand All @@ -1720,6 +1719,8 @@ Zotero.Translate.Base.prototype = {

if (returnValue !== undefined) this._returnValue = returnValue;
this.decrementAsyncProcesses("Zotero.Translate#getTranslators");

return returnValue;
},

/**
Expand Down
77 changes: 62 additions & 15 deletions testTranslators/translatorTester.js
Original file line number Diff line number Diff line change
Expand Up @@ -547,16 +547,35 @@ Zotero_TranslatorTester.prototype.runTest = function(test, doc, testDoneCallback
* Runs translation for a translator, given a document to test against
*/
Zotero_TranslatorTester.prototype._runTestTranslate = function(translate, translators, test, testDoneCallback) {
if(!translators.length) {
testDoneCallback(this, test, "failed", "Detection failed");
return;
} else if(this.type === "web" && translators[0].itemType !== Zotero.Translator.RUN_MODE_ZOTERO_SERVER
&& (translators[0].itemType !== "multiple" && test.items.length > 1 ||
test.items.length === 1 && translators[0].itemType !== test.items[0].itemType)) {
// this handles "items":"multiple" too, since the string has length 8
testDoneCallback(this, test, "failed", "Detection returned wrong item type");
if (!translators.length) {
if (test.detectedItemType === false) {
testDoneCallback(this, test, "succeeded", "Test succeeded");
}
else {
testDoneCallback(this, test, "failed", "Detection failed");
}
return;
}
else if (this.type === "web" && translators[0].itemType !== Zotero.Translator.RUN_MODE_ZOTERO_SERVER) {
let expected;
if (test.detectedItemType !== undefined) {
expected = test.detectedItemType;
}
else if (test.items.length === 1) {
expected = test.items[0].itemType;
}
else if (test.items.length > 1) {
expected = "multiple";
}
else {
testDoneCallback(this, test, "failed", "No items specified in test");
return;
}
if (translators[0].itemType !== expected) {
testDoneCallback(this, test, "failed", "Detection returned wrong item type");
return;
}
}

translate.setTranslator(this.translator);
translate.translate({
Expand Down Expand Up @@ -631,12 +650,13 @@ Zotero_TranslatorTester.prototype._checkResult = function(test, translate, retur
* Creates a new test for a document
* @param {Document} doc DOM document to test against
* @param {Function} testReadyCallback A callback to be passed test (as object) when complete
* @param {() => (Promise<Boolean> | Boolean)} detectionFailedCallback A callback to be called when detection fails.
* Allows the user to decide whether to continue creating an expected-fail test.
*/
Zotero_TranslatorTester.prototype.newTest = function(doc, testReadyCallback) {
Zotero_TranslatorTester.prototype.newTest = async function (doc, testReadyCallback, detectionFailedCallback) {
// keeps track of whether select was called
var multipleMode = false;

var me = this;
var translate = Zotero.Translate.newInstance(this.type);
if (this.translatorProvider) {
translate.setTranslatorProvider(this.translatorProvider);
Expand All @@ -650,6 +670,25 @@ Zotero_TranslatorTester.prototype.newTest = function(doc, testReadyCallback) {
doc.cookie
));
}

// internal hack to call detect on this translator
translate._potentialTranslators = [this.translator];
translate._foundTranslators = [];
translate._currentState = "detect";
let detectResult = await translate._detect();
if (!detectResult) {
if (!(await detectionFailedCallback())) {
return;
}
testReadyCallback(this,
{
type: this.type,
url: translate.document.location.href,
detectedItemType: false,
items: [],
});
}

translate.setTranslator(this.translator);
translate.setHandler("debug", this._debug);
translate.setHandler("select", function(obj, items, callback) {
Expand All @@ -667,7 +706,7 @@ Zotero_TranslatorTester.prototype.newTest = function(doc, testReadyCallback) {

callback(newItems);
});
translate.setHandler("done", function(obj, returnValue) { me._createTest(obj, multipleMode, returnValue, testReadyCallback) });
translate.setHandler("done", (obj, returnValue) => this._createTest(obj, detectResult, multipleMode, returnValue, testReadyCallback));
translate.capitalizeTitles = false;
translate.translate({
libraryID: false
Expand All @@ -677,9 +716,12 @@ Zotero_TranslatorTester.prototype.newTest = function(doc, testReadyCallback) {
/**
* Creates a new test for a document
* @param {Zotero.Translate} translate The Zotero.Translate instance
* @param {Function} testDoneCallback A callback to be passed test (as object) when complete
* @param {String | false} detectResult
* @param {Boolean} multipleMode
* @param {Object} returnValue
* @param {Function} testReadyCallback A callback to be passed test (as object) when complete
*/
Zotero_TranslatorTester.prototype._createTest = function(translate, multipleMode, returnValue, testReadyCallback) {
Zotero_TranslatorTester.prototype._createTest = function(translate, detectResult, multipleMode, returnValue, testReadyCallback) {
if(!returnValue) {
testReadyCallback(returnValue);
return;
Expand All @@ -699,8 +741,13 @@ Zotero_TranslatorTester.prototype._createTest = function(translate, multipleMode
var items = translate.newItems;
}

testReadyCallback(this, {"type":this.type, "url":translate.document.location.href,
"items":items});
testReadyCallback(this,
{
type: this.type,
url: translate.document.location.href,
detectedItemType: detectResult,
items: items,
});
};


Expand Down

0 comments on commit fcb7b8a

Please sign in to comment.