toolkit/components/satchel/test/unit/test_autocomplete.js

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:8071a393ea5c
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 "use strict";
6
7 var testnum = 0;
8 var fac;
9 var prefs;
10
11 let numRecords, timeGroupingSize, now;
12
13 const DEFAULT_EXPIRE_DAYS = 180;
14
15 function padLeft(number, length) {
16 var str = number + '';
17 while (str.length < length)
18 str = '0' + str;
19 return str;
20 }
21
22 function getFormExpiryDays() {
23 if (prefs.prefHasUserValue("browser.formfill.expire_days"))
24 return prefs.getIntPref("browser.formfill.expire_days");
25 else
26 return DEFAULT_EXPIRE_DAYS;
27 }
28
29 function run_test() {
30 // ===== test init =====
31 var testfile = do_get_file("formhistory_autocomplete.sqlite");
32 var profileDir = dirSvc.get("ProfD", Ci.nsIFile);
33
34 // Cleanup from any previous tests or failures.
35 var destFile = profileDir.clone();
36 destFile.append("formhistory.sqlite");
37 if (destFile.exists())
38 destFile.remove(false);
39
40 testfile.copyTo(profileDir, "formhistory.sqlite");
41
42 fac = Cc["@mozilla.org/satchel/form-autocomplete;1"].
43 getService(Ci.nsIFormAutoComplete);
44 prefs = Cc["@mozilla.org/preferences-service;1"].
45 getService(Ci.nsIPrefBranch);
46
47 timeGroupingSize = prefs.getIntPref("browser.formfill.timeGroupingSize") * 1000 * 1000;
48
49 run_next_test();
50 }
51
52 add_test(function test0() {
53 var maxTimeGroupings = prefs.getIntPref("browser.formfill.maxTimeGroupings");
54 var bucketSize = prefs.getIntPref("browser.formfill.bucketSize");
55
56 // ===== Tests with constant timesUsed and varying lastUsed date =====
57 // insert 2 records per bucket to check alphabetical sort within
58 now = 1000 * Date.now();
59 numRecords = Math.ceil(maxTimeGroupings / bucketSize) * 2;
60
61 let changes = [ ];
62 for (let i = 0; i < numRecords; i+=2) {
63 let useDate = now - (i/2 * bucketSize * timeGroupingSize);
64
65 changes.push({ op : "add", fieldname: "field1", value: "value" + padLeft(numRecords - 1 - i, 2),
66 timesUsed: 1, firstUsed: useDate, lastUsed: useDate });
67 changes.push({ op : "add", fieldname: "field1", value: "value" + padLeft(numRecords - 2 - i, 2),
68 timesUsed: 1, firstUsed: useDate, lastUsed: useDate });
69 }
70
71 updateFormHistory(changes, run_next_test);
72 });
73
74 add_test(function test1() {
75 do_log_info("Check initial state is as expected");
76
77 countEntries(null, null, function (count) {
78 countEntries("field1", null, function (count) {
79 do_check_true(count > 0);
80 run_next_test();
81 });
82 });
83 });
84
85 add_test(function test2() {
86 do_log_info("Check search contains all entries");
87
88 fac.autoCompleteSearchAsync("field1", "", null, null, {
89 onSearchCompletion : function(aResults) {
90 do_check_eq(numRecords, aResults.matchCount);
91 run_next_test();
92 }
93 });
94 });
95
96 add_test(function test3() {
97 do_log_info("Check search result ordering with empty search term");
98
99 let lastFound = numRecords;
100 fac.autoCompleteSearchAsync("field1", "", null, null, {
101 onSearchCompletion : function(aResults) {
102 for (let i = 0; i < numRecords; i+=2) {
103 do_check_eq(parseInt(aResults.getValueAt(i + 1).substr(5), 10), --lastFound);
104 do_check_eq(parseInt(aResults.getValueAt(i).substr(5), 10), --lastFound);
105 }
106 run_next_test();
107 }
108 });
109 });
110
111 add_test(function test4() {
112 do_log_info("Check search result ordering with \"v\"");
113
114 let lastFound = numRecords;
115 fac.autoCompleteSearchAsync("field1", "v", null, null, {
116 onSearchCompletion : function(aResults) {
117 for (let i = 0; i < numRecords; i+=2) {
118 do_check_eq(parseInt(aResults.getValueAt(i + 1).substr(5), 10), --lastFound);
119 do_check_eq(parseInt(aResults.getValueAt(i).substr(5), 10), --lastFound);
120 }
121 run_next_test();
122 }
123 });
124 });
125
126 const timesUsedSamples = 20;
127
128 add_test(function test5() {
129 do_log_info("Begin tests with constant use dates and varying timesUsed");
130
131 let changes = [];
132 for (let i = 0; i < timesUsedSamples; i++) {
133 let timesUsed = (timesUsedSamples - i);
134 let change = { op : "add", fieldname: "field2", value: "value" + (timesUsedSamples - 1 - i),
135 timesUsed: timesUsed * timeGroupingSize, firstUsed: now, lastUsed: now };
136 changes.push(change);
137 }
138 updateFormHistory(changes, run_next_test);
139 });
140
141 add_test(function test6() {
142 do_log_info("Check search result ordering with empty search term");
143
144 let lastFound = timesUsedSamples;
145 fac.autoCompleteSearchAsync("field2", "", null, null, {
146 onSearchCompletion : function(aResults) {
147 for (let i = 0; i < timesUsedSamples; i++) {
148 do_check_eq(parseInt(aResults.getValueAt(i).substr(5)), --lastFound);
149 }
150 run_next_test();
151 }
152 });
153 });
154
155 add_test(function test7() {
156 do_log_info("Check search result ordering with \"v\"");
157
158 let lastFound = timesUsedSamples;
159 fac.autoCompleteSearchAsync("field2", "v", null, null, {
160 onSearchCompletion : function(aResults) {
161 for (let i = 0; i < timesUsedSamples; i++) {
162 do_check_eq(parseInt(aResults.getValueAt(i).substr(5)), --lastFound);
163 }
164 run_next_test();
165 }
166 });
167 });
168
169 add_test(function test8() {
170 do_log_info("Check that \"senior citizen\" entries get a bonus (browser.formfill.agedBonus)");
171
172 let agedDate = 1000 * (Date.now() - getFormExpiryDays() * 24 * 60 * 60 * 1000);
173
174 let changes = [ ];
175 changes.push({ op : "add", fieldname: "field3", value: "old but not senior",
176 timesUsed: 100, firstUsed: (agedDate + 60 * 1000 * 1000), lastUsed: now });
177 changes.push({ op : "add", fieldname: "field3", value: "senior citizen",
178 timesUsed: 100, firstUsed: (agedDate - 60 * 1000 * 1000), lastUsed: now });
179 updateFormHistory(changes, run_next_test);
180 });
181
182 add_test(function test9() {
183 fac.autoCompleteSearchAsync("field3", "", null, null, {
184 onSearchCompletion : function(aResults) {
185 do_check_eq(aResults.getValueAt(0), "senior citizen");
186 do_check_eq(aResults.getValueAt(1), "old but not senior");
187 run_next_test();
188 }
189 });
190 });
191
192 add_test(function test10() {
193 do_log_info("Check entries that are really old or in the future");
194
195 let changes = [ ];
196 changes.push({ op : "add", fieldname: "field4", value: "date of 0",
197 timesUsed: 1, firstUsed: 0, lastUsed: 0 });
198 changes.push({ op : "add", fieldname: "field4", value: "in the future 1",
199 timesUsed: 1, firstUsed: 0, lastUsed: now * 2 });
200 changes.push({ op : "add", fieldname: "field4", value: "in the future 2",
201 timesUsed: 1, firstUsed: now * 2, lastUsed: now * 2 });
202 updateFormHistory(changes, run_next_test);
203 });
204
205 add_test(function test11() {
206 fac.autoCompleteSearchAsync("field4", "", null, null, {
207 onSearchCompletion : function(aResults) {
208 do_check_eq(aResults.matchCount, 3);
209 run_next_test();
210 }
211 });
212 });
213
214 let syncValues = ["sync1", "sync1a", "sync2", "sync3"]
215
216 add_test(function test12() {
217 do_log_info("Check old synchronous api");
218
219 let changes = [ ];
220 for (let value of syncValues) {
221 changes.push({ op : "add", fieldname: "field5", value: value });
222 }
223 updateFormHistory(changes, run_next_test);
224 });
225
226 add_test(function test13() {
227 let autocompleteService = Cc["@mozilla.org/satchel/form-autocomplete;1"].getService(Ci.nsIFormAutoComplete);
228 let results = autocompleteService.autoCompleteSearch("field5", "", null, null);
229 do_check_eq(results.matchCount, syncValues.length, "synchronous matchCount");
230 for (let i = 0; i < results.matchCount; i++) {
231 do_check_eq(results.getValueAt(i), syncValues[i]);
232 }
233
234 let results = autocompleteService.autoCompleteSearch("field5", "sync1", null, null);
235 do_check_eq(results.matchCount, 2, "synchronous matchCount");
236 do_check_eq(results.getValueAt(0), "sync1");
237 do_check_eq(results.getValueAt(1), "sync1a");
238 run_next_test();
239 });
240
241 add_test(function test_token_limit_DB() {
242 function test_token_limit_previousResult(previousResult) {
243 do_log_info("Check that the number of tokens used in a search is not capped to " +
244 "MAX_SEARCH_TOKENS when using a previousResult");
245 // This provide more accuracy since performance is less of an issue.
246 // Search for a string where the first 10 tokens match the previous value but the 11th does not
247 // when re-using a previous result.
248 fac.autoCompleteSearchAsync("field_token_cap",
249 "a b c d e f g h i j .",
250 null, previousResult, {
251 onSearchCompletion : function(aResults) {
252 do_check_eq(aResults.matchCount, 0,
253 "All search tokens should be used with " +
254 "previous results");
255 run_next_test();
256 }
257 });
258 }
259
260 do_log_info("Check that the number of tokens used in a search is capped to MAX_SEARCH_TOKENS " +
261 "for performance when querying the DB");
262 let changes = [ ];
263 changes.push({ op : "add", fieldname: "field_token_cap",
264 // value with 15 unique tokens
265 value: "a b c d e f g h i j k l m n o",
266 timesUsed: 1, firstUsed: 0, lastUsed: 0 });
267 updateFormHistory(changes, () => {
268 // Search for a string where the first 10 tokens match the value above but the 11th does not
269 // (which would prevent the result from being returned if the 11th term was used).
270 fac.autoCompleteSearchAsync("field_token_cap",
271 "a b c d e f g h i j .",
272 null, null, {
273 onSearchCompletion : function(aResults) {
274 do_check_eq(aResults.matchCount, 1,
275 "Only the first MAX_SEARCH_TOKENS tokens " +
276 "should be used for DB queries");
277 test_token_limit_previousResult(aResults);
278 }
279 });
280 });
281 });

mercurial