|
1 // newPset: returns an empty nsIUrlClassifierPrefixSet. |
|
2 function newPset() { |
|
3 let pset = Cc["@mozilla.org/url-classifier/prefixset;1"] |
|
4 .createInstance(Ci.nsIUrlClassifierPrefixSet); |
|
5 pset.init("all"); |
|
6 return pset; |
|
7 } |
|
8 |
|
9 // arrContains: returns true if |arr| contains the element |target|. Uses binary |
|
10 // search and requires |arr| to be sorted. |
|
11 function arrContains(arr, target) { |
|
12 let start = 0; |
|
13 let end = arr.length - 1; |
|
14 let i = 0; |
|
15 |
|
16 while (end > start) { |
|
17 i = start + (end - start >> 1); |
|
18 let value = arr[i]; |
|
19 |
|
20 if (value < target) |
|
21 start = i+1; |
|
22 else if (value > target) |
|
23 end = i-1; |
|
24 else |
|
25 break; |
|
26 } |
|
27 if (start == end) |
|
28 i = start; |
|
29 |
|
30 return (!(i < 0 || i >= arr.length) && arr[i] == target); |
|
31 } |
|
32 |
|
33 // checkContents: Check whether the PrefixSet pset contains |
|
34 // the prefixes in the passed array. |
|
35 function checkContents(pset, prefixes) { |
|
36 var outcount = {}, outset = {}; |
|
37 outset = pset.getPrefixes(outcount); |
|
38 let inset = prefixes; |
|
39 do_check_eq(inset.length, outset.length); |
|
40 inset.sort(function(x,y) x - y); |
|
41 for (let i = 0; i < inset.length; i++) { |
|
42 do_check_eq(inset[i], outset[i]); |
|
43 } |
|
44 } |
|
45 |
|
46 function wrappedProbe(pset, prefix) { |
|
47 return pset.contains(prefix); |
|
48 }; |
|
49 |
|
50 // doRandomLookups: we use this to test for false membership with random input |
|
51 // over the range of prefixes (unsigned 32-bits integers). |
|
52 // pset: a nsIUrlClassifierPrefixSet to test. |
|
53 // prefixes: an array of prefixes supposed to make up the prefix set. |
|
54 // N: number of random lookups to make. |
|
55 function doRandomLookups(pset, prefixes, N) { |
|
56 for (let i = 0; i < N; i++) { |
|
57 let randInt = prefixes[0]; |
|
58 while (arrContains(prefixes, randInt)) |
|
59 randInt = Math.floor(Math.random() * Math.pow(2, 32)); |
|
60 |
|
61 do_check_false(wrappedProbe(pset, randInt)); |
|
62 } |
|
63 } |
|
64 |
|
65 // doExpectedLookups: we use this to test expected membership. |
|
66 // pset: a nsIUrlClassifierPrefixSet to test. |
|
67 // prefixes: |
|
68 function doExpectedLookups(pset, prefixes, N) { |
|
69 for (let i = 0; i < N; i++) { |
|
70 prefixes.forEach(function (x) { |
|
71 dump("Checking " + x + "\n"); |
|
72 do_check_true(wrappedProbe(pset, x)); |
|
73 }); |
|
74 } |
|
75 } |
|
76 |
|
77 // testBasicPset: A very basic test of the prefix set to make sure that it |
|
78 // exists and to give a basic example of its use. |
|
79 function testBasicPset() { |
|
80 let pset = Cc["@mozilla.org/url-classifier/prefixset;1"] |
|
81 .createInstance(Ci.nsIUrlClassifierPrefixSet); |
|
82 let prefixes = [2,50,100,2000,78000,1593203]; |
|
83 pset.setPrefixes(prefixes, prefixes.length); |
|
84 |
|
85 do_check_true(wrappedProbe(pset, 100)); |
|
86 do_check_false(wrappedProbe(pset, 100000)); |
|
87 do_check_true(wrappedProbe(pset, 1593203)); |
|
88 do_check_false(wrappedProbe(pset, 999)); |
|
89 do_check_false(wrappedProbe(pset, 0)); |
|
90 |
|
91 |
|
92 checkContents(pset, prefixes); |
|
93 } |
|
94 |
|
95 function testDuplicates() { |
|
96 let pset = Cc["@mozilla.org/url-classifier/prefixset;1"] |
|
97 .createInstance(Ci.nsIUrlClassifierPrefixSet); |
|
98 let prefixes = [1,1,2,2,2,3,3,3,3,3,3,5,6,6,7,7,9,9,9]; |
|
99 pset.setPrefixes(prefixes, prefixes.length); |
|
100 |
|
101 do_check_true(wrappedProbe(pset, 1)); |
|
102 do_check_true(wrappedProbe(pset, 2)); |
|
103 do_check_true(wrappedProbe(pset, 5)); |
|
104 do_check_true(wrappedProbe(pset, 9)); |
|
105 do_check_false(wrappedProbe(pset, 4)); |
|
106 do_check_false(wrappedProbe(pset, 8)); |
|
107 |
|
108 |
|
109 checkContents(pset, prefixes); |
|
110 } |
|
111 |
|
112 function testSimplePset() { |
|
113 let pset = newPset(); |
|
114 let prefixes = [1,2,100,400,123456789]; |
|
115 pset.setPrefixes(prefixes, prefixes.length); |
|
116 |
|
117 doRandomLookups(pset, prefixes, 100); |
|
118 doExpectedLookups(pset, prefixes, 1); |
|
119 |
|
120 |
|
121 checkContents(pset, prefixes); |
|
122 } |
|
123 |
|
124 function testReSetPrefixes() { |
|
125 let pset = newPset(); |
|
126 let prefixes = [1, 5, 100, 1000, 150000]; |
|
127 pset.setPrefixes(prefixes, prefixes.length); |
|
128 |
|
129 doExpectedLookups(pset, prefixes, 1); |
|
130 |
|
131 let secondPrefixes = [12, 50, 300, 2000, 5000, 200000]; |
|
132 pset.setPrefixes(secondPrefixes, secondPrefixes.length); |
|
133 |
|
134 doExpectedLookups(pset, secondPrefixes, 1); |
|
135 for (let i = 0; i < prefixes.length; i++) { |
|
136 do_check_false(wrappedProbe(pset, prefixes[i])); |
|
137 } |
|
138 |
|
139 |
|
140 checkContents(pset, secondPrefixes); |
|
141 } |
|
142 |
|
143 function testLargeSet() { |
|
144 let N = 1000; |
|
145 let arr = []; |
|
146 |
|
147 for (let i = 0; i < N; i++) { |
|
148 let randInt = Math.floor(Math.random() * Math.pow(2, 32)); |
|
149 arr.push(randInt); |
|
150 } |
|
151 |
|
152 arr.sort(function(x,y) x - y); |
|
153 |
|
154 let pset = newPset(); |
|
155 pset.setPrefixes(arr, arr.length); |
|
156 |
|
157 doExpectedLookups(pset, arr, 1); |
|
158 doRandomLookups(pset, arr, 1000); |
|
159 |
|
160 checkContents(pset, arr); |
|
161 } |
|
162 |
|
163 function testTinySet() { |
|
164 let pset = Cc["@mozilla.org/url-classifier/prefixset;1"] |
|
165 .createInstance(Ci.nsIUrlClassifierPrefixSet); |
|
166 let prefixes = [1]; |
|
167 pset.setPrefixes(prefixes, prefixes.length); |
|
168 |
|
169 do_check_true(wrappedProbe(pset, 1)); |
|
170 do_check_false(wrappedProbe(pset, 100000)); |
|
171 checkContents(pset, prefixes); |
|
172 |
|
173 prefixes = []; |
|
174 pset.setPrefixes(prefixes, prefixes.length); |
|
175 do_check_false(wrappedProbe(pset, 1)); |
|
176 checkContents(pset, prefixes); |
|
177 } |
|
178 |
|
179 let tests = [testBasicPset, |
|
180 testSimplePset, |
|
181 testReSetPrefixes, |
|
182 testLargeSet, |
|
183 testDuplicates, |
|
184 testTinySet]; |
|
185 |
|
186 function run_test() { |
|
187 // None of the tests use |executeSoon| or any sort of callbacks, so we can |
|
188 // just run them in succession. |
|
189 for (let i = 0; i < tests.length; i++) { |
|
190 dump("Running " + tests[i].name + "\n"); |
|
191 tests[i](); |
|
192 } |
|
193 } |