diff options
Diffstat (limited to 'toolkit/modules/tests/xpcshell/test_FinderIterator.js')
-rw-r--r-- | toolkit/modules/tests/xpcshell/test_FinderIterator.js | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/toolkit/modules/tests/xpcshell/test_FinderIterator.js b/toolkit/modules/tests/xpcshell/test_FinderIterator.js new file mode 100644 index 000000000..02c923a00 --- /dev/null +++ b/toolkit/modules/tests/xpcshell/test_FinderIterator.js @@ -0,0 +1,265 @@ +const { interfaces: Ci, classes: Cc, utils: Cu } = Components; +const { FinderIterator } = Cu.import("resource://gre/modules/FinderIterator.jsm", {}); +Cu.import("resource://gre/modules/Promise.jsm"); + +var gFindResults = []; +// Stub the method that instantiates nsIFind and does all the interaction with +// the docShell to be searched through. +FinderIterator._iterateDocument = function* (word, window, finder) { + for (let range of gFindResults) + yield range; +}; + +FinderIterator._rangeStartsInLink = fakeRange => fakeRange.startsInLink; + +function FakeRange(textContent, startsInLink = false) { + this.startContainer = {}; + this.startsInLink = startsInLink; + this.toString = () => textContent; +} + +var gMockWindow = { + setTimeout(cb, delay) { + Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer) + .initWithCallback(cb, delay, Ci.nsITimer.TYPE_ONE_SHOT); + } +}; + +var gMockFinder = { + _getWindow() { return gMockWindow; } +}; + +function prepareIterator(findText, rangeCount) { + gFindResults = []; + for (let i = rangeCount; --i >= 0;) + gFindResults.push(new FakeRange(findText)); +} + +add_task(function* test_start() { + let findText = "test"; + let rangeCount = 300; + prepareIterator(findText, rangeCount); + + let count = 0; + yield FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { + onIteratorRangeFound(range) { + ++count; + Assert.equal(range.toString(), findText, "Text content should match"); + } + }, + word: findText + }); + + Assert.equal(rangeCount, count, "Amount of ranges yielded should match!"); + Assert.ok(!FinderIterator.running, "Running state should match"); + Assert.equal(FinderIterator._previousRanges.length, rangeCount, "Ranges cache should match"); + + FinderIterator.reset(); +}); + +add_task(function* test_valid_arguments() { + let findText = "foo"; + let rangeCount = 20; + prepareIterator(findText, rangeCount); + + let count = 0; + + yield FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }); + + let params = FinderIterator._previousParams; + Assert.ok(!params.linksOnly, "Default for linksOnly is false"); + Assert.ok(!params.useCache, "Default for useCache is false"); + Assert.equal(params.word, findText, "Words should match"); + + count = 0; + Assert.throws(() => FinderIterator.start({ + entireWord: false, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }), /Missing required option 'caseSensitive'/, "Should throw when missing an argument"); + FinderIterator.reset(); + + Assert.throws(() => FinderIterator.start({ + caseSensitive: false, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }), /Missing required option 'entireWord'/, "Should throw when missing an argument"); + FinderIterator.reset(); + + Assert.throws(() => FinderIterator.start({ + caseSensitive: false, + entireWord: false, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }), /Missing required option 'finder'/, "Should throw when missing an argument"); + FinderIterator.reset(); + + Assert.throws(() => FinderIterator.start({ + caseSensitive: true, + entireWord: false, + finder: gMockFinder, + word: findText + }), /Missing valid, required option 'listener'/, "Should throw when missing an argument"); + FinderIterator.reset(); + + Assert.throws(() => FinderIterator.start({ + caseSensitive: false, + entireWord: true, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count; } }, + }), /Missing required option 'word'/, "Should throw when missing an argument"); + FinderIterator.reset(); + + Assert.equal(count, 0, "No ranges should've been counted"); +}); + +add_task(function* test_stop() { + let findText = "bar"; + let rangeCount = 120; + prepareIterator(findText, rangeCount); + + let count = 0; + let whenDone = FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }); + + FinderIterator.stop(); + + yield whenDone; + + Assert.equal(count, 0, "Number of ranges should be 0"); + + FinderIterator.reset(); +}); + +add_task(function* test_reset() { + let findText = "tik"; + let rangeCount = 142; + prepareIterator(findText, rangeCount); + + let count = 0; + let whenDone = FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }); + + Assert.ok(FinderIterator.running, "Yup, running we are"); + Assert.equal(count, 0, "Number of ranges should match 0"); + Assert.equal(FinderIterator.ranges.length, 0, "Number of ranges should match 0"); + + FinderIterator.reset(); + + Assert.ok(!FinderIterator.running, "Nope, running we are not"); + Assert.equal(FinderIterator.ranges.length, 0, "No ranges after reset"); + Assert.equal(FinderIterator._previousRanges.length, 0, "No ranges after reset"); + + yield whenDone; + + Assert.equal(count, 0, "Number of ranges should match 0"); +}); + +add_task(function* test_parallel_starts() { + let findText = "tak"; + let rangeCount = 2143; + prepareIterator(findText, rangeCount); + + // Start off the iterator. + let count = 0; + let whenDone = FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }); + + yield new Promise(resolve => gMockWindow.setTimeout(resolve, 120)); + Assert.ok(FinderIterator.running, "We ought to be running here"); + + let count2 = 0; + let whenDone2 = FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count2; } }, + word: findText + }); + + // Let the iterator run for a little while longer before we assert the world. + yield new Promise(resolve => gMockWindow.setTimeout(resolve, 10)); + FinderIterator.stop(); + + Assert.ok(!FinderIterator.running, "Stop means stop"); + + yield whenDone; + yield whenDone2; + + Assert.greater(count, FinderIterator.kIterationSizeMax, "At least one range should've been found"); + Assert.less(count, rangeCount, "Not all ranges should've been found"); + Assert.greater(count2, FinderIterator.kIterationSizeMax, "At least one range should've been found"); + Assert.less(count2, rangeCount, "Not all ranges should've been found"); + + Assert.equal(count2, count, "The second start was later, but should have caught up"); + + FinderIterator.reset(); +}); + +add_task(function* test_allowDistance() { + let findText = "gup"; + let rangeCount = 20; + prepareIterator(findText, rangeCount); + + // Start off the iterator. + let count = 0; + let whenDone = FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count; } }, + word: findText + }); + + let count2 = 0; + let whenDone2 = FinderIterator.start({ + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count2; } }, + word: "gu" + }); + + let count3 = 0; + let whenDone3 = FinderIterator.start({ + allowDistance: 1, + caseSensitive: false, + entireWord: false, + finder: gMockFinder, + listener: { onIteratorRangeFound(range) { ++count3; } }, + word: "gu" + }); + + yield Promise.all([whenDone, whenDone2, whenDone3]); + + Assert.equal(count, rangeCount, "The first iterator invocation should yield all results"); + Assert.equal(count2, 0, "The second iterator invocation should yield _no_ results"); + Assert.equal(count3, rangeCount, "The first iterator invocation should yield all results"); + + FinderIterator.reset(); +}); |