diff --git a/chrome/content/zotero/xpcom/sync/syncAPIClient.js b/chrome/content/zotero/xpcom/sync/syncAPIClient.js index 911a5ae3e..b56439e38 100644 --- a/chrome/content/zotero/xpcom/sync/syncAPIClient.js +++ b/chrome/content/zotero/xpcom/sync/syncAPIClient.js @@ -587,7 +587,7 @@ Zotero.Sync.APIClient.prototype = { this.failureDelayIntervals, 60 * 60 * 1000 ); } - let keepGoing = yield failureDelayGenerator.next(); + let keepGoing = yield failureDelayGenerator.next().value; if (!keepGoing) { Zotero.logError("Failed too many times"); throw lastError; diff --git a/chrome/content/zotero/xpcom/utilities_internal.js b/chrome/content/zotero/xpcom/utilities_internal.js index 51c08986b..b726d3b8f 100644 --- a/chrome/content/zotero/xpcom/utilities_internal.js +++ b/chrome/content/zotero/xpcom/utilities_internal.js @@ -461,25 +461,23 @@ Zotero.Utilities.Internal = { * promise will return false. Before maxTime has elapsed, or if * maxTime isn't specified, the promises will yield true. */ - "delayGenerator": function (intervals, maxTime) { + "delayGenerator": function* (intervals, maxTime) { var totalTime = 0; - var lastInterval = intervals[intervals.length - 1]; + var last = false; while (true) { let interval = intervals.shift(); if (interval) { - delay = lastInterval = interval; + delay = interval; } - else if (infinite) { - delay = lastInterval; - } - else { - break; + + if (maxTime && (totalTime + delay) > maxTime) { + yield Zotero.Promise.resolve(false); } totalTime += delay; Zotero.debug("Delaying " + delay + " ms"); - yield Zotero.Promise.delay(delay).return(!maxTime || totalTime <= maxTime); + yield Zotero.Promise.delay(delay).return(true); } }, diff --git a/test/tests/utilities_internalTest.js b/test/tests/utilities_internalTest.js index 7ff552908..c76ead75e 100644 --- a/test/tests/utilities_internalTest.js +++ b/test/tests/utilities_internalTest.js @@ -10,4 +10,58 @@ describe("Zotero.Utilities.Internal", function () { ); }) }) + + + describe("#delayGenerator", function () { + var spy; + + before(function () { + spy = sinon.spy(Zotero.Promise, "delay"); + }); + + afterEach(function () { + spy.reset(); + }); + + after(function () { + spy.restore(); + }); + + it("should delay for given amounts of time without limit", function* () { + var intervals = [1, 2]; + var gen = Zotero.Utilities.Internal.delayGenerator(intervals); + + // When intervals are exhausted, keep using last interval + var testIntervals = intervals.slice(); + testIntervals.push(intervals[intervals.length - 1]); + + for (let i of testIntervals) { + let val = yield gen.next().value; + assert.isTrue(val); + assert.isTrue(spy.calledWith(i)); + spy.reset(); + } + }); + + it("should return false when maxTime is reached", function* () { + var intervals = [5, 10]; + var gen = Zotero.Utilities.Internal.delayGenerator(intervals, 30); + + // When intervals are exhausted, keep using last interval + var testIntervals = intervals.slice(); + testIntervals.push(intervals[intervals.length - 1]); + + for (let i of testIntervals) { + let val = yield gen.next().value; + assert.isTrue(val); + assert.isTrue(spy.calledWith(i)); + spy.reset(); + } + + // Another interval would put us over maxTime, so return false immediately + let val = yield gen.next().value; + assert.isFalse(val); + assert.isFalse(spy.called); + }); + }) })