Web Inspector: Quick Open fails to match pattern "bB" in file "abBc"
[WebKit-https.git] / LayoutTests / inspector / unit-tests / resource-query-controller.html
1 <!doctype html>
2 <html>
3 <head>
4 <script src="../../http/tests/inspector/resources/inspector-test.js"></script>
5 <script>
6 function test()
7 {
8     let suite = InspectorTest.createSyncSuite("ResourceQueryController");
9
10     suite.addTestCase({
11         name: "FindSpecialCharacterIndices",
12         description: "Should correctly find special filename characters.",
13         test: function() {
14             let matcher = new WebInspector.ResourceQueryController;
15             let tests = [
16                 {
17                     filename: "Abcd",
18                     expected: "^"
19                 },
20                 {
21                     filename: "ABCDE",
22                     expected: "^"
23                 },
24                 {
25                     filename: "abcdef",
26                     expected: "^",
27                 },
28                 {
29                     filename: "abc-def",
30                     expected: "^  ^^",
31                 },
32                 {
33                     filename: "abc---def",
34                     expected: "^  ^^^^",
35                 },
36                 {
37                     filename: "a-bc_de.f",
38                     expected: "^^^ ^^ ^^",
39                 },
40                 {
41                     filename: "AxBxCxDxExFx",
42                     expected: "^ ^ ^ ^ ^ ^",
43                 },
44                 {
45                     filename: "ab-c_d.ef",
46                     expected: "^ ^^^^^^",
47                 },
48                 {
49                     filename: "AxBxCxdxexDxyxEF",
50                     expected: "^ ^ ^     ^   ^",
51                 },
52             ];
53
54             function createSpecialMask(filename, specialIndices) {
55                 let mask = " ".repeat(filename.length);
56                 specialIndices.forEach((index) => {
57                     mask = mask.substr(0, index) + "^" + mask.substr(index + 1);
58                 });
59                 return mask.trim();
60             }
61
62             for (let {filename, expected} of tests) {
63                 let actual = createSpecialMask(filename, matcher._findSpecialCharacterIndices(filename));
64                 InspectorTest.expectThat(actual === expected, "Result should match expected special indices.");
65             }
66         }
67     });
68
69     suite.addTestCase({
70         name: "ExecuteQueryAgainstNoResources",
71         description: "Should return no results if no resources were added to the controller.",
72         test: function() {
73             let matcher = new WebInspector.ResourceQueryController;
74             let results = matcher.executeQuery("abcde");
75             InspectorTest.expectThat(!results.length, "Should return no results.")
76         }
77     });
78
79     suite.addTestCase({
80         name: "ExecuteWhitespaceQueryOrEmptyQuery",
81         description: "Empty queries and queries containing only whitespace should return no results.",
82         test: function() {
83             const whitespaceCharacters = " \t\r\n";
84             let matcher = new WebInspector.ResourceQueryController;
85             matcher.addResource(new WebInspector.Resource("abcde"));
86
87             for (let query of whitespaceCharacters) {
88                 let results = matcher.executeQuery(query);
89                 InspectorTest.expectThat(!results.length, "Whitespace query should return no results.");
90             }
91
92             let results = matcher.executeQuery("");
93             InspectorTest.expectThat(!results.length, "Empty query should return no results.");
94         }
95     });
96
97     suite.addTestCase({
98         name: "ExecuteQueryContainingWhitespace",
99         description: "Whitespace within a query should be ignored.",
100         test: function() {
101             let matcher = new WebInspector.ResourceQueryController;
102             matcher.addResource(new WebInspector.Resource("abcde"));
103
104             for (let query of [" abcde", "abcde ", " abcde ", "a b c d e", "a  b  c  d  e"]) {
105                 let results = matcher.executeQuery(query);
106                 InspectorTest.expectThat(results.length === 1, "Should match one result.");
107             }
108         }
109     });
110
111     suite.addTestCase({
112         name: "ExecuteQueryMatchNone",
113         description: "Should not find a match.",
114         test: function() {
115             let matcher = new WebInspector.ResourceQueryController;
116             let tests = [
117                 {query: "abcde", filename: "abcd"},
118                 {query: "abcd-", filename: "abcde"},
119                 {query: "abcde", filename: "abced"},
120             ];
121
122             for (let {query, filename} of tests) {
123                 matcher.reset();
124                 matcher.addResource(new WebInspector.Resource(filename));
125                 let results = matcher.executeQuery(query);
126                 InspectorTest.expectThat(!results.length, `Query "${query}" shouldn't match "${filename}".`);
127             }
128         }
129     });
130
131     suite.addTestCase({
132         name: "ExecuteQueryMatchesExpectedCharacters",
133         description: "Should match the expected query characters.",
134         test: function() {
135             let matcher = new WebInspector.ResourceQueryController;
136             let tests = [
137                 {
138                     query: "abcd",
139                     filename: "abcde",
140                     expected: "abcd"
141                 },
142                 {
143                     query: " abcd",
144                     filename: "abcde",
145                     expected: "abcd"
146                 },
147                 {
148                     query: "abcd ",
149                     filename: "abcde",
150                     expected: "abcd"
151                 },
152                 {
153                     query: "a b c d",
154                     filename: "abcde",
155                     expected: "abcd"
156                 },
157                 {
158                     query: "a-bcde",
159                     filename: "abcde-abcde",
160                     expected: "a    - bcde"
161                 },
162                 {
163                     query: "abcde",
164                     filename: "AaBbCcDdEe",
165                     expected: "A B C D E"
166                 },
167                 {
168                     query: "abcde",
169                     filename: "AbcdBcdCdDe",
170                     expected: "A   B  C De"
171                 },
172                 {
173                     query: "abcdex",
174                     filename: "AxBxCxdxexDxyxEF",
175                     expected: "A B C d ex"
176                 },
177                 {
178                     query: "bc",
179                     filename: "abCd",
180                     expected: " bC"
181                 },
182                 {
183                     query: "bb",
184                     filename: "abBc",
185                     expected: " bB"
186                 }
187             ];
188
189             for (let {query, filename, expected} of tests) {
190                 matcher.reset();
191                 matcher.addResource(new WebInspector.Resource(filename));
192
193                 let results = matcher.executeQuery(query);
194                 InspectorTest.assert(results.length === 1, "Should return exactly one match.");
195                 let actual = results.length ? results[0].__test_createMatchesMask() : null;
196                 InspectorTest.expectThat(actual === expected, `Query "${query}" should match "${expected}" in "${filename}".`);
197             }
198         }
199     });
200
201     // Generator for creating a sequence of case permutations for a string.
202     // Example: "xx" => ["xx", "Xx", "xX", "XX"]
203     function *casePermutations(string) {
204         let permutationCount = Math.pow(2, string.length);
205         InspectorTest.assert(permutationCount !== Infinity, "String length exceeds permutations limit.");
206         if (permutationCount === Infinity)
207             return;
208
209         let index = 0;
210         while (index < permutationCount) {
211             let result = "";
212             for (let i = 0; i < string.length; ++i)
213                 result += (index & (1 << i)) ? string[i].toUpperCase() : string[i].toLowerCase();
214
215             index++;
216             yield result;
217         }
218
219         return;
220     }
221
222     suite.addTestCase({
223         name: "ExecuteQueryShouldIgnoreCase",
224         description: "Queries that differ only in case should return identical results.",
225         test: function() {
226             let matcher = new WebInspector.ResourceQueryController;
227             let tests = [
228                 {
229                     query: "abcd",
230                     filename: "abcde",
231                     expected: "abcd"
232                 },
233                 {
234                     query: "abcde",
235                     filename: "AaBbCcDdEe",
236                     expected: "A B C D E"
237                 },
238                 {
239                     query: "abcde",
240                     filename: "AbcdBcdCdDe",
241                     expected: "A   B  C De"
242                 },
243                 {
244                     query: "abcdex",
245                     filename: "AxBxCxdxexDxyxEF",
246                     expected: "A B C d ex"
247                 },
248                 {
249                     query: "bc",
250                     filename: "abCd",
251                     expected: " bC"
252                 },
253             ];
254
255             for (let {query, filename, expected} of tests) {
256                 InspectorTest.log(`All case permutations of query "${query}" should match "${expected}" in "${filename}".`);
257
258                 matcher.reset();
259                 matcher.addResource(new WebInspector.Resource(filename));
260
261                 for (let queryPermutation of casePermutations(query)) {
262                     let results = matcher.executeQuery(queryPermutation);
263                     let actual = results.length === 1 ? results[0].__test_createMatchesMask() : "";
264                     InspectorTest.expectThat(expected === actual, `Permutation "${queryPermutation}".`);
265                 }
266             }
267         }
268     });
269
270     suite.addTestCase({
271         name: "ExecuteQueryGeneralRankings",
272         description: "Check that query results are ranked by descending relevance.",
273         test: function() {
274             let filenames = ["AxBxCxDxEx", "AbCdE", "AbcDe", "AxbcDe", "AxbxcDe", "abcde", "xabcde"]; // Filenames in order of descending rank.
275             let matcher = new WebInspector.ResourceQueryController;
276             filenames.forEach((filename) => matcher.addResource(new WebInspector.Resource(filename)));
277
278             let query = "abcde";
279             let results = matcher.executeQuery(query);
280             let resultFilenames = results.map((filename) => filename.resource.displayName);
281             InspectorTest.expectThat(Object.shallowEqual(resultFilenames, filenames), "Results should be ranked by descending relevancy.");
282         }
283     });
284
285     suite.addTestCase({
286         name: "ExecuteQueryPositionRankings",
287         description: "Check that matches close to the beginning of the filename rank higher.",
288         test: function() {
289             let filenames = ["BxCxDx", "AxBxCxDx", "xxxAxxxBxxxCxxxD", "bcd", "abcd"]; // Filenames in order of descending rank.
290             let matcher = new WebInspector.ResourceQueryController;
291             filenames.forEach((filename) => matcher.addResource(new WebInspector.Resource(filename)));
292
293             let query = "bcd";
294             let results = matcher.executeQuery(query);
295             let resultFilenames = results.map((result) => result.resource.displayName);
296             InspectorTest.expectThat(Object.shallowEqual(resultFilenames, filenames), "Results should be ranked by descending relevancy.");
297         }
298     });
299
300     suite.addTestCase({
301         name: "GetMatchingTextRanges",
302         description: "Check that query result TextRanges are correct.",
303         test: function() {
304             function textRange(start, end) {
305                 return new WebInspector.TextRange(0, start, 0, end);
306             }
307
308             let matcher = new WebInspector.ResourceQueryController;
309             let tests = [
310                 {filename: "a", ranges: []},
311                 {filename: "abcde", ranges: [textRange(0, 5)]},
312                 {filename: "AxBxCxDe", ranges: [textRange(0, 1), textRange(2, 3), textRange(4, 5), textRange(6, 8)]},
313             ];
314
315             for (let {filename, ranges} of tests) {
316                 matcher.reset();
317                 matcher.addResource(new WebInspector.Resource(filename));
318
319                 let results = matcher.executeQuery("abcde");
320                 let resultTextRanges = results.length ? results[0].matchingTextRanges : [];
321                 InspectorTest.expectThat(JSON.stringify(resultTextRanges) === JSON.stringify(ranges), "Result TextRanges should match the expected ranges.");
322             }
323         }
324     });
325
326     suite.runTestCasesAndFinish();
327 }
328 </script>
329 </head>
330 <body onload="runTest()">
331     <p>Testing WebInspector.ResourceQueryController.</p>
332 </body>
333 </html>