aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--background_scripts/completion.coffee15
-rw-r--r--tests/unit_tests/completion_test.coffee25
2 files changed, 35 insertions, 5 deletions
diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee
index 9e12d497..9314d9be 100644
--- a/background_scripts/completion.coffee
+++ b/background_scripts/completion.coffee
@@ -307,12 +307,16 @@ RegexpCache =
clear: -> @cache = {}
- get: (string) ->
+ # Get rexexp for string from cache, creating the regexp if necessary.
+ # Regexp meta-characters in string are escaped.
+ # Regexp is wrapped in prefix/suffix, which may contain meta-characters.
+ get: (string, prefix="", suffix="") ->
@init() unless @initialized
- @cache[string] ||= @escapeRegexp(string)
-
- # Creates a Regexp from the given string, with all special Regexp characters escaped.
- escapeRegexp: (string) -> new RegExp(string.replace(@escapeRegExp, "\\$&"), "i")
+ regexpString = string.replace(@escapeRegExp, "\\$&")
+ # Avoid cost of constructing new strings if prefix/suffix are empty (which is expected to be a common case).
+ regexpString = prefix + regexpString if prefix
+ regexpString = regexpString + suffix if suffix
+ @cache[regexpString] ||= new RegExp(regexpString, "i")
# Provides cached access to Chrome's history. As the user browses to new pages, we add those pages to this
# history cache.
@@ -382,3 +386,4 @@ root.DomainCompleter = DomainCompleter
root.TabCompleter = TabCompleter
root.HistoryCache = HistoryCache
root.RankingUtils = RankingUtils
+root.RegexpCache = RegexpCache
diff --git a/tests/unit_tests/completion_test.coffee b/tests/unit_tests/completion_test.coffee
index 32b62a28..f978c57b 100644
--- a/tests/unit_tests/completion_test.coffee
+++ b/tests/unit_tests/completion_test.coffee
@@ -174,6 +174,31 @@ context "RankingUtils",
should "every term must match at least one thing (not matching)", ->
assert.isTrue not RankingUtils.matches(["cat", "dog", "wolf"], "catapult", "hound dog")
+context "RegexpCache",
+ should "RegexpCache is in fact caching (positive case)", ->
+ assert.isTrue RegexpCache.get("this") is RegexpCache.get("this")
+
+ should "RegexpCache is in fact caching (negative case)", ->
+ assert.isTrue RegexpCache.get("this") isnt RegexpCache.get("that")
+
+ should "RegexpCache prefix/suffix wrapping is working (positive case)", ->
+ assert.isTrue RegexpCache.get("this", "(", ")") is RegexpCache.get("this", "(", ")")
+
+ should "RegexpCache prefix/suffix wrapping is working (negative case)", ->
+ assert.isTrue RegexpCache.get("this", "(", ")") isnt RegexpCache.get("this")
+
+ should "search for a string", ->
+ assert.isTrue "hound dog".search(RegexpCache.get("dog")) == 6
+
+ should "search for a string which isn't there", ->
+ assert.isTrue "hound dog".search(RegexpCache.get("cat")) == -1
+
+ should "search for a string with a prefix/suffix (positive case)", ->
+ assert.isTrue "hound dog".search(RegexpCache.get("dog", "\\b", "\\b")) == 6
+
+ should "search for a string with a prefix/suffix (negative case)", ->
+ assert.isTrue "hound dog".search(RegexpCache.get("do", "\\b", "\\b")) == -1
+
# A convenience wrapper around completer.filter() so it can be called synchronously in tests.
filterCompleter = (completer, queryTerms) ->
results = []