@@ -41,6 +41,9 @@ context "HistoryCache",
4141 should " return length - 1 if it should be at the end of the list" , ->
4242 assert .equal 0 , HistoryCache .binarySearch (3 , [3 , 5 , 8 ], @compare )
4343
44+ should " return one passed end of array (so: array.length) if greater than last element in array" , ->
45+ assert .equal 3 , HistoryCache .binarySearch (10 , [3 , 5 , 8 ], @compare )
46+
4447 should " found return the position if it's between two elements" , ->
4548 assert .equal 1 , HistoryCache .binarySearch (4 , [3 , 5 , 8 ], @compare )
4649 assert .equal 2 , HistoryCache .binarySearch (7 , [3 , 5 , 8 ], @compare )
@@ -51,9 +54,11 @@ context "HistoryCache",
5154 @history2 = { url : " a.com" , lastVisitTime : 10 }
5255 history = [@history1 , @history2 ]
5356 @onVisitedListener = null
57+ @onVisitRemovedListener = null
5458 global .chrome .history =
5559 search : (options , callback ) -> callback (history)
5660 onVisited : { addListener : (@onVisitedListener ) => }
61+ onVisitRemoved : { addListener : (@onVisitRemovedListener ) => }
5762 HistoryCache .reset ()
5863
5964 should " store visits sorted by url ascending" , ->
@@ -75,6 +80,30 @@ context "HistoryCache",
7580 HistoryCache .use (@results ) =>
7681 assert .arrayEqual [newSite, @history1 ], @results
7782
83+ should " (not) remove page from the history, when page is not in history (it should be a no-op)" , ->
84+ HistoryCache .use (@results ) =>
85+ assert .arrayEqual [@history2 , @history1 ], @results
86+ toRemove = { urls : [ " x.com" ], allHistory : false }
87+ @ onVisitRemovedListener (toRemove)
88+ HistoryCache .use (@results ) =>
89+ assert .arrayEqual [@history2 , @history1 ], @results
90+
91+ should " remove pages from the history" , ->
92+ HistoryCache .use (@results ) =>
93+ assert .arrayEqual [@history2 , @history1 ], @results
94+ toRemove = { urls : [ " a.com" ], allHistory : false }
95+ @ onVisitRemovedListener (toRemove)
96+ HistoryCache .use (@results ) =>
97+ assert .arrayEqual [@history1 ], @results
98+
99+ should " remove all pages from the history" , ->
100+ HistoryCache .use (@results ) =>
101+ assert .arrayEqual [@history2 , @history1 ], @results
102+ toRemove = { allHistory : true }
103+ @ onVisitRemovedListener (toRemove)
104+ HistoryCache .use (@results ) =>
105+ assert .arrayEqual [], @results
106+
78107context " history completer" ,
79108 setup ->
80109 @history1 = { title : " history1" , url : " history1.com" , lastVisitTime : hours (1 ) }
@@ -83,6 +112,7 @@ context "history completer",
83112 global .chrome .history =
84113 search : (options , callback ) => callback ([@history1 , @history2 ])
85114 onVisited : { addListener : -> }
115+ onVisitRemoved : { addListener : -> }
86116
87117 @completer = new HistoryCompleter ()
88118
@@ -102,7 +132,9 @@ context "domain completer",
102132 @history2 = { title : " history2" , url : " http://history2.com" , lastVisitTime : hours (1 ) }
103133
104134 stub (HistoryCache, " use" , (onComplete ) => onComplete ([@history1 , @history2 ]))
105- global .chrome .history = { onVisited : { addListener : -> } }
135+ global .chrome .history =
136+ onVisited : { addListener : -> }
137+ onVisitRemoved : { addListener : -> }
106138 stub (Date , " now" , returns (hours (24 )))
107139
108140 @completer = new DomainCompleter ()
@@ -112,14 +144,58 @@ context "domain completer",
112144 assert .arrayEqual [" history1.com" ], results .map (result) -> result .url
113145
114146 should " pick domains which are more recent" , ->
115- # This domains are the same except for their last visited time.
147+ # These domains are the same except for their last visited time.
116148 assert .equal " history1.com" , filterCompleter (@completer , [" story" ])[0 ].url
117149 @history2 .lastVisitTime = hours (3 )
118150 assert .equal " history2.com" , filterCompleter (@completer , [" story" ])[0 ].url
119151
120152 should " returns no results when there's more than one query term, because clearly it's not a domain" , ->
121153 assert .arrayEqual [], filterCompleter (@completer , [" his" , " tory" ])
122154
155+ context " domain completer (removing entries)" ,
156+ setup ->
157+ @history1 = { title : " history1" , url : " http://history1.com" , lastVisitTime : hours (2 ) }
158+ @history2 = { title : " history2" , url : " http://history2.com" , lastVisitTime : hours (1 ) }
159+ @history3 = { title : " history2something" , url : " http://history2.com/something" , lastVisitTime : hours (0 ) }
160+
161+ stub (HistoryCache, " use" , (onComplete ) => onComplete ([@history1 , @history2 , @history3 ]))
162+ @onVisitedListener = null
163+ @onVisitRemovedListener = null
164+ global .chrome .history =
165+ onVisited : { addListener : (@onVisitedListener ) => }
166+ onVisitRemoved : { addListener : (@onVisitRemovedListener ) => }
167+ stub (Date , " now" , returns (hours (24 )))
168+
169+ @completer = new DomainCompleter ()
170+ # Force installation of listeners.
171+ filterCompleter (@completer , [" story" ])
172+
173+ should " remove 1 entry for domain with reference count of 1" , ->
174+ @ onVisitRemovedListener { allHistory : false , urls : [@history1 .url ] }
175+ assert .equal " history2.com" , filterCompleter (@completer , [" story" ])[0 ].url
176+ assert .equal 0 , filterCompleter (@completer , [" story1" ]).length
177+
178+ should " remove 2 entries for domain with reference count of 2" , ->
179+ @ onVisitRemovedListener { allHistory : false , urls : [@history2 .url ] }
180+ assert .equal " history2.com" , filterCompleter (@completer , [" story2" ])[0 ].url
181+ @ onVisitRemovedListener { allHistory : false , urls : [@history3 .url ] }
182+ assert .equal 0 , filterCompleter (@completer , [" story2" ]).length
183+ assert .equal " history1.com" , filterCompleter (@completer , [" story" ])[0 ].url
184+
185+ should " remove 3 (all) matching domain entries" , ->
186+ @ onVisitRemovedListener { allHistory : false , urls : [@history2 .url ] }
187+ @ onVisitRemovedListener { allHistory : false , urls : [@history1 .url ] }
188+ @ onVisitRemovedListener { allHistory : false , urls : [@history3 .url ] }
189+ assert .equal 0 , filterCompleter (@completer , [" story" ]).length
190+
191+ should " remove 3 (all) matching domain entries, and do it all at once" , ->
192+ @ onVisitRemovedListener { allHistory : false , urls : [ @history2 .url , @history1 .url , @history3 .url ] }
193+ assert .equal 0 , filterCompleter (@completer , [" story" ]).length
194+
195+ should " remove *all* domain entries" , ->
196+ @ onVisitRemovedListener { allHistory : true }
197+ assert .equal 0 , filterCompleter (@completer , [" story" ]).length
198+
123199context " tab completer" ,
124200 setup ->
125201 @tabs = [
0 commit comments