gecko-dev/browser/components/urlbar/tests/unit/test_providersManager_maxResults.js
Drew Willcoxon 81609255b5 Bug 1713322 - Properly fill flex groups and add support for both availableSpan and maxResultCount. r=mak
The problem in this bug is that the sum of the available spans of child buckets
is not necessarily equal to the available span of the parent bucket. That's
because each child span must be an integer, but a child's ideal span may not be
an integer, so we have to round and an error can accumulate.

This fixes it by detecting that case and then tweaking child spans until their
sum is equal to the parent's available span. If the sum is smaller than the
parent span, then we increment child spans until it's equal; if the sum is
larger than the parent span, then we decrement instead. (The case where the sum
is larger isn't as much of a problem as when it's smaller. We still correctly
limit the total result span due to logic elsewhere, but the bucket's final
result composition may not reflect flex ratios as accurately as it could.)

I added some logic so that the child spans we choose to tweak are the ones that
minimize the mathematical error between the final integer spans and the ideal
unrounded spans. In other words, we pick the best spans possible given that they
must be integers.

We need to do this tweaking when we try to overfill buckets too, not only on the
first pass for a bucket. Currently the second pass is hardcoded in
`_fillBuckets`. Rather than hardcoding the tweaking in both places, I added an
`_updateFlexData` helper method. While I was doing that, I realized we may need
more than two passes per parent bucket in order to optimally fill the children.
So I modified `_fillBuckets` so it recurses with the parent bucket itself when
we need to overfill any of its children.

I also added support for both `availableSpan` and `maxResultCount`. That lets us
get rid of the ugly heuristic special case in `_addResults`. A bucket will be
filled while both its used span and result count are under both these limits.

This also removes support for zero flex. I got really annoyed with it while I
was working on earlier versions of this. It made the code unnecessarily complex.
I added zero flex kind of as a hack to support tail suggestions, but we don't
actually need it at all. We can just move the tail suggestions bucket out of the
main suggestions bucket with form history and remote suggestions.

Finally while I was here I switched from "bucket" to "group" in light of the
renaming in bug 1715484 and bug 1715822.

Differential Revision: https://phabricator.services.mozilla.com/D117582
2021-06-18 00:08:25 +00:00

37 lines
1.1 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_maxResults() {
const MATCHES_LENGTH = 20;
let matches = [];
for (let i = 0; i < MATCHES_LENGTH; i++) {
matches.push(
new UrlbarResult(
UrlbarUtils.RESULT_TYPE.TAB_SWITCH,
UrlbarUtils.RESULT_SOURCE.TABS,
{ url: `http://mozilla.org/foo/${i}` }
)
);
}
let provider = registerBasicTestProvider(matches);
let context = createContext(undefined, { providers: [provider.name] });
let controller = UrlbarTestUtils.newMockController();
async function test_count(count) {
let promise = promiseControllerNotification(controller, "onQueryFinished");
context.maxResults = count;
await controller.startQuery(context);
await promise;
Assert.equal(
context.results.length,
Math.min(MATCHES_LENGTH, count),
"Check count"
);
Assert.deepEqual(context.results, matches.slice(0, count), "Check results");
}
await test_count(10);
await test_count(1);
await test_count(30);
});