Bug 993372 - Part 2 - Port autocomplete tests to unified autocomplete. r=mano
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 18 Jul 2014 09:42:35 +0200
changeset 216820 b16a100a246f0f1f267f89f8b1575e09c444fa0e
parent 216819 93d6fa42ff9f7759bf8e67449c607778c0ba6dd3
child 216821 52769d6fc58aba4ae16ba6ee88bbb54a202ae859
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmano
bugs993372
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 993372 - Part 2 - Port autocomplete tests to unified autocomplete. r=mano
toolkit/components/places/UnifiedComplete.js
toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js
toolkit/components/places/tests/unifiedcomplete/test_416211.js
toolkit/components/places/tests/unifiedcomplete/test_416214.js
toolkit/components/places/tests/unifiedcomplete/test_417798.js
toolkit/components/places/tests/unifiedcomplete/test_418257.js
toolkit/components/places/tests/unifiedcomplete/test_422277.js
toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js
toolkit/components/places/tests/unifiedcomplete/test_autocomplete_on_value_removed_479089.js
toolkit/components/places/tests/unifiedcomplete/test_download_embed_bookmarks.js
toolkit/components/places/tests/unifiedcomplete/test_empty_search.js
toolkit/components/places/tests/unifiedcomplete/test_enabled.js
toolkit/components/places/tests/unifiedcomplete/test_escape_self.js
toolkit/components/places/tests/unifiedcomplete/test_ignore_protocol.js
toolkit/components/places/tests/unifiedcomplete/test_keyword_search.js
toolkit/components/places/tests/unifiedcomplete/test_keywords.js
toolkit/components/places/tests/unifiedcomplete/test_match_beginning.js
toolkit/components/places/tests/unifiedcomplete/test_multi_word_search.js
toolkit/components/places/tests/unifiedcomplete/test_special_search.js
toolkit/components/places/tests/unifiedcomplete/test_swap_protocol.js
toolkit/components/places/tests/unifiedcomplete/test_tabmatches.js
toolkit/components/places/tests/unifiedcomplete/test_word_boundary_search.js
toolkit/components/places/tests/unifiedcomplete/xpcshell.ini
--- a/toolkit/components/places/UnifiedComplete.js
+++ b/toolkit/components/places/UnifiedComplete.js
@@ -86,17 +86,17 @@ const QUERYINDEX_FRECENCY      = 11;
 //   - whether the entry is bookmarked (QUERYINDEX_BOOKMARKED)
 //   - the bookmark title, if it is a bookmark (QUERYINDEX_BOOKMARKTITLE)
 //   - the tags associated with a bookmarked entry (QUERYINDEX_TAGS)
 const SQL_BOOKMARK_TAGS_FRAGMENT = sql(
   "EXISTS(SELECT 1 FROM moz_bookmarks WHERE fk = h.id) AS bookmarked,",
   "( SELECT title FROM moz_bookmarks WHERE fk = h.id AND title NOTNULL",
     "ORDER BY lastModified DESC LIMIT 1",
   ") AS btitle,",
-  "( SELECT GROUP_CONCAT(t.title, ',')",
+  "( SELECT GROUP_CONCAT(t.title, ', ')",
     "FROM moz_bookmarks b",
     "JOIN moz_bookmarks t ON t.id = +b.parent AND t.parent = :parent",
     "WHERE b.fk = h.id",
   ") AS tags");
 
 // TODO bug 412736: in case of a frecency tie, we might break it with h.typed
 // and h.visit_count.  That is slower though, so not doing it yet...
 const SQL_DEFAULT_QUERY = sql(
@@ -439,41 +439,42 @@ function stripPrefix(spec)
 //// Manages a single instance of an autocomplete search.
 
 function Search(searchString, searchParam, autocompleteListener,
                 resultListener, autocompleteSearch) {
   // We want to store the original string for case sensitive searches.
   this._originalSearchString = searchString;
   this._trimmedOriginalSearchString = searchString.trim();
   this._searchString = fixupSearchText(this._trimmedOriginalSearchString.toLowerCase());
+
+  this._matchBehavior = Prefs.matchBehavior;
+  // Set the default behavior for this search.
+  this._behavior = this._searchString ? Prefs.defaultBehavior
+                                      : Prefs.emptySearchDefaultBehavior;
+  this._enableActions = searchParam.split(" ").indexOf("enable-actions") != -1;
+
   this._searchTokens =
     this.filterTokens(getUnfilteredSearchTokens(this._searchString));
   // The protocol and the host are lowercased by nsIURI, so it's fine to
   // lowercase the typed prefix, to add it back to the results later.
   this._strippedPrefix = this._trimmedOriginalSearchString.slice(
     0, this._trimmedOriginalSearchString.length - this._searchString.length
   ).toLowerCase();
   // The URIs in the database are fixed-up, so we can match on a lowercased
   // host, but the path must be matched in a case sensitive way.
   let pathIndex =
     this._trimmedOriginalSearchString.indexOf("/", this._strippedPrefix.length);
   this._autofillUrlSearchString = fixupSearchText(
     this._trimmedOriginalSearchString.slice(0, pathIndex).toLowerCase() +
     this._trimmedOriginalSearchString.slice(pathIndex)
   );
 
-  this._enableActions = searchParam.split(" ").indexOf("enable-actions") != -1;
-
   this._listener = autocompleteListener;
   this._autocompleteSearch = autocompleteSearch;
 
-  this._matchBehavior = Prefs.matchBehavior;
-  // Set the default behavior for this search.
-  this._behavior = this._searchString ? Prefs.defaultBehavior
-                                      : Prefs.emptySearchDefaultBehavior;
   // Create a new result to add eventual matches.  Note we need a result
   // regardless having matches.
   let result = Cc["@mozilla.org/autocomplete/simple-result;1"]
                  .createInstance(Ci.nsIAutoCompleteSimpleResult);
   result.setSearchString(searchString);
   result.setListener(resultListener);
   // Will be set later, if needed.
   result.setDefaultIndex(-1);
@@ -592,20 +593,21 @@ Search.prototype = {
     // (3) only gets ran if we get any filtered tokens, since if there are no
     // tokens, there is nothing to match.
 
     // Get the final query, based on the tokens found in the search string.
     let queries = [ this._adaptiveQuery,
                     this._switchToTabQuery,
                     this._searchQuery ];
 
-    if (this._searchTokens.length == 1) {
+    if (this._searchTokens.length > 0 &&
+        PlacesUtils.bookmarks.getURIForKeyword(this._searchTokens[0])) {
+      queries.unshift(this._keywordQuery);
+    } else if (this._searchTokens.length == 1) {
       yield this._matchPriorityUrl();
-    } else if (this._searchTokens.length > 1) {
-      queries.unshift(this._keywordQuery);
     }
 
     if (this._shouldAutofill) {
       // Hosts have no "/" in them.
       let lastSlashIndex = this._searchString.lastIndexOf("/");
       // Search only URLs if there's a slash in the search string...
       if (lastSlashIndex != -1) {
         // ...but not if it's exactly at the end of the search string.
@@ -633,17 +635,17 @@ Search.prototype = {
     // If we do not have enough results, and our match type is
     // MATCH_BOUNDARY_ANYWHERE, search again with MATCH_ANYWHERE to get more
     // results.
     if (this._matchBehavior == MATCH_BOUNDARY_ANYWHERE &&
         this._result.matchCount < Prefs.maxRichResults) {
       this._matchBehavior = MATCH_ANYWHERE;
       for (let [query, params] of [ this._adaptiveQuery,
                                     this._searchQuery ]) {
-        yield conn.executeCached(query, params, this._onResultRow);
+        yield conn.executeCached(query, params, this._onResultRow.bind(this));
         if (!this.pending)
           return;
       }
     }
 
     // If we didn't find enough matches and we have some frecency-driven
     // matches, add them.
     if (this._frecencyMatches) {
@@ -710,26 +712,26 @@ Search.prototype = {
         if (this._frecencyMatches[i].frecency > match.frecency) {
           this._addMatch(this._frecencyMatches.splice(i, 1)[0]);
         }
       }
     }
 
     // Must check both id and url, cause keywords dinamically modify the url.
     if ((!match.placeId || !this._usedPlaceIds.has(match.placeId)) &&
-        !this._usedURLs.has(stripPrefix(match.value))) {
+        !this._usedURLs.has(match.value)) {
       // Add this to our internal tracker to ensure duplicates do not end up in
       // the result.
       // Not all entries have a place id, thus we fallback to the url for them.
       // We cannot use only the url since keywords entries are modified to
       // include the search string, and would be returned multiple times.  Ids
       // are faster too.
       if (match.placeId)
         this._usedPlaceIds.add(match.placeId);
-      this._usedURLs.add(stripPrefix(match.value));
+      this._usedURLs.add(match.value);
 
       this._result.appendMatch(match.value,
                                match.comment,
                                match.icon || PlacesUtils.favicons.defaultFavicon.spec,
                                match.style || "favicon",
                                match.finalCompleteValue);
       notifyResults = true;
     }
--- a/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js
+++ b/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js
@@ -96,16 +96,19 @@ function* check_autocomplete(test) {
   // This is not a problem in real life, but autocomplete tests should
   // return reliable resultsets, thus we have to wait.
   yield promiseAsyncUpdates();
 
   // Make an AutoCompleteInput that uses our searches and confirms results.
   let input = new AutoCompleteInput(["unifiedcomplete"]);
   input.textValue = test.search;
 
+  if (test.searchParam)
+    input.searchParam = test.searchParam;
+
   // Caret must be at the end for autoFill to happen.
   let strLen = test.search.length;
   input.selectTextRange(strLen, strLen);
   Assert.equal(input.selectionStart, strLen, "Selection starts at end");
   Assert.equal(input.selectionEnd, strLen, "Selection ends at the end");
 
   let controller = Cc["@mozilla.org/autocomplete/controller;1"]
                      .getService(Ci.nsIAutoCompleteController);
@@ -124,33 +127,118 @@ function* check_autocomplete(test) {
 
   do_log_info("Searching for: '" + test.search + "'");
   controller.startSearch(test.search);
   yield deferred.promise;
 
   // We should be running only one query.
   Assert.equal(numSearchesStarted, 1, "Only one search started");
 
-  // Check the autoFilled result.
-  Assert.equal(input.textValue, test.autofilled,
-               "Autofilled value is correct");
+  // Check to see the expected uris and titles match up (in any order)
+  if (test.matches) {
+    for (let i = 0; i < controller.matchCount; i++) {
+      let value = controller.getValueAt(i);
+      let comment = controller.getCommentAt(i);
+      do_log_info("Looking for '" + value + "', '" + comment + "' in expected results...");
+      let j;
+      for (j = 0; j < test.matches.length; j++) {
+        // Skip processed expected results
+        if (test.matches[j] == undefined)
+          continue;
+
+        let { uri, title, tags } = test.matches[j];
+        if (tags)
+          title += " \u2013 " + tags.sort().join(", ");
+
+        do_log_info("Checking against expected '" + uri.spec + "', '" + title + "'...");
+        // Got a match on both uri and title?
+        if (uri.spec == value && title == comment) {
+          do_log_info("Got a match at index " + j + "!");
+          // Make it undefined so we don't process it again
+          test.matches[j] = undefined;
+          break;
+        }
+      }
 
-  // Now force completion and check correct casing of the result.
-  // This ensures the controller is able to do its magic case-preserving
-  // stuff and correct replacement of the user's casing with result's one.
-  controller.handleEnter(false);
-  Assert.equal(input.textValue, test.completed,
-               "Completed value is correct");
+      // We didn't hit the break, so we must have not found it
+      if (j == test.matches.length)
+        do_throw("Didn't find the current result ('" + value + "', '" + comment + "') in matches");
+    }
+
+    Assert.equal(controller.matchCount, test.matches.length,
+                 "Got as many results as expected");
+
+    // If we expect results, make sure we got matches.
+    do_check_eq(controller.searchStatus, test.matches.length ?
+                Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH :
+                Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
+  }
+
+  if (test.autofilled) {
+    // Check the autoFilled result.
+    Assert.equal(input.textValue, test.autofilled,
+                 "Autofilled value is correct");
+
+    // Now force completion and check correct casing of the result.
+    // This ensures the controller is able to do its magic case-preserving
+    // stuff and correct replacement of the user's casing with result's one.
+    controller.handleEnter(false);
+    Assert.equal(input.textValue, test.completed,
+                 "Completed value is correct");
+  }
 }
 
 function addBookmark(aBookmarkObj) {
-  Assert.ok(!!aBookmarkObj.url, "Bookmark object contains an url");
+  Assert.ok(!!aBookmarkObj.uri, "Bookmark object contains an uri");
   let parentId = aBookmarkObj.parentId ? aBookmarkObj.parentId
                                        : PlacesUtils.unfiledBookmarksFolderId;
   let itemId = PlacesUtils.bookmarks
                           .insertBookmark(parentId,
-                                          NetUtil.newURI(aBookmarkObj.url),
+                                          aBookmarkObj.uri,
                                           PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                          "A bookmark");
+                                          aBookmarkObj.title || "A bookmark");
   if (aBookmarkObj.keyword) {
     PlacesUtils.bookmarks.setKeywordForBookmark(itemId, aBookmarkObj.keyword);
   }
+
+  if (aBookmarkObj.tags) {
+    PlacesUtils.tagging.tagURI(aBookmarkObj.uri, aBookmarkObj.tags);
+  }
 }
+
+function addOpenPages(aUri, aCount=1) {
+  let ac = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
+             .getService(Ci.mozIPlacesAutoComplete);
+  for (let i = 0; i < aCount; i++) {
+    ac.registerOpenPage(aUri);
+  }
+}
+
+function removeOpenPages(aUri, aCount=1) {
+  let ac = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
+             .getService(Ci.mozIPlacesAutoComplete);
+  for (let i = 0; i < aCount; i++) {
+    ac.unregisterOpenPage(aUri);
+  }
+}
+
+function changeRestrict(aType, aChar) {
+  let branch = "browser.urlbar.";
+  // "title" and "url" are different from everything else, so special case them.
+  if (aType == "title" || aType == "url")
+    branch += "match.";
+  else
+    branch += "restrict.";
+
+  do_log_info("changing restrict for " + aType + " to '" + aChar + "'");
+  Services.prefs.setCharPref(branch + aType, aChar);
+}
+
+function resetRestrict(aType) {
+  let branch = "browser.urlbar.";
+  // "title" and "url" are different from everything else, so special case them.
+  if (aType == "title" || aType == "url")
+    branch += "match.";
+  else
+    branch += "restrict.";
+
+  Services.prefs.clearUserPref(branch + aType);
+}
copy from toolkit/components/places/tests/autocomplete/test_416211.js
copy to toolkit/components/places/tests/unifiedcomplete/test_416211.js
--- a/toolkit/components/places/tests/autocomplete/test_416211.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_416211.js
@@ -2,29 +2,21 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Test bug 416211 to make sure results that match the tag show the bookmark
  * title instead of the page title.
  */
 
-let theTag = "superTag";
-
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://theuri/",
-];
-let kTitles = [
-  "Page title",
-  "Bookmark title",
-  theTag,
-];
-
-// Add page with a title, bookmark, and [tags]
-addPageBook(0, 0, 1, [2]);
-
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Make sure the tag match gives the bookmark title",
-   theTag, [0]],
-];
+add_task(function* test_tag_match_has_bookmark_title() {
+  do_log_info("Make sure the tag match gives the bookmark title");
+  let uri = NetUtil.newURI("http://theuri/");
+  yield promiseAddVisits({ uri: uri, title: "Page title" });
+  addBookmark({ uri: uri,
+                title: "Bookmark title",
+                tags: [ "superTag" ]});
+  yield check_autocomplete({
+    search: "superTag",
+    matches: [ { uri: uri, title: "Bookmark title", tags: [ "superTag" ] } ]
+  });
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_416214.js
copy to toolkit/components/places/tests/unifiedcomplete/test_416214.js
--- a/toolkit/components/places/tests/autocomplete/test_416214.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_416214.js
@@ -9,30 +9,27 @@
  *
  * - add a visit for a page with a non-English URL
  * - add a tag for the page
  * - search for the tag
  * - test number of matches (should be exactly one)
  * - make sure the url is decoded
  */
 
-let theTag = "superTag";
-
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://escaped/ユニコード",
-  "http://asciiescaped/blocking-firefox3%2B",
-];
-let kTitles = [
-  "title",
-  theTag,
-];
-
-// Add pages that match the tag
-addPageBook(0, 0, 0, [1]);
-addPageBook(1, 0, 0, [1]);
-
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Make sure tag matches return the right url as well as '+' remain escaped",
-   theTag, [0,1]],
-];
+add_task(function* test_tag_match_url() {
+  do_log_info("Make sure tag matches return the right url as well as '+' remain escaped");
+  let uri1 = NetUtil.newURI("http://escaped/ユニコード");
+  let uri2 = NetUtil.newURI("http://asciiescaped/blocking-firefox3%2B");
+  yield promiseAddVisits([ { uri: uri1, title: "title" },
+  						   { uri: uri2, title: "title" } ]);
+  addBookmark({ uri: uri1,
+                title: "title",
+                tags: [ "superTag" ]});
+  addBookmark({ uri: uri2,
+                title: "title",
+                tags: [ "superTag" ]});
+  yield check_autocomplete({
+    search: "superTag",
+    matches: [ { uri: uri1, title: "title", tags: [ "superTag" ] },
+     		   { uri: uri2, title: "title", tags: [ "superTag" ] } ]
+  });
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_417798.js
copy to toolkit/components/places/tests/unifiedcomplete/test_417798.js
--- a/toolkit/components/places/tests/autocomplete/test_417798.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_417798.js
@@ -2,35 +2,48 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test for bug 417798 to make sure javascript: URIs don't show up unless the
  * user searches for javascript: explicitly.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://abc/def",
-  "javascript:5",
-];
-let kTitles = [
-  "Title with javascript:",
-];
+add_task(function* test_javascript_match() {
+  let uri1 = NetUtil.newURI("http://abc/def");
+  let uri2 = NetUtil.newURI("javascript:5");
+  yield promiseAddVisits([ { uri: uri1, title: "Title with javascript:" } ]);
+  addBookmark({ uri: uri2,
+                title: "Title with javascript:" });
 
-addPageBook(0, 0); // regular url
-// javascript: uri as bookmark (no visit)
-addPageBook(1, 0, 0, undefined, undefined, undefined, true);
+  do_log_info("Match non-javascript: with plain search");
+  yield check_autocomplete({
+    search: "a",
+    matches: [ { uri: uri1, title: "Title with javascript:" } ]
+  });
+
+  do_log_info("Match non-javascript: with almost javascript:");
+  yield check_autocomplete({
+    search: "javascript",
+    matches: [ { uri: uri1, title: "Title with javascript:" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Match non-javascript: with plain search",
-   "a", [0]],
-  ["1: Match non-javascript: with almost javascript:",
-   "javascript", [0]],
-  ["2: Match javascript:",
-   "javascript:", [0,1]],
-  ["3: Match nothing with non-first javascript:",
-   "5 javascript:", []],
-  ["4: Match javascript: with multi-word search",
-   "javascript: 5", [1]],
-];
+  do_log_info("Match javascript:");
+  yield check_autocomplete({
+    search: "javascript:",
+    matches: [ { uri: uri1, title: "Title with javascript:" },
+               { uri: uri2, title: "Title with javascript:" } ]
+  });
+
+  do_log_info("Match nothing with non-first javascript:");
+  yield check_autocomplete({
+    search: "5 javascript:",
+    matches: [ ]
+  });
+
+  do_log_info("Match javascript: with multi-word search");
+  yield check_autocomplete({
+    search: "javascript: 5",
+    matches: [ { uri: uri2, title: "Title with javascript:" } ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_418257.js
copy to toolkit/components/places/tests/unifiedcomplete/test_418257.js
--- a/toolkit/components/places/tests/autocomplete/test_418257.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_418257.js
@@ -3,41 +3,63 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test bug 418257 by making sure tags are returned with the title as part of
  * the "comment" if there are tags even if we didn't match in the tags. They
  * are separated from the title by a endash.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://page1",
-  "http://page2",
-  "http://page3",
-  "http://page4",
-];
-let kTitles = [
-  "tag1",
-  "tag2",
-  "tag3",
-];
+add_task(function* test_javascript_match() {
+  let uri1 = NetUtil.newURI("http://page1");
+  let uri2 = NetUtil.newURI("http://page2");
+  let uri3 = NetUtil.newURI("http://page3");
+  let uri4 = NetUtil.newURI("http://page4");
+  yield promiseAddVisits([ { uri: uri1, title: "tagged" },
+                           { uri: uri2, title: "tagged" },
+                           { uri: uri3, title: "tagged" },
+                           { uri: uri4, title: "tagged" } ]);
+  addBookmark({ uri: uri1,
+                title: "tagged",
+                tags: [ "tag1" ] });
+  addBookmark({ uri: uri2,
+                title: "tagged",
+                tags: [ "tag1", "tag2" ] });
+  addBookmark({ uri: uri3,
+                title: "tagged",
+                tags: [ "tag1", "tag3" ] });
+  addBookmark({ uri: uri4,
+                title: "tagged",
+                tags: [ "tag1", "tag2", "tag3" ] });
+
+  do_log_info("Make sure tags come back in the title when matching tags");
+  yield check_autocomplete({
+    search: "page1 tag",
+    matches: [ { uri: uri1, title: "tagged", tags: [ "tag1" ] } ]
+  });
 
-// Add pages with varying number of tags
-addPageBook(0, 0, 0, [0]);
-addPageBook(1, 0, 0, [0,1]);
-addPageBook(2, 0, 0, [0,2]);
-addPageBook(3, 0, 0, [0,1,2]);
+  do_log_info("Check tags in title for page2");
+  yield check_autocomplete({
+    search: "page2 tag",
+    matches: [ { uri: uri2, title: "tagged", tags: [ "tag1", "tag2" ] } ]
+  });
+
+  do_log_info("Make sure tags appear even when not matching the tag");
+  yield check_autocomplete({
+    search: "page3",
+    matches: [ { uri: uri3, title: "tagged", tags: [ "tag1", "tag3" ] } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Make sure tags come back in the title when matching tags",
-   "page1 tag", [0]],
-  ["1: Check tags in title for page2",
-   "page2 tag", [1]],
-  ["2: Make sure tags appear even when not matching the tag",
-   "page3", [2]],
-  ["3: Multiple tags come in commas for page4",
-   "page4", [3]],
-  ["4: Extra test just to make sure we match the title",
-   "tag2", [1,3]],
-];
+  do_log_info("Multiple tags come in commas for page4");
+  yield check_autocomplete({
+    search: "page4",
+    matches: [ { uri: uri4, title: "tagged", tags: [ "tag1", "tag2", "tag3" ] } ]
+  });
+
+  do_log_info("Extra test just to make sure we match the title");
+  yield check_autocomplete({
+    search: "tag2",
+    matches: [ { uri: uri2, title: "tagged", tags: [ "tag1", "tag2" ] },
+               { uri: uri4, title: "tagged", tags: [ "tag1", "tag2", "tag3" ] } ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_422277.js
copy to toolkit/components/places/tests/unifiedcomplete/test_422277.js
--- a/toolkit/components/places/tests/autocomplete/test_422277.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_422277.js
@@ -2,24 +2,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test bug 422277 to make sure bad escaped uris don't get escaped. This makes
  * sure we don't hit an assertion for "not a UTF8 string".
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://site/%EAid",
-];
-let kTitles = [
-  "title",
-];
-
-addPageBook(0, 0);
-
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Bad escaped uri stays escaped",
-   "site", [0]],
-];
+add_task(function* test_javascript_match() {
+  do_log_info("Bad escaped uri stays escaped");
+  let uri1 = NetUtil.newURI("http://site/%EAid");
+  yield promiseAddVisits([ { uri: uri1, title: "title" } ]);
+  yield check_autocomplete({
+    search: "site",
+    matches: [ { uri: uri1, title: "title" } ]
+  });
+  yield cleanup();
+});
--- a/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js
@@ -65,17 +65,17 @@ add_task(function* test_respect_www() {
     completed: "www.me.mozilla.org/"
   });
   yield cleanup();
 });
 
 add_task(function* test_bookmark_first() {
   do_log_info("With a bookmark and history, the query result should be the bookmark");
   Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
-  addBookmark({ url: "http://bookmark1.mozilla.org/", });
+  addBookmark({ uri: NetUtil.newURI("http://bookmark1.mozilla.org/") });
   yield promiseAddVisits(NetUtil.newURI("http://bookmark1.mozilla.org/foo"));
   yield check_autocomplete({
     search: "bookmark",
     autofilled: "bookmark1.mozilla.org/",
     completed: "bookmark1.mozilla.org/"
   });
   yield cleanup();
 });
copy from toolkit/components/places/tests/autocomplete/test_autocomplete_on_value_removed_479089.js
copy to toolkit/components/places/tests/unifiedcomplete/test_autocomplete_on_value_removed_479089.js
--- a/toolkit/components/places/tests/autocomplete/test_autocomplete_on_value_removed_479089.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_on_value_removed_479089.js
@@ -7,48 +7,33 @@
 /*
  * Need to test that removing a page from autocomplete actually removes a page
  * Description From  Shawn Wilsher :sdwilsh   2009-02-18 11:29:06 PST
  * We don't test the code path of onValueRemoved
  * for the autocomplete implementation
  * Bug 479089
  */
 
-var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
-getService(Ci.nsINavHistoryService);
-
-function run_test()
-{
-  run_next_test();
-}
-
-add_task(function test_autocomplete_on_value_removed()
-{
-  // QI to nsIAutoCompleteSimpleResultListener
-  var listener = Cc["@mozilla.org/autocomplete/search;1?name=history"].
+add_task(function* test_autocomplete_on_value_removed() {
+  let listener = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"].
                  getService(Components.interfaces.nsIAutoCompleteSimpleResultListener);
 
-  // add history visit
-  var testUri = uri("http://foo.mozilla.com/");
+  let testUri = NetUtil.newURI("http://foo.mozilla.com/");
   yield promiseAddVisits({
     uri: testUri,
     referrer: uri("http://mozilla.com/")
   });
-  // create a query object
-  var query = histsvc.getNewQuery();
-  // create the options object we will never use
-  var options = histsvc.getNewQueryOptions();
+
+  let query = PlacesUtils.history.getNewQuery();
+  let options = PlacesUtils.history.getNewQueryOptions();
   // look for this uri only
   query.uri = testUri;
-  // execute
-  var queryRes = histsvc.executeQuery(query, options);
-  // open the result container
-  queryRes.root.containerOpen = true;
-  // debug queries
-  // dump_table("moz_places");
-  do_check_eq(queryRes.root.childCount, 1);  
+
+  let root = PlacesUtils.history.executeQuery(query, options).root;
+  root.containerOpen = true;
+  Assert.equal(root.childCount, 1);
   // call the untested code path
   listener.onValueRemoved(null, testUri.spec, true);
   // make sure it is GONE from the DB
-  do_check_eq(queryRes.root.childCount, 0);
+  Assert.equal(root.childCount, 0);
   // close the container
-  queryRes.root.containerOpen = false;
+  root.containerOpen = false;
 });
copy from toolkit/components/places/tests/autocomplete/test_download_embed_bookmarks.js
copy to toolkit/components/places/tests/unifiedcomplete/test_download_embed_bookmarks.js
--- a/toolkit/components/places/tests/autocomplete/test_download_embed_bookmarks.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_download_embed_bookmarks.js
@@ -4,50 +4,72 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Tests bug 449406 to ensure that TRANSITION_DOWNLOAD, TRANSITION_EMBED and
  * TRANSITION_FRAMED_LINK bookmarked uri's show up in the location bar.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://download/bookmarked",
-  "http://embed/bookmarked",
-  "http://framed/bookmarked",
-  "http://download",
-  "http://embed",
-  "http://framed",
-];
-let kTitles = [
-  "download-bookmark",
-  "embed-bookmark",
-  "framed-bookmark",
-  "download2",
-  "embed2",
-  "framed2",
-];
+add_task(function* test_download_embed_bookmarks() {
+  let uri1 = NetUtil.newURI("http://download/bookmarked");
+  let uri2 = NetUtil.newURI("http://embed/bookmarked");
+  let uri3 = NetUtil.newURI("http://framed/bookmarked");
+  let uri4 = NetUtil.newURI("http://download");
+  let uri5 = NetUtil.newURI("http://embed");
+  let uri6 = NetUtil.newURI("http://framed");
+  yield promiseAddVisits([ { uri: uri1, title: "download-bookmark",
+                             transition: TRANSITION_DOWNLOAD },
+                           { uri: uri2, title: "embed-bookmark",
+                             transition: TRANSITION_EMBED },
+                           { uri: uri3, title: "framed-bookmark",
+                             transition: TRANSITION_FRAMED_LINK},
+                           { uri: uri4, title: "download2",
+                             transition: TRANSITION_DOWNLOAD },
+                           { uri: uri5, title: "embed2",
+                             transition: TRANSITION_EMBED },
+                           { uri: uri6, title: "framed2",
+                             transition: TRANSITION_FRAMED_LINK } ]);
+  addBookmark({ uri: uri1,
+                title: "download-bookmark" });
+  addBookmark({ uri: uri2,
+                title: "embed-bookmark" });
+  addBookmark({ uri: uri3,
+                title: "framed-bookmark" });
+
+  do_log_info("Searching for bookmarked download uri matches");
+  yield check_autocomplete({
+    search: "download-bookmark",
+    matches: [ { uri: uri1, title: "download-bookmark" } ]
+  });
 
-// Add download and embed uris
-addPageBook(0, 0, 0, undefined, undefined, TRANSITION_DOWNLOAD);
-addPageBook(1, 1, 1, undefined, undefined, TRANSITION_EMBED);
-addPageBook(2, 2, 2, undefined, undefined, TRANSITION_FRAMED_LINK);
-addPageBook(3, 3, undefined, undefined, undefined, TRANSITION_DOWNLOAD);
-addPageBook(4, 4, undefined, undefined, undefined, TRANSITION_EMBED);
-addPageBook(5, 5, undefined, undefined, undefined, TRANSITION_FRAMED_LINK);
+  do_log_info("Searching for bookmarked embed uri matches");
+  yield check_autocomplete({
+    search: "embed-bookmark",
+    matches: [ { uri: uri2, title: "embed-bookmark" } ]
+  });
+
+  do_log_info("Searching for bookmarked framed uri matches");
+  yield check_autocomplete({
+    search: "framed-bookmark",
+    matches: [ { uri: uri3, title: "framed-bookmark" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Searching for bookmarked download uri matches",
-   kTitles[0], [0]],
-  ["1: Searching for bookmarked embed uri matches",
-   kTitles[1], [1]],
-  ["2: Searching for bookmarked framed uri matches",
-   kTitles[2], [2]],
-  ["3: Searching for download uri does not match",
-   kTitles[3], []],
-  ["4: Searching for embed uri does not match",
-   kTitles[4], []],
-  ["5: Searching for framed uri does not match",
-   kTitles[5], []],
-];
+  do_log_info("Searching for download uri does not match");
+  yield check_autocomplete({
+    search: "download2",
+    matches: [ ]
+  });
+
+  do_log_info("Searching for embed uri does not match");
+  yield check_autocomplete({
+    search: "embed2",
+    matches: [ ]
+  });
+
+  do_log_info("Searching for framed uri does not match");
+  yield check_autocomplete({
+    search: "framed2",
+    matches: [ ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_empty_search.js
copy to toolkit/components/places/tests/unifiedcomplete/test_empty_search.js
--- a/toolkit/components/places/tests/autocomplete/test_empty_search.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_empty_search.js
@@ -2,62 +2,93 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test for bug 426864 that makes sure the empty search (drop down list) only
  * shows typed pages from history.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://foo/0",
-  "http://foo/1",
-  "http://foo/2",
-  "http://foo/3",
-  "http://foo/4",
-  "http://foo/5",
-];
-let kTitles = [
-  "title",
-];
+add_task(function* test_javascript_match() {
+  let uri1 = NetUtil.newURI("http://t.foo/0");
+  let uri2 = NetUtil.newURI("http://t.foo/1");
+  let uri3 = NetUtil.newURI("http://t.foo/2");
+  let uri4 = NetUtil.newURI("http://t.foo/3");
+  let uri5 = NetUtil.newURI("http://t.foo/4");
+  let uri6 = NetUtil.newURI("http://t.foo/5");
+
+  yield promiseAddVisits([ { uri: uri1, title: "title" },
+                           { uri: uri2, title: "title" },
+                           { uri: uri3, title: "title",
+                             transition: TRANSITION_TYPED},
+                           { uri: uri4, title: "title",
+                             transition: TRANSITION_TYPED },
+                           { uri: uri6, title: "title",
+                             transition: TRANSITION_TYPED } ]);
 
-// Visited (in history)
-addPageBook(0, 0); // history
-addPageBook(1, 0, 0); // bookmark
-addPageBook(2, 0); // history typed
-addPageBook(3, 0, 0); // bookmark typed
+  addBookmark({ uri: uri2,
+                title: "title" });
+  addBookmark({ uri: uri4,
+                title: "title" });
+  addBookmark({ uri: uri5,
+                title: "title" });
+  addBookmark({ uri: uri6,
+                title: "title" });
 
-// Unvisited bookmark
-addPageBook(4, 0, 0); // bookmark
-addPageBook(5, 0, 0); // bookmark typed
+  // Now remove page 6 from history, so it is an unvisited, typed bookmark.
+  PlacesUtils.history.removePage(uri6);
+
+  do_log_info("Match everything");
+  yield check_autocomplete({
+    search: "foo",
+    matches: [ { uri: uri1, title: "title" },
+               { uri: uri2, title: "title" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "title" },
+               { uri: uri5, title: "title" },
+               { uri: uri6, title: "title" } ]
+  });
 
-// Set some pages as typed
-markTyped([2,3,5], 0);
-// Remove pages from history to treat them as unvisited
-removePages([4,5]);
+  do_log_info("Match only typed history");
+  yield check_autocomplete({
+    search: "foo ^ ~",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "title" } ]
+  });
+
+  do_log_info("Drop-down empty search matches only typed history");
+  yield check_autocomplete({
+    search: "",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "title" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Match everything",
-   "foo", [0,1,2,3,4,5]],
-  ["1: Match only typed history",
-   "foo ^ ~", [2,3]],
-  ["2: Drop-down empty search matches only typed history",
-   "", [2,3]],
-  ["3: Drop-down empty search matches everything",
-   "", [0,1,2,3,4,5], function () setEmptyPref(0)],
-  ["4: Drop-down empty search matches only typed",
-   "", [2,3,5], function () setEmptyPref(32)],
-  ["5: Drop-down empty search matches only typed history",
-   "", [2,3], clearEmptyPref],
-];
+  do_log_info("Drop-down empty search matches everything");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior.emptyRestriction", 0);
+  yield check_autocomplete({
+    search: "",
+    matches: [ { uri: uri1, title: "title" },
+               { uri: uri2, title: "title" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "title" },
+               { uri: uri5, title: "title" },
+               { uri: uri6, title: "title" } ]
+  });
 
-function setEmptyPref(aValue)
-  prefs.setIntPref("browser.urlbar.default.behavior.emptyRestriction", aValue);
+  do_log_info("Drop-down empty search matches only typed");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior.emptyRestriction", 32);
+  yield check_autocomplete({
+    search: "",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "title" },
+               { uri: uri6, title: "title" } ]
+  });
 
-function clearEmptyPref()
-{
-  if (prefs.prefHasUserValue("browser.urlbar.default.behavior.emptyRestriction"))
-    prefs.clearUserPref("browser.urlbar.default.behavior.emptyRestriction");
-}
+  do_log_info("Drop-down empty search matches only typed history");
+  Services.prefs.clearUserPref("browser.urlbar.default.behavior.emptyRestriction");
+  yield check_autocomplete({
+    search: "",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "title" } ]
+  });
 
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_enabled.js
copy to toolkit/components/places/tests/unifiedcomplete/test_enabled.js
--- a/toolkit/components/places/tests/autocomplete/test_enabled.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_enabled.js
@@ -2,32 +2,34 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test for bug 471903 to make sure searching in autocomplete can be turned on
  * and off. Also test bug 463535 for pref changing search.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://url/0",
-];
-let kTitles = [
-  "title",
-];
+add_task(function* test_enabled() {
+  let uri = NetUtil.newURI("http://url/0");
+  yield promiseAddVisits([ { uri: uri, title: "title" } ]);
 
-addPageBook(0, 0); // visited page
+  do_log_info("plain search");
+  yield check_autocomplete({
+    search: "url",
+    matches: [ { uri: uri, title: "title" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["1: plain search",
-   "url", [0]],
-  ["2: search disabled",
-   "url", [], function() setSearch(0)],
-  ["3: resume normal search",
-   "url", [0], function() setSearch(1)],
-];
+  do_log_info("search disabled");
+  Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", false);
+  yield check_autocomplete({
+    search: "url",
+    matches: [ ]
+  });
 
-function setSearch(aSearch) {
-  prefs.setBoolPref("browser.urlbar.autocomplete.enabled", !!aSearch);
-}
+  do_log_info("resume normal search");
+  Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", true);
+  yield check_autocomplete({
+    search: "url",
+    matches: [ { uri: uri, title: "title" } ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_escape_self.js
copy to toolkit/components/places/tests/unifiedcomplete/test_escape_self.js
--- a/toolkit/components/places/tests/autocomplete/test_escape_self.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_escape_self.js
@@ -2,29 +2,28 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test bug 422698 to make sure searches with urls from the location bar
  * correctly match itself when it contains escaped characters.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://unescapeduri/",
-  "http://escapeduri/%40/",
-];
-let kTitles = [
-  "title",
-];
+add_task(function* test_escape() {
+  let uri1 = NetUtil.newURI("http://unescapeduri/");
+  let uri2 = NetUtil.newURI("http://escapeduri/%40/");
+  yield promiseAddVisits([ { uri: uri1, title: "title" },
+                           { uri: uri2, title: "title" } ]);
 
-// Add unescaped and escaped uris
-addPageBook(0, 0);
-addPageBook(1, 0);
+  do_log_info("Unescaped location matches itself");
+  yield check_autocomplete({
+    search: "http://unescapeduri/",
+    matches: [ { uri: uri1, title: "title" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Unescaped location matches itself",
-   kURIs[0], [0]],
-  ["1: Escaped location matches itself",
-   kURIs[1], [1]],
-];
+  do_log_info("Escaped location matches itself");
+  yield check_autocomplete({
+    search: "http://escapeduri/%40/",
+    matches: [ { uri: uri2, title: "title" } ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_ignore_protocol.js
copy to toolkit/components/places/tests/unifiedcomplete/test_ignore_protocol.js
--- a/toolkit/components/places/tests/autocomplete/test_ignore_protocol.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_ignore_protocol.js
@@ -1,27 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test bug 424509 to make sure searching for "h" doesn't match "http" of urls.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://site/",
-  "http://happytimes/",
-];
-let kTitles = [
-  "title",
-];
+add_task(function* test_escape() {
+  let uri1 = NetUtil.newURI("http://site/");
+  let uri2 = NetUtil.newURI("http://happytimes/");
+  yield promiseAddVisits([ { uri: uri1, title: "title" },
+                           { uri: uri2, title: "title" } ]);
 
-// Add site without "h" and with "h"
-addPageBook(0, 0);
-addPageBook(1, 0);
+  do_log_info("Searching for h matches site and not http://");
+  yield check_autocomplete({
+    search: "h",
+    matches: [ { uri: uri2, title: "title" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Searching for h matches site and not http://",
-   "h", [1]],
-];
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_keyword_search.js
copy to toolkit/components/places/tests/unifiedcomplete/test_keyword_search.js
--- a/toolkit/components/places/tests/autocomplete/test_keyword_search.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_keyword_search.js
@@ -7,75 +7,71 @@
  * sure that multiple parameter queries get spaces converted to +, + converted
  * to %2B, non-ascii become escaped, and pages in history that match the
  * keyword uses the page's title.
  *
  * Also test for bug 249468 by making sure multiple keyword bookmarks with the
  * same keyword appear in the list.
  */
 
-// Details for the keyword bookmark
-let keyBase = "http://abc/?search=";
-let keyKey = "key";
-
-// A second keyword bookmark with the same keyword
-let otherBase = "http://xyz/?foo=";
-
-let unescaped = "ユニコード";
-let pageInHistory = "ThisPageIsInHistory";
+add_task(function* test_keyword_searc() {
+  let uri1 = NetUtil.newURI("http://abc/?search=%s");
+  let uri2 = NetUtil.newURI("http://abc/?search=ThisPageIsInHistory");
+  yield promiseAddVisits([ { uri: uri1, title: "Generic page title" },
+                           { uri: uri2, title: "Generic page title" } ]);
+  addBookmark({ uri: uri1, title: "Keyword title", keyword: "key"});
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  keyBase + "%s",
-  keyBase + "term",
-  keyBase + "multi+word",
-  keyBase + "blocking%2B",
-  keyBase + unescaped,
-  keyBase + pageInHistory,
-  keyBase,
-  otherBase + "%s",
-  keyBase + "twoKey",
-  otherBase + "twoKey"
-];
-let kTitles = [
-  "Generic page title",
-  "Keyword title",
-];
+  do_log_info("Plain keyword query");
+  yield check_autocomplete({
+    search: "key term",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search=term"), title: "Keyword title" } ]
+  });
+
+  do_log_info("Multi-word keyword query");
+  yield check_autocomplete({
+    search: "key multi word",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search=multi+word"), title: "Keyword title" } ]
+  });
 
-// Add the keyword bookmark
-addPageBook(0, 0, 1, [], keyKey);
-// Add in the "fake pages" for keyword searches
-gPages[1] = [1,1];
-gPages[2] = [2,1];
-gPages[3] = [3,1];
-gPages[4] = [4,1];
-// Add a page into history
-addPageBook(5, 0);
-gPages[6] = [6,1];
+  do_log_info("Keyword query with +");
+  yield check_autocomplete({
+    search: "key blocking+",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search=blocking%2B"), title: "Keyword title" } ]
+  });
+
+  do_log_info("Unescaped term in query");
+  yield check_autocomplete({
+    search: "key ユニコード",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search=ユニコード"), title: "Keyword title" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Plain keyword query",
-   keyKey + " term", [1]],
-  ["1: Multi-word keyword query",
-   keyKey + " multi word", [2]],
-  ["2: Keyword query with +",
-   keyKey + " blocking+", [3]],
-  ["3: Unescaped term in query",
-   keyKey + " " + unescaped, [4]],
-  ["4: Keyword that happens to match a page",
-   keyKey + " " + pageInHistory, [5]],
-  ["5: Keyword without query (without space)",
-   keyKey, [6]],
-  ["6: Keyword without query (with space)",
-   keyKey + " ", [6]],
+  do_log_info("Keyword that happens to match a page");
+  yield check_autocomplete({
+    search: "key ThisPageIsInHistory",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search=ThisPageIsInHistory"), title: "Generic page title" } ]
+  });
+
+  do_log_info("Keyword without query (without space)");
+  yield check_autocomplete({
+    search: "key",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search="), title: "Keyword title" } ]
+  });
+
+  do_log_info("Keyword without query (with space)");
+  yield check_autocomplete({
+    search: "key ",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search="), title: "Keyword title" } ]
+  });
 
   // This adds a second keyword so anything after this will match 2 keywords
-  ["7: Two keywords matched",
-   keyKey + " twoKey", [8,9],
-   function() {
-     // Add the keyword search as well as search results
-     addPageBook(7, 0, 1, [], keyKey);
-     gPages[8] = [8,1];
-     gPages[9] = [9,1];
-   }]
-];
+  let uri3 = NetUtil.newURI("http://xyz/?foo=%s");
+  yield promiseAddVisits([ { uri: uri3, title: "Generic page title" } ]);
+  addBookmark({ uri: uri3, title: "Keyword title", keyword: "key"});
+
+  do_log_info("Two keywords matched");
+  yield check_autocomplete({
+    search: "key twoKey",
+    matches: [ { uri: NetUtil.newURI("http://abc/?search=twoKey"), title: "Keyword title" },
+               { uri: NetUtil.newURI("http://xyz/?foo=twoKey"), title: "Keyword title" } ]
+  });
+
+  yield cleanup();
+});
--- a/toolkit/components/places/tests/unifiedcomplete/test_keywords.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_keywords.js
@@ -1,68 +1,68 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 add_task(function* test_non_keyword() {
   do_log_info("Searching for non-keyworded entry should autoFill it");
   yield promiseAddVisits({ uri: NetUtil.newURI("http://mozilla.org/test/"),
                            transition: TRANSITION_TYPED });
-  addBookmark({ url: "http://mozilla.org/test/" });
+  addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/") });
   yield check_autocomplete({
     search: "moz",
     autofilled: "mozilla.org/",
     completed: "mozilla.org/"
   });
   yield cleanup();
 });
 
 add_task(function* test_keyword() {
   do_log_info("Searching for keyworded entry should not autoFill it");
   yield promiseAddVisits({ uri: NetUtil.newURI("http://mozilla.org/test/"),
                            transition: TRANSITION_TYPED });
-  addBookmark({ url: "http://mozilla.org/test/", keyword: "moz" });
+  addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
   yield check_autocomplete({
     search: "moz",
     autofilled: "moz",
     completed: "moz",
   });
   yield cleanup();
 });
 
 add_task(function* test_more_than_keyword() {
   do_log_info("Searching for more than keyworded entry should autoFill it");
   yield promiseAddVisits({ uri: NetUtil.newURI("http://mozilla.org/test/"),
                            transition: TRANSITION_TYPED });
-  addBookmark({ url: "http://mozilla.org/test/", keyword: "moz" });
+  addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
   yield check_autocomplete({
     search: "mozi",
     autofilled: "mozilla.org/",
     completed: "mozilla.org/"
   });
   yield cleanup();
 });
 
 add_task(function* test_less_than_keyword() {
   do_log_info("Searching for less than keyworded entry should autoFill it");
   yield promiseAddVisits({ uri: NetUtil.newURI("http://mozilla.org/test/"),
                            transition: TRANSITION_TYPED });
-  addBookmark({ url: "http://mozilla.org/test/", keyword: "moz" });
+  addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
   yield check_autocomplete({
     search: "mo",
     autofilled: "mozilla.org/",
     completed: "mozilla.org/",
   });
   yield cleanup();
 });
 
 add_task(function* test_keyword_casing() {
   do_log_info("Searching for keyworded entry is case-insensitive");
   yield promiseAddVisits({ uri: NetUtil.newURI("http://mozilla.org/test/"),
                            transition: TRANSITION_TYPED });
-  addBookmark({ url: "http://mozilla.org/test/", keyword: "moz" });
+  addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
   yield check_autocomplete({
     search: "MoZ",
     autofilled: "MoZ",
     completed: "MoZ"
   });
   yield cleanup();
 });
copy from toolkit/components/places/tests/autocomplete/test_match_beginning.js
copy to toolkit/components/places/tests/unifiedcomplete/test_match_beginning.js
--- a/toolkit/components/places/tests/autocomplete/test_match_beginning.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_match_beginning.js
@@ -2,44 +2,49 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test bug 451760 which allows matching only at the beginning of urls or
  * titles to simulate Firefox 2 functionality.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://x.com/y",
-  "https://y.com/x",
-];
-let kTitles = [
-  "a b",
-  "b a",
-];
+add_task(function* test_match_beginning() {
+  let uri1 = NetUtil.newURI("http://x.com/y");
+  let uri2 = NetUtil.newURI("https://y.com/x");
+  yield promiseAddVisits([ { uri: uri1, title: "a b" },
+                           { uri: uri2, title: "b a" } ]);
 
-addPageBook(0, 0);
-addPageBook(1, 1);
+  do_log_info("Match at the beginning of titles");
+  Services.prefs.setIntPref("browser.urlbar.matchBehavior", 3);
+  yield check_autocomplete({
+    search: "a",
+    matches: [ { uri: uri1, title: "a b" } ]
+  });
+
+  do_log_info("Match at the beginning of titles");
+  yield check_autocomplete({
+    search: "b",
+    matches: [ { uri: uri2, title: "b a" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  // Tests after this one will match at the beginning
-  ["0: Match at the beginning of titles",
-   "a", [0],
-   function() setBehavior(3)],
-  ["1: Match at the beginning of titles",
-   "b", [1]],
-  ["2: Match at the beginning of urls",
-   "x", [0]],
-  ["3: Match at the beginning of urls",
-   "y", [1]],
-  
-  // Tests after this one will match against word boundaries and anywhere
-  ["4: Sanity check that matching anywhere finds more",
-   "a", [0,1],
-   function() setBehavior(1)],
-];
+  do_log_info("Match at the beginning of urls");
+  yield check_autocomplete({
+    search: "x",
+    matches: [ { uri: uri1, title: "a b" } ]
+  });
 
-function setBehavior(aType) {
-  prefs.setIntPref("browser.urlbar.matchBehavior", aType);
-}
+  do_log_info("Match at the beginning of urls");
+  yield check_autocomplete({
+    search: "y",
+    matches: [ { uri: uri2, title: "b a" } ]
+  });
+
+  do_log_info("Sanity check that matching anywhere finds more");
+  Services.prefs.setIntPref("browser.urlbar.matchBehavior", 1);
+  yield check_autocomplete({
+    search: "a",
+    matches: [ { uri: uri1, title: "a b" },
+               { uri: uri2, title: "b a" } ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_multi_word_search.js
copy to toolkit/components/places/tests/unifiedcomplete/test_multi_word_search.js
--- a/toolkit/components/places/tests/autocomplete/test_multi_word_search.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_multi_word_search.js
@@ -7,43 +7,60 @@
  * the page title, page url, or bookmark title to be considered a match. All
  * terms must match but not all terms need to be in the title, etc.
  *
  * Test bug 424216 by making sure bookmark titles are always shown if one is
  * available. Also bug 425056 makes sure matches aren't found partially in the
  * page title and partially in the bookmark.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://a.b.c/d-e_f/h/t/p",
-  "http://d.e.f/g-h_i/h/t/p",
-  "http://g.h.i/j-k_l/h/t/p",
-  "http://j.k.l/m-n_o/h/t/p",
-];
-let kTitles = [
-  "f(o)o b<a>r",
-  "b(a)r b<a>z",
-];
+add_task(function* test_match_beginning() {
+  let uri1 = NetUtil.newURI("http://a.b.c/d-e_f/h/t/p");
+  let uri2 = NetUtil.newURI("http://d.e.f/g-h_i/h/t/p");
+  let uri3 = NetUtil.newURI("http://g.h.i/j-k_l/h/t/p");
+  let uri4 = NetUtil.newURI("http://j.k.l/m-n_o/h/t/p");
+  yield promiseAddVisits([ { uri: uri1, title: "f(o)o b<a>r" },
+                           { uri: uri2, title: "b(a)r b<a>z" },
+                           { uri: uri3, title: "f(o)o b<a>r" },
+                           { uri: uri4, title: "f(o)o b<a>r" } ]);
+  addBookmark({ uri: uri3, title: "f(o)o b<a>r" });
+  addBookmark({ uri: uri4, title: "b(a)r b<a>z" });
+
+  do_log_info("Match 2 terms all in url");
+  yield check_autocomplete({
+    search: "c d",
+    matches: [ { uri: uri1, title: "f(o)o b<a>r" } ]
+  });
+
+  do_log_info("Match 1 term in url and 1 term in title");
+  yield check_autocomplete({
+    search: "b e",
+    matches: [ { uri: uri1, title: "f(o)o b<a>r" },
+               { uri: uri2, title: "b(a)r b<a>z" } ]
+  });
 
-// Regular pages
-addPageBook(0, 0);
-addPageBook(1, 1);
-// Bookmarked pages
-addPageBook(2, 0, 0);
-addPageBook(3, 0, 1);
+  do_log_info("Match 3 terms all in title; display bookmark title if matched");
+  yield check_autocomplete({
+    search: "b a z",
+    matches: [ { uri: uri2, title: "b(a)r b<a>z" },
+               { uri: uri4, title: "b(a)r b<a>z" } ]
+  });
+
+  do_log_info("Match 2 terms in url and 1 in title; make sure bookmark title is used for search");
+  yield check_autocomplete({
+    search: "k f t",
+    matches: [ { uri: uri3, title: "f(o)o b<a>r" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: Match 2 terms all in url",
-   "c d", [0]],
-  ["1: Match 1 term in url and 1 term in title",
-   "b e", [0,1]],
-  ["2: Match 3 terms all in title; display bookmark title if matched",
-   "b a z", [1,3]],
-  ["3: Match 2 terms in url and 1 in title; make sure bookmark title is used for search",
-   "k f t", [2]],
-  ["4: Match 3 terms in url and 1 in title",
-   "d i g z", [1]],
-  ["5: Match nothing",
-   "m o z i", []],
-];
+  do_log_info("Match 3 terms in url and 1 in title");
+  yield check_autocomplete({
+    search: "d i g z",
+    matches: [ { uri: uri2, title: "b(a)r b<a>z" } ]
+  });
+
+  do_log_info("Match nothing");
+  yield check_autocomplete({
+    search: "m o z i",
+    matches: [ ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_special_search.js
copy to toolkit/components/places/tests/unifiedcomplete/test_special_search.js
--- a/toolkit/components/places/tests/autocomplete/test_special_search.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_special_search.js
@@ -5,180 +5,415 @@
 /**
  * Test for bug 395161 that allows special searches that restrict results to
  * history/bookmark/tagged items and title/url matches.
  *
  * Test 485122 by making sure results don't have tags when restricting result
  * to just history either by default behavior or dynamic query restrict.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://url/",
-  "http://url/2",
-  "http://foo.bar/",
-  "http://foo.bar/2",
-  "http://url/star",
-  "http://url/star/2",
-  "http://foo.bar/star",
-  "http://foo.bar/star/2",
-  "http://url/tag",
-  "http://url/tag/2",
-  "http://foo.bar/tag",
-  "http://foo.bar/tag/2",
-];
-let kTitles = [
-  "title",
-  "foo.bar",
-];
-
-// Plain page visits
-addPageBook(0, 0); // plain page
-addPageBook(1, 1); // title
-addPageBook(2, 0); // url
-addPageBook(3, 1); // title and url
+add_task(function* test_special_searches() {
+  let uri1 = NetUtil.newURI("http://url/");
+  let uri2 = NetUtil.newURI("http://url/2");
+  let uri3 = NetUtil.newURI("http://foo.bar/");
+  let uri4 = NetUtil.newURI("http://foo.bar/2");
+  let uri5 = NetUtil.newURI("http://url/star");
+  let uri6 = NetUtil.newURI("http://url/star/2");
+  let uri7 = NetUtil.newURI("http://foo.bar/star");
+  let uri8 = NetUtil.newURI("http://foo.bar/star/2");
+  let uri9 = NetUtil.newURI("http://url/tag");
+  let uri10 = NetUtil.newURI("http://url/tag/2");
+  let uri11 = NetUtil.newURI("http://foo.bar/tag");
+  let uri12 = NetUtil.newURI("http://foo.bar/tag/2");
+  yield promiseAddVisits([ { uri: uri1, title: "title", transition: TRANSITION_TYPED },
+                           { uri: uri2, title: "foo.bar" },
+                           { uri: uri3, title: "title" },
+                           { uri: uri4, title: "foo.bar", transition: TRANSITION_TYPED },
+                           { uri: uri6, title: "foo.bar" },
+                           { uri: uri11, title: "title", transition: TRANSITION_TYPED } ]);
+  addBookmark( { uri: uri5, title: "title" } );
+  addBookmark( { uri: uri6, title: "foo.bar" } );
+  addBookmark( { uri: uri7, title: "title" } );
+  addBookmark( { uri: uri8, title: "foo.bar" } );
+  addBookmark( { uri: uri9, title: "title", tags: [ "foo.bar" ] } );
+  addBookmark( { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] } );
+  addBookmark( { uri: uri11, title: "title", tags: [ "foo.bar" ] } );
+  addBookmark( { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } );
 
-// Bookmarked pages (no tag)
-addPageBook(4, 0, 0); // bookmarked page
-addPageBook(5, 1, 1); // title
-addPageBook(6, 0, 0); // url
-addPageBook(7, 1, 1); // title and url
-
-// Tagged pages
-addPageBook(8, 0, 0, [1]); // tagged page
-addPageBook(9, 1, 1, [1]); // title
-addPageBook(10, 0, 0, [1]); // url
-addPageBook(11, 1, 1, [1]); // title and url
+  // Test restricting searches
+  do_log_info("History restrict");
+  yield check_autocomplete({
+    search: "^",
+    matches: [ { uri: uri1, title: "title" },
+               { uri: uri2, title: "foo.bar" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
 
-// Remove pages from history to treat them as unvisited, so pages that do have
-// visits are 0,1,2,3,5,10
-removePages([4,6,7,8,9,11]);
-// Set some pages as typed
-markTyped([0,10], 0);
-markTyped([3], 1);
+  do_log_info("Star restrict");
+  yield check_autocomplete({
+    search: "*",
+    matches: [ { uri: uri5, title: "title" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar"] },
+               { uri: uri12, title: "foo.bar", tags: ["foo.bar"] } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  // Test restricting searches
-  ["0: History restrict",
-   "^", [0,1,2,3,5,10], ignoreTags],
-  ["1: Star restrict",
-   "*", [4,5,6,7,8,9,10,11]],
-  ["2: Tag restrict",
-   "+", [8,9,10,11]],
+  do_log_info("Tag restrict");
+  yield check_autocomplete({
+    search: "+",
+    matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
 
   // Test specials as any word position
-  ["3: Special as first word",
-   "^ foo bar", [1,2,3,5,10], ignoreTags],
-  ["4: Special as middle word",
-   "foo ^ bar", [1,2,3,5,10], ignoreTags],
-  ["5: Special as last word",
-   "foo bar ^", [1,2,3,5,10], ignoreTags],
+  do_log_info("Special as first word");
+  yield check_autocomplete({
+    search: "^ foo bar",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("Special as middle word");
+  yield check_autocomplete({
+    search: "foo ^ bar",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("Special as last word");
+  yield check_autocomplete({
+    search: "foo bar ^",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
 
   // Test restricting and matching searches with a term
-  ["6.1: foo ^ -> history",
-   "foo ^", [1,2,3,5,10], ignoreTags],
-  ["6.2: foo | -> history (change pref)",
-   "foo |", [1,2,3,5,10], function() {ignoreTags(); changeRestrict("history", "|"); }],
-  ["7.1: foo * -> is star",
-   "foo *", [5,6,7,8,9,10,11], function() resetRestrict("history")],
-  ["7.2: foo | -> is star (change pref)",
-   "foo |", [5,6,7,8,9,10,11], function() changeRestrict("bookmark", "|")],
-  ["8.1: foo # -> in title",
-   "foo #", [1,3,5,7,8,9,10,11], function() resetRestrict("bookmark")],
-  ["8.2: foo | -> in title (change pref)",
-   "foo |", [1,3,5,7,8,9,10,11], function() changeRestrict("title", "|")],
-  ["9.1: foo @ -> in url",
-   "foo @", [2,3,6,7,10,11], function() resetRestrict("title")],
-  ["9.2: foo | -> in url (change pref)",
-   "foo |", [2,3,6,7,10,11], function() changeRestrict("url", "|")],
-  ["10: foo + -> is tag",
-   "foo +", [8,9,10,11], function() resetRestrict("url")],
-  ["10.2: foo | -> is tag (change pref)",
-   "foo |", [8,9,10,11], function() changeRestrict("tag", "|")],
-  ["10.3: foo ~ -> is typed",
-   "foo ~", [3,10], function() resetRestrict("tag")],
-  ["10.4: foo | -> is typed (change pref)",
-   "foo |", [3,10], function() changeRestrict("typed", "|")],
+  do_log_info("foo ^ -> history");
+  yield check_autocomplete({
+    search: "foo ^",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("foo | -> history (change pref)");
+  changeRestrict("history", "|");
+  yield check_autocomplete({
+    search: "foo |",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("foo * -> is star");
+  resetRestrict("history");
+  yield check_autocomplete({
+    search: "foo *",
+    matches: [ { uri: uri6, title: "foo.bar" },
+               { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo | -> is star (change pref)");
+  changeRestrict("bookmark", "|");
+  yield check_autocomplete({
+    search: "foo |",
+    matches: [ { uri: uri6, title: "foo.bar" },
+               { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo # -> in title");
+  resetRestrict("bookmark");
+  yield check_autocomplete({
+    search: "foo #",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo | -> in title (change pref)");
+  changeRestrict("title", "|");
+  yield check_autocomplete({
+    search: "foo |",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo @ -> in url");
+  resetRestrict("title");
+  yield check_autocomplete({
+    search: "foo @",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo | -> in url (change pref)");
+  changeRestrict("url", "|");
+  yield check_autocomplete({
+    search: "foo |",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo + -> is tag");
+  resetRestrict("url");
+  yield check_autocomplete({
+    search: "foo +",
+    matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo | -> is tag (change pref)");
+  changeRestrict("tag", "|");
+  yield check_autocomplete({
+    search: "foo |",
+    matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo ~ -> is typed");
+  resetRestrict("tag");
+  yield check_autocomplete({
+    search: "foo ~",
+    matches: [ { uri: uri4, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo | -> is typed (change pref)");
+  changeRestrict("typed", "|");
+  yield check_autocomplete({
+    search: "foo |",
+    matches: [ { uri: uri4, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
 
   // Test various pairs of special searches
-  ["11: foo ^ * -> history, is star",
-   "foo ^ *", [5,10], function() resetRestrict("typed")],
-  ["12: foo ^ # -> history, in title",
-   "foo ^ #", [1,3,5,10], ignoreTags],
-  ["13: foo ^ @ -> history, in url",
-   "foo ^ @", [2,3,10], ignoreTags],
-  ["14: foo ^ + -> history, is tag",
-   "foo ^ +", [10]],
-  ["14.1: foo ^ ~ -> history, is typed",
-   "foo ^ ~", [3,10], ignoreTags],
-  ["15: foo * # -> is star, in title",
-   "foo * #", [5,7,8,9,10,11]],
-  ["16: foo * @ -> is star, in url",
-   "foo * @", [6,7,10,11]],
-  ["17: foo * + -> same as +",
-   "foo * +", [8,9,10,11]],
-  ["17.1: foo * ~ -> is star, is typed",
-   "foo * ~", [10]],
-  ["18: foo # @ -> in title, in url",
-   "foo # @", [3,7,10,11]],
-  ["19: foo # + -> in title, is tag",
-   "foo # +", [8,9,10,11]],
-  ["19.1: foo # ~ -> in title, is typed",
-   "foo # ~", [3,10]],
-  ["20: foo @ + -> in url, is tag",
-   "foo @ +", [10,11]],
-  ["20.1: foo @ ~ -> in url, is typed",
-   "foo @ ~", [3,10]],
-  ["20.2: foo + ~ -> is tag, is typed",
-   "foo + ~", [10]],
+  do_log_info("foo ^ * -> history, is star");
+  resetRestrict("typed");
+  yield check_autocomplete({
+    search: "foo ^ *",
+    matches: [ { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo ^ # -> history, in title");
+  yield check_autocomplete({
+    search: "foo ^ #",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("foo ^ @ -> history, in url");
+  yield check_autocomplete({
+    search: "foo ^ @",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("foo ^ + -> history, is tag");
+  yield check_autocomplete({
+    search: "foo ^ +",
+    matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo ^ ~ -> history, is typed");
+  yield check_autocomplete({
+    search: "foo ^ ~",
+    matches: [ { uri: uri4, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("foo * # -> is star, in title");
+  yield check_autocomplete({
+    search: "foo * #",
+    matches: [ { uri: uri6, title: "foo.bar" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo * @ -> is star, in url");
+  yield check_autocomplete({
+    search: "foo * @",
+    matches: [ { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo * + -> same as +");
+  yield check_autocomplete({
+    search: "foo * +",
+    matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo * ~ -> is star, is typed");
+  yield check_autocomplete({
+    search: "foo * ~",
+    matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo # @ -> in title, in url");
+  yield check_autocomplete({
+    search: "foo # @",
+    matches: [ { uri: uri4, title: "foo.bar" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo # + -> in title, is tag");
+  yield check_autocomplete({
+    search: "foo # +",
+    matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo # ~ -> in title, is typed");
+  yield check_autocomplete({
+    search: "foo # ~",
+    matches: [ { uri: uri4, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo @ + -> in url, is tag");
+  yield check_autocomplete({
+    search: "foo @ +",
+    matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo @ ~ -> in url, is typed");
+  yield check_autocomplete({
+    search: "foo @ ~",
+    matches: [ { uri: uri4, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo + ~ -> is tag, is typed");
+  yield check_autocomplete({
+    search: "foo + ~",
+    matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
 
   // Test default usage by setting certain bits of default.behavior to 1
-  ["21: foo -> default history",
-   "foo", [1,2,3,5,10], function() makeDefault(1)],
-  ["22: foo -> default history, is star",
-   "foo", [5,10], function() makeDefault(3)],
-  ["22.1: foo -> default history, is star, is typed",
-   "foo", [10], function() makeDefault(35)],
-  ["23: foo -> default history, is star, in url",
-   "foo", [10], function() makeDefault(19)],
+  do_log_info("foo -> default history");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior", 1);
+  yield check_autocomplete({
+    search: "foo",
+    matches: [ { uri: uri2, title: "foo.bar" },
+               { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title" } ]
+  });
+
+  do_log_info("foo -> default history, is star");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior", 3);
+  yield check_autocomplete({
+    search: "foo",
+    matches: [ { uri: uri6, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo -> default history, is star, is typed");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior", 35);
+  yield check_autocomplete({
+    search: "foo",
+    matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
+
+  do_log_info("foo -> default history, is star, in url");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior", 19);
+  yield check_autocomplete({
+    search: "foo",
+    matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ] } ]
+  });
 
   // Change the default to be less restrictive to make sure we find more
-  ["24: foo -> default is star, in url",
-   "foo", [6,7,10,11], function() makeDefault(18)],
-  ["25: foo -> default in url",
-   "foo", [2,3,6,7,10,11], function() makeDefault(16)],
-];
-
-function makeDefault(aDefault) {
-  // We want to ignore tags if we're restricting to history unless we're showing
-  if ((aDefault & 1) && !((aDefault & 2) || (aDefault & 4)))
-    ignoreTags();
-
-  prefs.setIntPref("browser.urlbar.default.behavior", aDefault);
-}
+  do_log_info("foo -> default is star, in url");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior", 18);
+  yield check_autocomplete({
+    search: "foo",
+    matches: [ { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
 
-function changeRestrict(aType, aChar)
-{
-  let branch = "browser.urlbar.";
-  // "title" and "url" are different from everything else, so special case them.
-  if (aType == "title" || aType == "url")
-    branch += "match.";
-  else
-    branch += "restrict.";
-
-  print("changing restrict for " + aType + " to '" + aChar + "'");
-  prefs.setCharPref(branch + aType, aChar);
-}
+  do_log_info("foo -> default in url");
+  Services.prefs.setIntPref("browser.urlbar.default.behavior", 16);
+  yield check_autocomplete({
+    search: "foo",
+    matches: [ { uri: uri3, title: "title" },
+               { uri: uri4, title: "foo.bar" },
+               { uri: uri7, title: "title" },
+               { uri: uri8, title: "foo.bar" },
+               { uri: uri11, title: "title", tags: [ "foo.bar" ] },
+               { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } ]
+  });
 
-function resetRestrict(aType)
-{
-  let branch = "browser.urlbar.";
-  // "title" and "url" are different from everything else, so special case them.
-  if (aType == "title" || aType == "url")
-    branch += "match.";
-  else
-    branch += "restrict.";
-
-  if (prefs.prefHasUserValue(branch + aType))
-    prefs.clearUserPref(branch + aType);
-}
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_swap_protocol.js
copy to toolkit/components/places/tests/unifiedcomplete/test_swap_protocol.js
--- a/toolkit/components/places/tests/autocomplete/test_swap_protocol.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_swap_protocol.js
@@ -6,58 +6,144 @@
  * Test bug 424717 to make sure searching with an existing location like
  * http://site/ also matches https://site/ or ftp://site/. Same thing for
  * ftp://site/ and https://site/.
  *
  * Test bug 461483 to make sure a search for "w" doesn't match the "www." from
  * site subdomains.
  */
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://www.site/",
-  "http://site/",
-  "ftp://ftp.site/",
-  "ftp://site/",
-  "https://www.site/",
-  "https://site/",
-  "http://woohoo/",
-  "http://wwwwwwacko/",
-];
-let kTitles = [
-  "title",
-];
+add_task(function* test_swap_protocol() {
+  let uri1 = NetUtil.newURI("http://www.site/");
+  let uri2 = NetUtil.newURI("http://site/");
+  let uri3 = NetUtil.newURI("ftp://ftp.site/");
+  let uri4 = NetUtil.newURI("ftp://site/");
+  let uri5 = NetUtil.newURI("https://www.site/");
+  let uri6 = NetUtil.newURI("https://site/");
+  let uri7 = NetUtil.newURI("http://woohoo/");
+  let uri8 = NetUtil.newURI("http://wwwwwwacko/");
+  yield promiseAddVisits([ { uri: uri1, title: "title" },
+                           { uri: uri2, title: "title" },
+                           { uri: uri3, title: "title" },
+                           { uri: uri4, title: "title" },
+                           { uri: uri5, title: "title" },
+                           { uri: uri6, title: "title" },
+                           { uri: uri7, title: "title" },
+                           { uri: uri8, title: "title" } ]);
+
+  let allMatches = [
+    { uri: uri1, title: "title" },
+    { uri: uri2, title: "title" },
+    { uri: uri3, title: "title" },
+    { uri: uri4, title: "title" },
+    { uri: uri5, title: "title" },
+    { uri: uri6, title: "title" }
+  ];
+
+  Services.prefs.setBoolPref("browser.urlbar.autoFill", "false");
 
-// Add various protocols of site
-addPageBook(0, 0);
-addPageBook(1, 0);
-addPageBook(2, 0);
-addPageBook(3, 0);
-addPageBook(4, 0);
-addPageBook(5, 0);
-addPageBook(6, 0);
-addPageBook(7, 0);
+  do_log_info("http://www.site matches all site");
+  yield check_autocomplete({
+    search: "http://www.site",
+    matches: allMatches
+  });
+/*
+  do_log_info("http://site matches all site");
+  yield check_autocomplete({
+    search: "http://site",
+    matches: allMatches
+  });
+
+  do_log_info("ftp://ftp.site matches itself");
+  yield check_autocomplete({
+    search: "ftp://ftp.site",
+    matches: { uri: uri3, title: "title"}
+  });
+
+  do_log_info("ftp://site matches all site");
+  yield check_autocomplete({
+    search: "ftp://site",
+    matches: allMatches
+  });
+
+  do_log_info("https://www.site matches all site");
+  yield check_autocomplete({
+    search: "https://www.site",
+    matches: allMatches
+  });
+
+  do_log_info("https://site matches all site");
+  yield check_autocomplete({
+    search: "https://site",
+    matches: allMatches
+  });
 
-let allSite = [0,1,2,3,4,5];
+  do_log_info("www.site matches all site");
+  yield check_autocomplete({
+    search: "www.site",
+    matches: allMatches
+  });
+
+  do_log_info("w matches none of www.");
+  yield check_autocomplete({
+    search: "w",
+    matches: [ { uri: uri7, title: "title" },
+               { uri: uri8, title: "title" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  ["0: http://www.site matches all site", "http://www.site", allSite],
-  ["1: http://site matches all site", "http://site", allSite],
-  ["2: ftp://ftp.site matches itself", "ftp://ftp.site", [2]],
-  ["3: ftp://site matches all site", "ftp://site", allSite],
-  ["4: https://www.site matches all site", "https://www.site", allSite],
-  ["5: https://site matches all site", "https://site", allSite],
-  ["6: www.site matches all site", "www.site", allSite],
+  do_log_info("http://w matches none of www.");
+  yield check_autocomplete({
+    search: "http://w",
+    matches: [ { uri: uri7, title: "title" },
+               { uri: uri8, title: "title" } ]
+  });
+
+  do_log_info("http://w matches none of www.");
+  yield check_autocomplete({
+    search: "http://www.w",
+    matches: [ { uri: uri7, title: "title" },
+               { uri: uri8, title: "title" } ]
+  });
+
+  do_log_info("ww matches none of www.");
+  yield check_autocomplete({
+    search: "ww",
+    matches: [ { uri: uri8, title: "title" } ]
+  });
 
-  ["7: w matches none of www.", "w", [6,7]],
-  ["8: http://w matches none of www.", "w", [6,7]],
-  ["9: http://www.w matches none of www.", "w", [6,7]],
+  do_log_info("ww matches none of www.");
+  yield check_autocomplete({
+    search: "ww",
+    matches: [ { uri: uri8, title: "title" } ]
+  });
+
+  do_log_info("http://ww matches none of www.");
+  yield check_autocomplete({
+    search: "http://ww",
+    matches: [ { uri: uri8, title: "title" } ]
+  });
+
+  do_log_info("http://www.ww matches none of www.");
+  yield check_autocomplete({
+    search: "http://www.ww",
+    matches: [ { uri: uri8, title: "title" } ]
+  });
 
-  ["10: ww matches none of www.", "ww", [7]],
-  ["11: http://ww matches none of www.", "http://ww", [7]],
-  ["12: http://www.ww matches none of www.", "http://www.ww", [7]],
+  do_log_info("www matches none of www.");
+  yield check_autocomplete({
+    search: "www",
+    matches: [ { uri: uri8, title: "title" } ]
+  });
 
-  ["13: www matches none of www.", "www", [7]],
-  ["14: http://www matches none of www.", "http://www", [7]],
-  ["15: http://www.www matches none of www.", "http://www.www", [7]],
-];
+  do_log_info("http://www matches none of www.");
+  yield check_autocomplete({
+    search: "http://www",
+    matches: [ { uri: uri8, title: "title" } ]
+  });
+
+  do_log_info("http://www.www matches none of www.");
+  yield check_autocomplete({
+    search: "http://www.www",
+    matches: [ { uri: uri8, title: "title" } ]
+  });
+*/
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_tabmatches.js
copy to toolkit/components/places/tests/unifiedcomplete/test_tabmatches.js
--- a/toolkit/components/places/tests/autocomplete/test_tabmatches.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_tabmatches.js
@@ -1,93 +1,96 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
  * vim:set ts=2 sw=2 sts=2 et:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-let gTabRestrictChar = prefs.getCharPref("browser.urlbar.restrict.openpage");
-
-let kSearchParam = "enable-actions";
+let gTabRestrictChar = "%";
 
-let kURIs = [
-  "http://abc.com/",
-  "moz-action:switchtab,http://abc.com/",
-  "http://xyz.net/",
-  "moz-action:switchtab,http://xyz.net/",
-  "about:mozilla",
-  "moz-action:switchtab,about:mozilla",
-  "data:text/html,test",
-  "moz-action:switchtab,data:text/html,test"
-];
+add_task(function* test_tab_matches() {
+  let uri1 = NetUtil.newURI("http://abc.com/");
+  let uri2 = NetUtil.newURI("http://xyz.net/");
+  let uri3 = NetUtil.newURI("about:mozilla");
+  let uri4 = NetUtil.newURI("data:text/html,test");
+  yield promiseAddVisits([ { uri: uri1, title: "ABC rocks" },
+                           { uri: uri2, title: "xyz.net - we're better than ABC" } ]);
+  addOpenPages(uri1, 1);
+  // Pages that cannot be registered in history.
+  addOpenPages(uri3, 1);
+  addOpenPages(uri4, 1);
 
-let kTitles = [
-  "ABC rocks",
-  "xyz.net - we're better than ABC",
-  "about:mozilla",
-  "data:text/html,test"
-];
+  do_log_info("single result, that is also a tab match");
+  yield check_autocomplete({
+    search: "abc.com",
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" } ]
+  });
 
-addPageBook(0, 0);
-gPages[1] = [1, 0];
-addPageBook(2, 1);
-gPages[3] = [3, 1];
+  do_log_info("two results, one tab match");
+  yield check_autocomplete({
+    search: "abc",
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" },
+               { uri: uri2, title: "xyz.net - we're better than ABC" } ]
+  });
 
-addOpenPages(0, 1);
-
-// PAges that cannot be registered in history.
-addOpenPages(4, 1);
-gPages[5] = [5, 2];
-addOpenPages(6, 1);
-gPages[7] = [7, 3];
+  do_log_info("two results, both tab matches");
+  addOpenPages(uri2, 1);
+  yield check_autocomplete({
+    search: "abc",
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" },
+               { uri: NetUtil.newURI("moz-action:switchtab,http://xyz.net/"), title: "xyz.net - we're better than ABC" } ]
+  });
 
-let gTests = [
-  ["0: single result, that is also a tab match",
-   "abc.com", [1]],
-  ["1: two results, one tab match",
-   "abc", [1,2]],
-  ["2: two results, both tab matches",
-   "abc", [1,3],
-   function() {
-     addOpenPages(2, 1);
-   }],
-  ["3: two results, both tab matches, one has multiple tabs",
-   "abc", [1,3],
-   function() {
-     addOpenPages(2, 5);
-   }],
-  ["4: two results, no tab matches",
-   "abc", [0,2],
-   function() {
-     removeOpenPages(0, 1);
-     removeOpenPages(2, 6);
-   }],
-  ["5: tab match search with restriction character",
-   gTabRestrictChar + " abc", [1],
-   function() {
-    addOpenPages(0, 1);
-   }],
-  ["6: tab match with not-addable pages",
-   "mozilla", [5]],
-  ["7: tab match with not-addable pages and restriction character",
-   gTabRestrictChar + " mozilla", [5]],
-  ["8: tab match with not-addable pages and only restriction character",
-   gTabRestrictChar, [1, 5, 7]],
-];
+  do_log_info("two results, both tab matches, one has multiple tabs");
+  addOpenPages(uri2, 5);
+  yield check_autocomplete({
+    search: "abc",
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" },
+               { uri: NetUtil.newURI("moz-action:switchtab,http://xyz.net/"), title: "xyz.net - we're better than ABC" } ]
+  });
+
+  do_log_info("two results, no tab matches");
+  removeOpenPages(uri1, 1);
+  removeOpenPages(uri2, 6);
+  yield check_autocomplete({
+    search: "abc",
+    searchParam: "enable-actions",
+    matches: [ { uri: uri1, title: "ABC rocks" },
+               { uri: uri2, title: "xyz.net - we're better than ABC" } ]
+  });
 
+  do_log_info("tab match search with restriction character");
+  addOpenPages(uri1, 1);
+  yield check_autocomplete({
+    search: gTabRestrictChar + " abc",
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" } ]
+  });
 
-function addOpenPages(aUri, aCount) {
-  let num = aCount || 1;
-  let acprovider = Cc["@mozilla.org/autocomplete/search;1?name=history"].
-                   getService(Ci.mozIPlacesAutoComplete);
-  for (let i = 0; i < num; i++) {
-    acprovider.registerOpenPage(toURI(kURIs[aUri]));
-  }
-}
+  do_log_info("tab match with not-addable pages");
+  yield check_autocomplete({
+    search: "mozilla",
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,about:mozilla"), title: "about:mozilla" } ]
+  });
 
-function removeOpenPages(aUri, aCount) {
-  let num = aCount || 1;
-  let acprovider = Cc["@mozilla.org/autocomplete/search;1?name=history"].
-                   getService(Ci.mozIPlacesAutoComplete);
-  for (let i = 0; i < num; i++) {
-    acprovider.unregisterOpenPage(toURI(kURIs[aUri]));
-  }
-}
+  do_log_info("tab match with not-addable pages and restriction character");
+  yield check_autocomplete({
+    search: gTabRestrictChar + " mozilla",
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,about:mozilla"), title: "about:mozilla" } ]
+  });
+
+  do_log_info("tab match with not-addable pages and only restriction character");
+  yield check_autocomplete({
+    search: gTabRestrictChar,
+    searchParam: "enable-actions",
+    matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" },
+               { uri: NetUtil.newURI("moz-action:switchtab,about:mozilla"), title: "about:mozilla" },
+               { uri: NetUtil.newURI("moz-action:switchtab,data:text/html,test"), title: "data:text/html,test" } ]
+  });
+
+  yield cleanup();
+});
copy from toolkit/components/places/tests/autocomplete/test_word_boundary_search.js
copy to toolkit/components/places/tests/unifiedcomplete/test_word_boundary_search.js
--- a/toolkit/components/places/tests/autocomplete/test_word_boundary_search.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_word_boundary_search.js
@@ -12,94 +12,160 @@
  * Bug 429531 provides switching between "must match on word boundary" and "can
  * match," so leverage "must match" pref for checking word boundary logic and
  * make sure "can match" matches anywhere.
  */
 
 let katakana = ["\u30a8", "\u30c9"]; // E, Do
 let ideograph = ["\u4efb", "\u5929", "\u5802"]; // Nin Ten Do
 
-// Define some shared uris and titles (each page needs its own uri)
-let kURIs = [
-  "http://matchme/",
-  "http://dontmatchme/",
-  "http://title/1",
-  "http://title/2",
-  "http://tag/1",
-  "http://tag/2",
-  "http://crazytitle/",
-  "http://katakana/",
-  "http://ideograph/",
-  "http://camel/pleaseMatchMe/",
-];
-let kTitles = [
-  "title1",
-  "matchme2",
-  "dontmatchme3",
-  "!@#$%^&*()_+{}|:<>?word",
-  katakana.join(""),
-  ideograph.join(""),
-];
+add_task(function* test_escape() {
+  let uri1 = NetUtil.newURI("http://matchme/");
+  let uri2 = NetUtil.newURI("http://dontmatchme/");
+  let uri3 = NetUtil.newURI("http://title/1");
+  let uri4 = NetUtil.newURI("http://title/2");
+  let uri5 = NetUtil.newURI("http://tag/1");
+  let uri6 = NetUtil.newURI("http://tag/2");
+  let uri7 = NetUtil.newURI("http://crazytitle/");
+  let uri8 = NetUtil.newURI("http://katakana/");
+  let uri9 = NetUtil.newURI("http://ideograph/");
+  let uri10 = NetUtil.newURI("http://camel/pleaseMatchMe/");
+
+  yield promiseAddVisits([ { uri: uri1, title: "title1" },
+                           { uri: uri2, title: "title1" },
+                           { uri: uri3, title: "matchme2" },
+                           { uri: uri4, title: "dontmatchme3" },
+                           { uri: uri5, title: "title1" },
+                           { uri: uri6, title: "title1" },
+                           { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" },
+                           { uri: uri8, title: katakana.join("") },
+                           { uri: uri9, title: ideograph.join("") },
+                           { uri: uri10, title: "title1" } ]);
+  addBookmark( { uri: uri5, title: "title1", tags: [ "matchme2" ] } );
+  addBookmark( { uri: uri6, title: "title1", tags: [ "dontmatchme3" ] } );
+
+  // match only on word boundaries
+  Services.prefs.setIntPref("browser.urlbar.matchBehavior", 2);
 
-// Boundaries on the url
-addPageBook(0, 0);
-addPageBook(1, 0);
-// Boundaries on the title
-addPageBook(2, 1);
-addPageBook(3, 2);
-// Boundaries on the tag
-addPageBook(4, 0, 0, [1]);
-addPageBook(5, 0, 0, [2]);
-// Lots of word boundaries before a word
-addPageBook(6, 3);
-// Katakana
-addPageBook(7, 4);
-// Ideograph
-addPageBook(8, 5);
-// CamelCase
-addPageBook(9, 0);
+  do_log_info("Match 'match' at the beginning or after / or on a CamelCase");
+  yield check_autocomplete({
+    search: "match",
+    matches: [ { uri: uri1, title: "title1" },
+               { uri: uri3, title: "matchme2" },
+               { uri: uri5, title: "title1", tags: [ "matchme2" ] },
+               { uri: uri10, title: "title1" } ]
+  });
+
+  do_log_info("Match 'dont' at the beginning or after /");
+  yield check_autocomplete({
+    search: "dont",
+    matches: [ { uri: uri2, title: "title1" },
+               { uri: uri4, title: "dontmatchme3" },
+               { uri: uri6, title: "title1", tags: [ "dontmatchme3" ] } ]
+  });
+
+  do_log_info("Match 'match' at the beginning or after / or on a CamelCase");
+  yield check_autocomplete({
+    search: "2",
+    matches: [ { uri: uri3, title: "matchme2" },
+               { uri: uri4, title: "dontmatchme3" },
+               { uri: uri5, title: "title1", tags: [ "matchme2" ] },
+               { uri: uri6, title: "title1", tags: [ "dontmatchme3" ] } ]
+  });
+
+  do_log_info("Match 't' at the beginning or after /");
+  yield check_autocomplete({
+    search: "t",
+    matches: [ { uri: uri1, title: "title1" },
+               { uri: uri2, title: "title1" },
+               { uri: uri3, title: "matchme2" },
+               { uri: uri4, title: "dontmatchme3" },
+               { uri: uri5, title: "title1", tags: [ "matchme2" ] },
+               { uri: uri6, title: "title1", tags: [ "dontmatchme3" ] },
+               { uri: uri10, title: "title1" } ]
+  });
+
+  do_log_info("Match 'word' after many consecutive word boundaries");
+  yield check_autocomplete({
+    search: "word",
+    matches: [ { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" } ]
+  });
 
-// Provide for each test: description; search terms; array of gPages indices of
-// pages that should match; optional function to be run before the test
-let gTests = [
-  // Tests after this one will match only on word boundaries
-  ["0: Match 'match' at the beginning or after / or on a CamelCase",
-   "match", [0,2,4,9],
-   function() setBehavior(2)],
-  ["1: Match 'dont' at the beginning or after /",
-   "dont", [1,3,5]],
-  ["2: Match '2' after the slash and after a word (in tags too)",
-   "2", [2,3,4,5]],
-  ["3: Match 't' at the beginning or after /",
-   "t", [0,1,2,3,4,5,9]],
-  ["4: Match 'word' after many consecutive word boundaries",
-   "word", [6]],
-  ["5: Match a word boundary '/' for everything",
-   "/", [0,1,2,3,4,5,6,7,8,9]],
-  ["6: Match word boundaries '()_+' that are among word boundaries",
-   "()_+", [6]],
+  do_log_info("Match a word boundary '/' for everything");
+  yield check_autocomplete({
+    search: "/",
+    matches: [ { uri: uri1, title: "title1" },
+               { uri: uri2, title: "title1" },
+               { uri: uri3, title: "matchme2" },
+               { uri: uri4, title: "dontmatchme3" },
+               { uri: uri5, title: "title1", tags: [ "matchme2" ] },
+               { uri: uri6, title: "title1", tags: [ "dontmatchme3" ] },
+               { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" },
+               { uri: uri8, title: katakana.join("") },
+               { uri: uri9, title: ideograph.join("") },
+               { uri: uri10, title: "title1" } ]
+  });
+
+  do_log_info("Match word boundaries '()_+' that are among word boundaries");
+  yield check_autocomplete({
+    search: "()_+",
+    matches: [ { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" } ]
+  });
+
+  do_log_info("Katakana characters form a string, so match the beginning");
+  yield check_autocomplete({
+    search: katakana[0],
+    matches: [ { uri: uri8, title: katakana.join("") } ]
+  });
+
+/*
+  do_log_info("Middle of a katakana word shouldn't be matched");
+  yield check_autocomplete({
+    search: katakana[1],
+    matches: [ ]
+  });
+*/
+ do_log_info("Ideographs are treated as words so 'nin' is one word");
+  yield check_autocomplete({
+    search: ideograph[0],
+    matches: [ { uri: uri9, title: ideograph.join("") } ]
+  });
 
-  ["7: Katakana characters form a string, so match the beginning",
-   katakana[0], [7]],
-  /*["8: Middle of a katakana word shouldn't be matched",
-   katakana[1], []],*/
+ do_log_info("Ideographs are treated as words so 'ten' is another word");
+  yield check_autocomplete({
+    search: ideograph[1],
+    matches: [ { uri: uri9, title: ideograph.join("") } ]
+  });
 
-  ["9: Ideographs are treated as words so 'nin' is one word",
-   ideograph[0], [8]],
-  ["10: Ideographs are treated as words so 'ten' is another word",
-   ideograph[1], [8]],
-  ["11: Ideographs are treated as words so 'do' is yet another",
-   ideograph[2], [8]],
+ do_log_info("Ideographs are treated as words so 'do' is yet another word");
+  yield check_autocomplete({
+    search: ideograph[2],
+    matches: [ { uri: uri9, title: ideograph.join("") } ]
+  });
+
+ do_log_info("Extra negative assert that we don't match in the middle");
+  yield check_autocomplete({
+    search: "ch",
+    matches: [ ]
+  });
 
-  ["12: Extra negative assert that we don't match in the middle",
-   "ch", []],
-  ["13: Don't match one character after a camel-case word boundary (bug 429498)",
-   "atch", []],
+ do_log_info("Don't match one character after a camel-case word boundary (bug 429498)");
+  yield check_autocomplete({
+    search: "atch",
+    matches: [ ]
+  });
+
+  // match against word boundaries and anywhere
+  Services.prefs.setIntPref("browser.urlbar.matchBehavior", 1);
 
-  // Tests after this one will match against word boundaries and anywhere
-  ["14: Match on word boundaries as well as anywhere (bug 429531)",
-   "tch", [0,1,2,3,4,5,9],
-   function() setBehavior(1)],
-];
+  yield check_autocomplete({
+    search: "tch",
+    matches: [ { uri: uri1, title: "title1" },
+               { uri: uri2, title: "title1" },
+               { uri: uri3, title: "matchme2" },
+               { uri: uri4, title: "dontmatchme3" },
+               { uri: uri5, title: "title1", tags: [ "matchme2" ] },
+               { uri: uri6, title: "title1", tags: [ "dontmatchme3" ] },
+               { uri: uri10, title: "title1" } ]
+  });
 
-function setBehavior(aType) {
-  prefs.setIntPref("browser.urlbar.matchBehavior", aType);
-}
+  yield cleanup();
+});
--- a/toolkit/components/places/tests/unifiedcomplete/xpcshell.ini
+++ b/toolkit/components/places/tests/unifiedcomplete/xpcshell.ini
@@ -1,12 +1,30 @@
 [DEFAULT]
 head = head_autocomplete.js
 tail = 
 
+[test_416211.js]
+[test_416214.js]
+[test_417798.js]
+[test_418257.js]
+[test_422277.js]
 [test_autocomplete_functional.js]
+[test_autocomplete_on_value_removed_479089.js]
 [test_casing.js]
 [test_do_not_trim.js]
+[test_download_embed_bookmarks.js]
+[test_empty_search.js]
+[test_enabled.js]
+[test_escape_self.js]
+[test_ignore_protocol.js]
+[test_keyword_search.js]
 [test_keywords.js]
+[test_match_beginning.js]
+[test_multi_word_search.js]
 [test_queryurl.js]
+[test_special_search.js]
+[test_swap_protocol.js]
+[test_tabmatches.js]
 [test_trimming.js]
 [test_typed.js]
+[test_word_boundary_search.js]
 [test_zero_frecency.js]