зеркало из https://github.com/mozilla/pjs.git
Bug 460119 - Convert autocomplete feedback increase to an async query, r=dietrich
This commit is contained in:
Родитель
864227e3f3
Коммит
79ee175539
|
@ -78,6 +78,7 @@
|
|||
#include "nsNavBookmarks.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsILivemarkService.h"
|
||||
#include "mozIStoragePendingStatement.h"
|
||||
|
||||
#define NS_AUTOCOMPLETESIMPLERESULT_CONTRACTID \
|
||||
"@mozilla.org/autocomplete/simple-result;1"
|
||||
|
@ -1155,7 +1156,9 @@ nsNavHistory::AutoCompleteFeedback(PRInt32 aIndex,
|
|||
rv = stmt->BindStringParameter(1, url);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmt->Execute();
|
||||
// We do the update async and we don't care about failures
|
||||
nsCOMPtr<mozIStoragePendingStatement> canceler;
|
||||
rv = stmt->ExecuteAsync(nsnull, getter_AddRefs(canceler));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -53,7 +53,22 @@
|
|||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
let current_test = 0;
|
||||
|
||||
// Wait for a maximum of MAX_POLLING_TIMEOUT milliseconds before timing out
|
||||
// while polling database.
|
||||
// Since feedback increase is done async we must wait that the async statement
|
||||
// gets executed, so we have to poll the database until data is consistent.
|
||||
const MAX_POLLING_TIMEOUT = 3000;
|
||||
|
||||
// Get services
|
||||
let histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
let db = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection;
|
||||
let bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory);
|
||||
let obs = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
|
||||
function AutoCompleteInput(aSearches) {
|
||||
this.searches = aSearches;
|
||||
|
@ -106,6 +121,9 @@ AutoCompleteInput.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that autocomplete results are ordered correctly
|
||||
*/
|
||||
function ensure_results(uris, searchTerm)
|
||||
{
|
||||
let controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
|
@ -117,9 +135,6 @@ function ensure_results(uris, searchTerm)
|
|||
|
||||
controller.input = input;
|
||||
|
||||
// Search is asynchronous, so don't let the test finish immediately
|
||||
do_test_pending();
|
||||
|
||||
input.onSearchComplete = function() {
|
||||
do_check_eq(controller.searchStatus,
|
||||
Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
|
||||
|
@ -128,28 +143,22 @@ function ensure_results(uris, searchTerm)
|
|||
do_check_eq(controller.getValueAt(i), uris[i].spec);
|
||||
}
|
||||
|
||||
// start the next test or finish testing if no more tests are available
|
||||
if (current_test < (tests.length - 1)) {
|
||||
current_test++;
|
||||
tests[current_test]();
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
else
|
||||
do_test_finished();
|
||||
};
|
||||
|
||||
controller.startSearch(searchTerm);
|
||||
}
|
||||
|
||||
// Get history service
|
||||
try {
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory);
|
||||
var obs = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
} catch(ex) {
|
||||
do_throw("Could not get history service\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Bump up the rank for an uri, returning the expected use_count value, we will
|
||||
* use this value to poll database.
|
||||
*/
|
||||
function setCountRank(aURI, aCount, aRank, aSearch)
|
||||
{
|
||||
// Bump up the visit count for the uri
|
||||
|
@ -169,9 +178,16 @@ function setCountRank(aURI, aCount, aRank, aSearch)
|
|||
searchString: aSearch
|
||||
};
|
||||
|
||||
// Bump up the instrumentation feedback
|
||||
for (let i = 0; i < aRank; i++)
|
||||
|
||||
// Bump up the instrumentation feedback, calculating the target use_count
|
||||
// we will reach after all updates
|
||||
let targetUseCount = 0;
|
||||
for (let i = 0; i < aRank; i++) {
|
||||
obs.notifyObservers(thing, "autocomplete-will-enter-text", null);
|
||||
targetUseCount = (targetUseCount * 0.9) + 1;
|
||||
}
|
||||
|
||||
return Math.floor(targetUseCount);
|
||||
}
|
||||
|
||||
let uri1 = uri("http://site.tld/1");
|
||||
|
@ -187,84 +203,157 @@ let s0 = "";
|
|||
let s1 = "si";
|
||||
let s2 = "site";
|
||||
|
||||
let curTestItem1 = null;
|
||||
let curTestItem2 = null;
|
||||
|
||||
let pollTime = Date.now();
|
||||
let stmt = db.createStatement(
|
||||
"SELECT use_count " +
|
||||
"FROM moz_inputhistory " +
|
||||
"WHERE input = ?1 AND place_id = " +
|
||||
"(SELECT IFNULL((SELECT id FROM moz_places_temp WHERE url = ?2), " +
|
||||
"(SELECT id FROM moz_places WHERE url = ?2)))");
|
||||
|
||||
/**
|
||||
* Feedback increase is done async, this function ensures that all data have
|
||||
* been written before checking the results.
|
||||
*/
|
||||
function poll_database(aSearch) {
|
||||
if (Date.now() - pollTime > MAX_POLLING_TIMEOUT)
|
||||
do_throw("*** TIMEOUT ***: The test timed out while polling database.\n");
|
||||
stmt.bindUTF8StringParameter(0, curTestItem1.input);
|
||||
stmt.bindUTF8StringParameter(1, curTestItem1.uri.spec);
|
||||
if (!stmt.executeStep()) {
|
||||
stmt.reset();
|
||||
do_timeout(100, "poll_database('" + aSearch + "');");
|
||||
return;
|
||||
}
|
||||
let useCount1 = stmt.getInt64(0);
|
||||
stmt.reset();
|
||||
stmt.bindUTF8StringParameter(0, curTestItem2.input);
|
||||
stmt.bindUTF8StringParameter(1, curTestItem2.uri.spec);
|
||||
if (!stmt.executeStep()) {
|
||||
stmt.reset();
|
||||
do_timeout(100, "poll_database('" + aSearch + "');");
|
||||
return;
|
||||
}
|
||||
let useCount2 = stmt.getInt64(0);
|
||||
stmt.reset();
|
||||
if (useCount1 == curTestItem1.useCount && useCount2 == curTestItem2.useCount) {
|
||||
// All data has been written, so we can check results
|
||||
ensure_results([curTestItem1.uri, curTestItem2.uri], aSearch);
|
||||
}
|
||||
else {
|
||||
// Some data is missing, poll again after 100ms
|
||||
do_timeout(100, "poll_database('" + aSearch + "');");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up database for next test
|
||||
*/
|
||||
function prepTest(name) {
|
||||
print("Test " + name);
|
||||
pollTime = Date.now();
|
||||
bhist.removeAllPages();
|
||||
}
|
||||
|
||||
let current_test = 0;
|
||||
|
||||
let tests = [
|
||||
// Test things without a search term
|
||||
function() {
|
||||
prepTest("0 same count, diff rank, same term; no search");
|
||||
setCountRank(uri1, c1, c1, s2);
|
||||
setCountRank(uri2, c1, c2, s2);
|
||||
ensure_results([uri1, uri2], s0);
|
||||
let uc1 = setCountRank(uri1, c1, c1, s2);
|
||||
let uc2 = setCountRank(uri2, c1, c2, s2);
|
||||
curTestItem1 = { uri: uri1, input: s2, useCount: uc1 };
|
||||
curTestItem2 = { uri: uri2, input: s2, useCount: uc2 };
|
||||
do_timeout(100, "poll_database('" + s0 + "');");
|
||||
},
|
||||
function() {
|
||||
prepTest("1 same count, diff rank, same term; no search");
|
||||
setCountRank(uri1, c1, c2, s2);
|
||||
setCountRank(uri2, c1, c1, s2);
|
||||
ensure_results([uri2, uri1], s0);
|
||||
let uc1 = setCountRank(uri1, c1, c2, s2);
|
||||
let uc2 = setCountRank(uri2, c1, c1, s2);
|
||||
curTestItem2 = {uri: uri1, input: s2, useCount: uc1};
|
||||
curTestItem1 = {uri: uri2, input: s2, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s0 + "');");
|
||||
},
|
||||
function() {
|
||||
prepTest("2 diff count, same rank, same term; no search");
|
||||
setCountRank(uri1, c1, c1, s2);
|
||||
setCountRank(uri2, c2, c1, s2);
|
||||
ensure_results([uri1, uri2], s0);
|
||||
let uc1 = setCountRank(uri1, c1, c1, s2);
|
||||
let uc2 = setCountRank(uri2, c2, c1, s2);
|
||||
curTestItem1 = {uri: uri1, input: s2, useCount: uc1};
|
||||
curTestItem2 = {uri: uri2, input: s2, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s0 + "');");
|
||||
},
|
||||
function() {
|
||||
prepTest("3 diff count, same rank, same term; no search");
|
||||
setCountRank(uri1, c2, c1, s2);
|
||||
setCountRank(uri2, c1, c1, s2);
|
||||
ensure_results([uri2, uri1], s0);
|
||||
let uc1 = setCountRank(uri1, c2, c1, s2);
|
||||
let uc2 = setCountRank(uri2, c1, c1, s2);
|
||||
curTestItem2 = {uri: uri1, input: s2, useCount: uc1};
|
||||
curTestItem1 = {uri: uri2, input: s2, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s0 + "');");
|
||||
},
|
||||
|
||||
// Test things with a search term (exact match one, partial other)
|
||||
function() {
|
||||
prepTest("4 same count, same rank, diff term; one exact/one partial search");
|
||||
setCountRank(uri1, c1, c1, s1);
|
||||
setCountRank(uri2, c1, c1, s2);
|
||||
ensure_results([uri1, uri2], s1);
|
||||
let uc1 = setCountRank(uri1, c1, c1, s1);
|
||||
let uc2 = setCountRank(uri2, c1, c1, s2);
|
||||
curTestItem1 = {uri: uri1, input: s1, useCount: uc1};
|
||||
curTestItem2 = {uri: uri2, input: s2, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s1 + "');");
|
||||
},
|
||||
function() {
|
||||
prepTest("5 same count, same rank, diff term; one exact/one partial search");
|
||||
setCountRank(uri1, c1, c1, s2);
|
||||
setCountRank(uri2, c1, c1, s1);
|
||||
ensure_results([uri2, uri1], s1);
|
||||
let uc1 = setCountRank(uri1, c1, c1, s2);
|
||||
let uc2 = setCountRank(uri2, c1, c1, s1);
|
||||
curTestItem2 = {uri: uri1, input: s2, useCount: uc1};
|
||||
curTestItem1 = {uri: uri2, input: s1, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s1 + "');");
|
||||
},
|
||||
|
||||
// Test things with a search term (exact match both)
|
||||
function() {
|
||||
prepTest("6 same count, diff rank, same term; both exact search");
|
||||
setCountRank(uri1, c1, c1, s1);
|
||||
setCountRank(uri2, c1, c2, s1);
|
||||
ensure_results([uri1, uri2], s1);
|
||||
let uc1 = setCountRank(uri1, c1, c1, s1);
|
||||
let uc2 = setCountRank(uri2, c1, c2, s1);
|
||||
curTestItem1 = {uri: uri1, input: s1, useCount: uc1};
|
||||
curTestItem2 = {uri: uri2, input: s1, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s1 + "');");
|
||||
},
|
||||
function() {
|
||||
prepTest("7 same count, diff rank, same term; both exact search");
|
||||
setCountRank(uri1, c1, c2, s1);
|
||||
setCountRank(uri2, c1, c1, s1);
|
||||
ensure_results([uri2, uri1], s1);
|
||||
let uc1 = setCountRank(uri1, c1, c2, s1);
|
||||
let uc2 = setCountRank(uri2, c1, c1, s1);
|
||||
curTestItem2 = {uri: uri1, input: s1, useCount: uc1};
|
||||
curTestItem1 = {uri: uri2, input: s1, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s1 + "');");
|
||||
},
|
||||
|
||||
// Test things with a search term (partial match both)
|
||||
function() {
|
||||
prepTest("8 same count, diff rank, same term; both partial search");
|
||||
setCountRank(uri1, c1, c1, s2);
|
||||
setCountRank(uri2, c1, c2, s2);
|
||||
ensure_results([uri1, uri2], s1);
|
||||
let uc1 = setCountRank(uri1, c1, c1, s2);
|
||||
let uc2 = setCountRank(uri2, c1, c2, s2);
|
||||
curTestItem1 = {uri: uri1, input: s2, useCount: uc1};
|
||||
curTestItem2 = {uri: uri2, input: s2, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s1 + "');");
|
||||
},
|
||||
function() {
|
||||
prepTest("9 same count, diff rank, same term; both partial search");
|
||||
setCountRank(uri1, c1, c2, s2);
|
||||
setCountRank(uri2, c1, c1, s2);
|
||||
ensure_results([uri2, uri1], s1);
|
||||
},
|
||||
let uc1 = setCountRank(uri1, c1, c2, s2);
|
||||
let uc2 = setCountRank(uri2, c1, c1, s2);
|
||||
curTestItem2 = {uri: uri1, input: s2, useCount: uc1};
|
||||
curTestItem1 = {uri: uri2, input: s2, useCount: uc2};
|
||||
do_timeout(100, "poll_database('" + s1 + "');");
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* Test history autocomplete
|
||||
* Test adapative autocomplete
|
||||
*/
|
||||
function run_test() {
|
||||
tests[0]();
|
||||
do_test_pending();
|
||||
tests[current_test]();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче