test_word_boundary_search.js (12157B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /** 6 * Test to make sure matches against the url, title, tags are first made on word 7 * boundaries, instead of in the middle of words, and later are extended to the 8 * whole words. For this test it is critical to check sorting of the matches. 9 * 10 * Make sure we don't try matching one after a CamelCase because the upper-case 11 * isn't really a word boundary. (bug 429498) 12 */ 13 14 testEngine_setup(); 15 16 var katakana = ["\u30a8", "\u30c9"]; // E, Do 17 var ideograph = ["\u4efb", "\u5929", "\u5802"]; // Nin Ten Do 18 19 add_task(async function test_escape() { 20 Services.prefs.setBoolPref("browser.urlbar.autoFill", false); 21 Services.prefs.setBoolPref("browser.urlbar.suggest.searches", false); 22 Services.prefs.setBoolPref("browser.urlbar.suggest.quickactions", false); 23 registerCleanupFunction(() => { 24 Services.prefs.clearUserPref("browser.urlbar.suggest.searches"); 25 Services.prefs.clearUserPref("browser.urlbar.suggest.quickactions"); 26 Services.prefs.clearUserPref("browser.urlbar.autoFill"); 27 }); 28 29 await PlacesTestUtils.addBookmarkWithDetails({ 30 uri: "http://tag/1", 31 title: "title1", 32 tags: ["matchme2"], 33 }); 34 await PlacesTestUtils.addBookmarkWithDetails({ 35 uri: "http://tag/2", 36 title: "title1", 37 tags: ["dontmatchme3"], 38 }); 39 40 await PlacesTestUtils.addVisits([ 41 { uri: "http://matchme/", title: "title1" }, 42 { uri: "http://dontmatchme/", title: "title1" }, 43 { uri: "http://title/1", title: "matchme2" }, 44 { uri: "http://title/2", title: "dontmatchme3" }, 45 { 46 uri: "http://tag/1", 47 title: "title1", 48 }, 49 { 50 uri: "http://tag/2", 51 title: "title1", 52 }, 53 { uri: "http://crazytitle/", title: "!@#$%^&*()_+{}|:<>?word" }, 54 { uri: "http://katakana/", title: katakana.join("") }, 55 { uri: "http://ideograph/", title: ideograph.join("") }, 56 { uri: "http://camel/pleaseMatchMe/", title: "title1" }, 57 ]); 58 await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); 59 60 info("Match 'match' at the beginning or after / or on a CamelCase"); 61 let context = createContext("match", { isPrivate: false }); 62 await check_results({ 63 context, 64 matches: [ 65 makeSearchResult(context, { 66 engineName: SUGGESTIONS_ENGINE_NAME, 67 heuristic: true, 68 }), 69 makeBookmarkResult(context, { 70 uri: "http://tag/1", 71 title: "title1", 72 tags: ["matchme2"], 73 }), 74 makeBookmarkResult(context, { 75 uri: "http://tag/2", 76 title: "title1", 77 tags: ["dontmatchme3"], 78 }), 79 makeVisitResult(context, { 80 uri: "http://camel/pleaseMatchMe/", 81 title: "title1", 82 }), 83 makeVisitResult(context, { uri: "http://title/1", title: "matchme2" }), 84 makeVisitResult(context, { uri: "http://matchme/", title: "title1" }), 85 makeVisitResult(context, { 86 uri: "http://title/2", 87 title: "dontmatchme3", 88 }), 89 makeVisitResult(context, { uri: "http://dontmatchme/", title: "title1" }), 90 ], 91 }); 92 93 info("Match 'dont' at the beginning or after /"); 94 context = createContext("dont", { isPrivate: false }); 95 await check_results({ 96 context, 97 matches: [ 98 makeSearchResult(context, { 99 engineName: SUGGESTIONS_ENGINE_NAME, 100 heuristic: true, 101 }), 102 makeBookmarkResult(context, { 103 uri: "http://tag/2", 104 title: "title1", 105 tags: ["dontmatchme3"], 106 }), 107 makeVisitResult(context, { 108 uri: "http://title/2", 109 title: "dontmatchme3", 110 }), 111 makeVisitResult(context, { uri: "http://dontmatchme/", title: "title1" }), 112 ], 113 }); 114 115 info("Match 'match' at the beginning or after / or on a CamelCase"); 116 context = createContext("2", { isPrivate: false }); 117 await check_results({ 118 context, 119 matches: [ 120 makeSearchResult(context, { 121 engineName: SUGGESTIONS_ENGINE_NAME, 122 heuristic: true, 123 }), 124 makeBookmarkResult(context, { 125 uri: "http://tag/2", 126 title: "title1", 127 }), 128 makeBookmarkResult(context, { 129 uri: "http://tag/1", 130 title: "title1", 131 tags: ["matchme2"], 132 }), 133 makeVisitResult(context, { 134 uri: "http://title/2", 135 title: "dontmatchme3", 136 }), 137 makeVisitResult(context, { uri: "http://title/1", title: "matchme2" }), 138 ], 139 }); 140 141 info("Match 't' at the beginning or after /"); 142 context = createContext("t", { isPrivate: false }); 143 await check_results({ 144 context, 145 matches: [ 146 makeSearchResult(context, { 147 engineName: SUGGESTIONS_ENGINE_NAME, 148 heuristic: true, 149 }), 150 makeBookmarkResult(context, { 151 uri: "http://tag/2", 152 title: "title1", 153 tags: ["dontmatchme3"], 154 }), 155 makeBookmarkResult(context, { 156 uri: "http://tag/1", 157 title: "title1", 158 tags: ["matchme2"], 159 }), 160 makeVisitResult(context, { 161 uri: "http://camel/pleaseMatchMe/", 162 title: "title1", 163 }), 164 makeVisitResult(context, { 165 uri: "http://title/2", 166 title: "dontmatchme3", 167 }), 168 makeVisitResult(context, { uri: "http://title/1", title: "matchme2" }), 169 makeVisitResult(context, { uri: "http://dontmatchme/", title: "title1" }), 170 makeVisitResult(context, { uri: "http://matchme/", title: "title1" }), 171 makeVisitResult(context, { 172 uri: "http://katakana/", 173 title: katakana.join(""), 174 }), 175 makeVisitResult(context, { 176 uri: "http://crazytitle/", 177 title: "!@#$%^&*()_+{}|:<>?word", 178 }), 179 ], 180 }); 181 182 info("Match 'word' after many consecutive word boundaries"); 183 context = createContext("word", { isPrivate: false }); 184 await check_results({ 185 context, 186 matches: [ 187 makeSearchResult(context, { 188 engineName: SUGGESTIONS_ENGINE_NAME, 189 heuristic: true, 190 }), 191 makeVisitResult(context, { 192 uri: "http://crazytitle/", 193 title: "!@#$%^&*()_+{}|:<>?word", 194 }), 195 ], 196 }); 197 198 info("Match a word boundary '/' for everything"); 199 context = createContext("/", { isPrivate: false }); 200 // UNIX platforms can search for a file:// URL by typing a forward slash. 201 let heuristicSlashResult = 202 AppConstants.platform == "win" 203 ? makeSearchResult(context, { 204 engineName: SUGGESTIONS_ENGINE_NAME, 205 heuristic: true, 206 }) 207 : makeVisitResult(context, { 208 uri: "file:///", 209 title: "file:///", 210 source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, 211 heuristic: true, 212 }); 213 await check_results({ 214 context, 215 matches: [ 216 heuristicSlashResult, 217 makeBookmarkResult(context, { 218 uri: "http://tag/2", 219 title: "title1", 220 }), 221 makeBookmarkResult(context, { 222 uri: "http://tag/1", 223 title: "title1", 224 }), 225 makeVisitResult(context, { 226 uri: "http://camel/pleaseMatchMe/", 227 title: "title1", 228 }), 229 makeVisitResult(context, { 230 uri: "http://ideograph/", 231 title: ideograph.join(""), 232 }), 233 makeVisitResult(context, { 234 uri: "http://katakana/", 235 title: katakana.join(""), 236 }), 237 makeVisitResult(context, { 238 uri: "http://crazytitle/", 239 title: "!@#$%^&*()_+{}|:<>?word", 240 }), 241 makeVisitResult(context, { 242 uri: "http://title/2", 243 title: "dontmatchme3", 244 }), 245 makeVisitResult(context, { uri: "http://title/1", title: "matchme2" }), 246 makeVisitResult(context, { uri: "http://dontmatchme/", title: "title1" }), 247 ], 248 }); 249 250 info("Match word boundaries '()_' that are among word boundaries"); 251 context = createContext("()_", { isPrivate: false }); 252 await check_results({ 253 context, 254 matches: [ 255 makeSearchResult(context, { 256 engineName: SUGGESTIONS_ENGINE_NAME, 257 heuristic: true, 258 }), 259 makeVisitResult(context, { 260 uri: "http://crazytitle/", 261 title: "!@#$%^&*()_+{}|:<>?word", 262 }), 263 ], 264 }); 265 266 info("Katakana characters form a string, so match the beginning"); 267 context = createContext(katakana[0], { isPrivate: false }); 268 await check_results({ 269 context, 270 matches: [ 271 makeSearchResult(context, { 272 engineName: SUGGESTIONS_ENGINE_NAME, 273 heuristic: true, 274 }), 275 makeVisitResult(context, { 276 uri: "http://katakana/", 277 title: katakana.join(""), 278 }), 279 ], 280 }); 281 282 /* 283 info("Middle of a katakana word shouldn't be matched"); 284 await check_autocomplete({ 285 search: katakana[1], 286 matches: [ ], 287 }); 288 */ 289 290 info("Ideographs are treated as words so 'nin' is one word"); 291 context = createContext(ideograph[0], { isPrivate: false }); 292 await check_results({ 293 context, 294 matches: [ 295 makeSearchResult(context, { 296 engineName: SUGGESTIONS_ENGINE_NAME, 297 heuristic: true, 298 }), 299 makeVisitResult(context, { 300 uri: "http://ideograph/", 301 title: ideograph.join(""), 302 }), 303 ], 304 }); 305 306 info("Ideographs are treated as words so 'ten' is another word"); 307 context = createContext(ideograph[1], { isPrivate: false }); 308 await check_results({ 309 context, 310 matches: [ 311 makeSearchResult(context, { 312 engineName: SUGGESTIONS_ENGINE_NAME, 313 heuristic: true, 314 }), 315 makeVisitResult(context, { 316 uri: "http://ideograph/", 317 title: ideograph.join(""), 318 }), 319 ], 320 }); 321 322 info("Ideographs are treated as words so 'do' is yet another word"); 323 context = createContext(ideograph[2], { isPrivate: false }); 324 await check_results({ 325 context, 326 matches: [ 327 makeSearchResult(context, { 328 engineName: SUGGESTIONS_ENGINE_NAME, 329 heuristic: true, 330 }), 331 makeVisitResult(context, { 332 uri: "http://ideograph/", 333 title: ideograph.join(""), 334 }), 335 ], 336 }); 337 338 info("Match in the middle. Should just be sorted by frecency."); 339 context = createContext("ch", { isPrivate: false }); 340 await check_results({ 341 context, 342 matches: [ 343 makeSearchResult(context, { 344 engineName: SUGGESTIONS_ENGINE_NAME, 345 heuristic: true, 346 }), 347 makeBookmarkResult(context, { 348 uri: "http://tag/2", 349 title: "title1", 350 tags: ["dontmatchme3"], 351 }), 352 makeBookmarkResult(context, { 353 uri: "http://tag/1", 354 title: "title1", 355 tags: ["matchme2"], 356 }), 357 makeVisitResult(context, { 358 uri: "http://camel/pleaseMatchMe/", 359 title: "title1", 360 }), 361 makeVisitResult(context, { 362 uri: "http://title/2", 363 title: "dontmatchme3", 364 }), 365 makeVisitResult(context, { uri: "http://title/1", title: "matchme2" }), 366 makeVisitResult(context, { uri: "http://dontmatchme/", title: "title1" }), 367 makeVisitResult(context, { uri: "http://matchme/", title: "title1" }), 368 ], 369 }); 370 371 // Also this test should just be sorted by frecency. 372 info( 373 "Don't match one character after a camel-case word boundary (bug 429498). Should just be sorted by frecency." 374 ); 375 context = createContext("atch", { isPrivate: false }); 376 await check_results({ 377 context, 378 matches: [ 379 makeSearchResult(context, { 380 engineName: SUGGESTIONS_ENGINE_NAME, 381 heuristic: true, 382 }), 383 makeBookmarkResult(context, { 384 uri: "http://tag/2", 385 title: "title1", 386 tags: ["dontmatchme3"], 387 }), 388 makeBookmarkResult(context, { 389 uri: "http://tag/1", 390 title: "title1", 391 tags: ["matchme2"], 392 }), 393 makeVisitResult(context, { 394 uri: "http://camel/pleaseMatchMe/", 395 title: "title1", 396 }), 397 makeVisitResult(context, { 398 uri: "http://title/2", 399 title: "dontmatchme3", 400 }), 401 makeVisitResult(context, { uri: "http://title/1", title: "matchme2" }), 402 makeVisitResult(context, { uri: "http://dontmatchme/", title: "title1" }), 403 makeVisitResult(context, { uri: "http://matchme/", title: "title1" }), 404 ], 405 }); 406 407 await cleanupPlaces(); 408 });