| <!doctype html> |
| <html> |
| <head> |
| <script src="../../http/tests/inspector/resources/inspector-test.js"></script> |
| <script> |
| function test() |
| { |
| let suite = InspectorTest.createSyncSuite("ResourceQueryController"); |
| |
| suite.addTestCase({ |
| name: "FindSpecialCharacterIndices.DisplayName", |
| description: "Should correctly find special filename characters in the displayName.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| let tests = [ |
| { |
| filename: "Abcd", |
| expected: "^ ", |
| }, |
| { |
| filename: "ABCDE", |
| expected: "^ ", |
| }, |
| { |
| filename: "abcdef", |
| expected: "^ ", |
| }, |
| { |
| filename: "abc-def", |
| expected: "^ ^^ ", |
| }, |
| { |
| filename: "abc---def", |
| expected: "^ ^^^^ ", |
| }, |
| { |
| filename: "a-bc_de.f", |
| expected: "^^^ ^^ ^^", |
| }, |
| { |
| filename: "AxBxCxDxExFx", |
| expected: "^ ^ ^ ^ ^ ^ ", |
| }, |
| { |
| filename: "ab-c_d.ef", |
| expected: "^ ^^^^^^ ", |
| }, |
| { |
| filename: "AxBxCxdxexDxyxEF", |
| expected: "^ ^ ^ ^ ^ ", |
| }, |
| ]; |
| |
| function createSpecialMask(filename, specialIndices) { |
| let mask = " ".repeat(filename.length); |
| specialIndices.forEach((index) => { |
| mask = mask.substr(0, index) + "^" + mask.substr(index + 1); |
| }); |
| return mask; |
| } |
| |
| for (let {filename, expected} of tests) { |
| let actual = createSpecialMask(filename, matcher._findSpecialCharacterIndicesInDisplayName(filename)); |
| InspectorTest.expectEqual(actual, expected, `The special characters in "${filename}" should match.`); |
| } |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "FindSpecialCharacterIndices.URL", |
| description: "Should correctly find special filename characters in the url.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| let tests = [ |
| { |
| filename: "aBcd", |
| expected: "^^ ", |
| }, |
| { |
| filename: "/aBcd", |
| expected: "^^^ ", |
| }, |
| { |
| filename: "aBcd_dEfg", |
| expected: "^^ ^^^ ", |
| }, |
| { |
| filename: "/aBcd_dEfg", |
| expected: "^^^ ^^^ ", |
| }, |
| { |
| filename: "aBcd-dEfg", |
| expected: "^^ ^^^ ", |
| }, |
| { |
| filename: "/aBcd-dEfg", |
| expected: "^^^ ^^^ ", |
| }, |
| { |
| filename: "aBcd.dEfg", |
| expected: "^^ ^^^ ", |
| }, |
| { |
| filename: "/aBcd.dEfg", |
| expected: "^^^ ^^^ ", |
| }, |
| { |
| filename: "aBcd/dEfg", |
| expected: "^^ ^^^ ", |
| }, |
| { |
| filename: "/aBcd/dEfg", |
| expected: "^^^ ^^^ ", |
| }, |
| { |
| filename: "aBcd/dEfg_hIjk-lMno.pQrs", |
| expected: "^^ ^^^ ^^^ ^^^ ^^^ ", |
| }, |
| { |
| filename: "/aBcd/dEfg_hIjk-lMno.pQrs", |
| expected: "^^^ ^^^ ^^^ ^^^ ^^^ ", |
| }, |
| ]; |
| |
| function createSpecialMask(filename, specialIndices) { |
| let mask = " ".repeat(filename.length); |
| specialIndices.forEach((index) => { |
| mask = mask.substr(0, index) + "^" + mask.substr(index + 1); |
| }); |
| return mask; |
| } |
| |
| for (let {filename, expected} of tests) { |
| let actual = createSpecialMask(filename, matcher._findSpecialCharacterIndicesInURL(filename)); |
| InspectorTest.expectEqual(actual, expected, `The special characters in "${filename}" should match.`); |
| } |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryAgainstNoResources", |
| description: "Should return no results if no resources were added to the controller.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| let results = matcher.executeQuery("abcde"); |
| InspectorTest.expectThat(!results.length, "Should return no results.") |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteWhitespaceQueryOrEmptyQuery", |
| description: "Empty queries and queries containing only whitespace should return no results.", |
| test() { |
| const whitespaceCharacters = " \t\r\n"; |
| let matcher = new WI.ResourceQueryController; |
| matcher.addResource(new WI.Resource("abcde")); |
| |
| for (let query of whitespaceCharacters) { |
| let results = matcher.executeQuery(query); |
| InspectorTest.expectThat(!results.length, "Whitespace query should return no results."); |
| } |
| |
| let results = matcher.executeQuery(""); |
| InspectorTest.expectThat(!results.length, "Empty query should return no results."); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryContainingWhitespace", |
| description: "Whitespace within a query should be ignored.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| matcher.addResource(new WI.Resource("abcde")); |
| |
| for (let query of [" abcde", "abcde ", " abcde ", "a b c d e", "a b c d e"]) { |
| let results = matcher.executeQuery(query); |
| InspectorTest.expectEqual(results.length, 1, "Should match one result."); |
| } |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryMatchNone", |
| description: "Should not find a match.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| let tests = [ |
| {query: "abcde", filename: "abcd"}, |
| {query: "abcd-", filename: "abcde"}, |
| {query: "abcde", filename: "abced"}, |
| ]; |
| |
| for (let {query, filename} of tests) { |
| matcher.reset(); |
| matcher.addResource(new WI.Resource(filename)); |
| let results = matcher.executeQuery(query); |
| InspectorTest.expectThat(!results.length, `Query "${query}" shouldn't match "${filename}".`); |
| } |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryMatchesExpectedCharacters", |
| description: "Should match the expected query characters.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| let tests = [ |
| { |
| query: "abcd", |
| filename: "abcde", |
| expected: "abcd" |
| }, |
| { |
| query: " abcd", |
| filename: "abcde", |
| expected: "abcd" |
| }, |
| { |
| query: "abcd ", |
| filename: "abcde", |
| expected: "abcd" |
| }, |
| { |
| query: "a b c d", |
| filename: "abcde", |
| expected: "abcd" |
| }, |
| { |
| query: "a-bcde", |
| filename: "abcde-abcde", |
| expected: "a - bcde" |
| }, |
| { |
| query: "abcde", |
| filename: "AaBbCcDdEe", |
| expected: "A B C D E" |
| }, |
| { |
| query: "abcde", |
| filename: "AbcdBcdCdDe", |
| expected: "A B C De" |
| }, |
| { |
| query: "abcdex", |
| filename: "AxBxCxdxexDxyxEF", |
| expected: "A B C d ex" |
| }, |
| { |
| query: "bc", |
| filename: "abCd", |
| expected: " bC" |
| }, |
| { |
| query: "bb", |
| filename: "abBc", |
| expected: " bB" |
| } |
| ]; |
| |
| for (let {query, filename, expected} of tests) { |
| matcher.reset(); |
| matcher.addResource(new WI.Resource(filename)); |
| |
| let results = matcher.executeQuery(query); |
| InspectorTest.assert(results.length === 1, "Should return exactly one match."); |
| let actual = results.length ? results[0].__test_createMatchesMask() : null; |
| InspectorTest.expectEqual(actual, expected, `Query "${query}" should match "${expected}" in "${filename}".`); |
| } |
| } |
| }); |
| |
| // Generator for creating a sequence of case permutations for a string. |
| // Example: "xx" => ["xx", "Xx", "xX", "XX"] |
| function *casePermutations(string) { |
| let permutationCount = Math.pow(2, string.length); |
| InspectorTest.assert(permutationCount !== Infinity, "String length exceeds permutations limit."); |
| if (permutationCount === Infinity) |
| return; |
| |
| let index = 0; |
| while (index < permutationCount) { |
| let result = ""; |
| for (let i = 0; i < string.length; ++i) |
| result += (index & (1 << i)) ? string[i].toUpperCase() : string[i].toLowerCase(); |
| |
| index++; |
| yield result; |
| } |
| |
| return; |
| } |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryShouldIgnoreCase", |
| description: "Queries that differ only in case should return identical results.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| let tests = [ |
| { |
| query: "abcd", |
| filename: "abcde", |
| expected: "abcd" |
| }, |
| { |
| query: "abcde", |
| filename: "AaBbCcDdEe", |
| expected: "A B C D E" |
| }, |
| { |
| query: "abcde", |
| filename: "AbcdBcdCdDe", |
| expected: "A B C De" |
| }, |
| { |
| query: "abcdex", |
| filename: "AxBxCxdxexDxyxEF", |
| expected: "A B C d ex" |
| }, |
| { |
| query: "bc", |
| filename: "abCd", |
| expected: " bC" |
| }, |
| ]; |
| |
| for (let {query, filename, expected} of tests) { |
| InspectorTest.log(`All case permutations of query "${query}" should match "${expected}" in "${filename}".`); |
| |
| matcher.reset(); |
| matcher.addResource(new WI.Resource(filename)); |
| |
| for (let queryPermutation of casePermutations(query)) { |
| let results = matcher.executeQuery(queryPermutation); |
| let actual = results.length === 1 ? results[0].__test_createMatchesMask() : ""; |
| InspectorTest.expectEqual(expected, actual, `Permutation "${queryPermutation}".`); |
| } |
| } |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryGeneralRankings", |
| description: "Check that query results are ranked by descending relevance.", |
| test() { |
| let filenames = ["AbCdE", "AbcDe", "abcde", "AxbcDe", "AxBxCxDxEx", "AxbxcDe", "xabcde"]; // Filenames in order of descending rank. |
| let matcher = new WI.ResourceQueryController; |
| filenames.forEach((filename) => matcher.addResource(new WI.Resource(filename))); |
| |
| let query = "abcde"; |
| let results = matcher.executeQuery(query); |
| let resultFilenames = results.map((filename) => filename.resource.displayName); |
| InspectorTest.expectShallowEqual(resultFilenames, filenames, "Results should be ranked by descending relevancy."); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryPositionRankings", |
| description: "Check that matches close to the beginning of the filename rank higher.", |
| test() { |
| let filenames = ["bcd", "BxCxDx", "AxBxCxDx", "abcd", "xxxAxxxBxxxCxxxD"]; // Filenames in order of descending rank. |
| let matcher = new WI.ResourceQueryController; |
| filenames.forEach((filename) => matcher.addResource(new WI.Resource(filename))); |
| |
| let query = "bcd"; |
| let results = matcher.executeQuery(query); |
| let resultFilenames = results.map((result) => result.resource.displayName); |
| InspectorTest.expectShallowEqual(resultFilenames, filenames, "Results should be ranked by descending relevancy."); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ExecuteQueryConsecutiveRankings", |
| description: "Check that consecutive matches rank higher.", |
| test() { |
| let matcher = new WI.ResourceQueryController; |
| let tests = [ |
| { |
| filenames: ["Color.js", "HighlightColor.js", "CxxOxxLxxOxxR.js"], |
| query: "color", |
| }, |
| { |
| filenames: ["ContentView.js", "CxxVxxIxxExxW.js"], |
| query: "cview", |
| }, |
| { |
| filenames: ["HeapSnapshot.js", "HxxSxxHxxOxxT.js"], |
| query: "hshot", |
| }, |
| ]; |
| |
| let passed = true; |
| for (let {filenames, query} of tests) { |
| matcher.reset(); |
| filenames.forEach((filename) => matcher.addResource(new WI.Resource(filename))); |
| |
| let results = matcher.executeQuery(query); |
| let resultFilenames = results.map((result) => result.resource.displayName); |
| |
| passed = passed && Object.shallowEqual(resultFilenames, filenames); |
| } |
| |
| InspectorTest.expectThat(passed, "Results should be ranked by descending relevancy."); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "GetMatchingTextRanges", |
| description: "Check that query result TextRanges are correct.", |
| test() { |
| function textRange(start, end) { |
| return new WI.TextRange(0, start, 0, end); |
| } |
| |
| let matcher = new WI.ResourceQueryController; |
| let tests = [ |
| {filename: "a", ranges: []}, |
| {filename: "abcde", ranges: [textRange(0, 5)]}, |
| {filename: "AxBxCxDe", ranges: [textRange(0, 1), textRange(2, 3), textRange(4, 5), textRange(6, 8)]}, |
| ]; |
| |
| for (let {filename, ranges} of tests) { |
| matcher.reset(); |
| matcher.addResource(new WI.Resource(filename)); |
| |
| let results = matcher.executeQuery("abcde"); |
| let resultTextRanges = results.length ? results[0].matchingTextRanges : []; |
| InspectorTest.expectEqual(JSON.stringify(resultTextRanges), JSON.stringify(ranges), "Result TextRanges should match the expected ranges."); |
| } |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "QueryMatchesExtension", |
| description: "Test case for when a character from the query is found in the extension of the resource.", |
| test() { |
| const query = "TestCase"; |
| const filenames = ["TestCase.123", "TestCase.a", "TestCase.b"]; |
| |
| let matcher = new WI.ResourceQueryController; |
| for (let filename of filenames) |
| matcher.addResource(new WI.Resource(filename)); |
| |
| let results = matcher.executeQuery(query); |
| let resultFilenames = results.map((result) => result.resource.displayName); |
| InspectorTest.expectShallowEqual(resultFilenames, filenames, "All resources should be matched."); |
| } |
| }); |
| |
| suite.runTestCasesAndFinish(); |
| } |
| </script> |
| </head> |
| <body onload="runTest()"> |
| <p>Testing WI.ResourceQueryController.</p> |
| </body> |
| </html> |