| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| (async function() { |
| TestRunner.addResult(`Tests that console correctly finds suggestions in complicated cases.\n`); |
| |
| await TestRunner.loadModule('console_test_runner'); |
| await TestRunner.showPanel('console'); |
| |
| await TestRunner.evaluateInPagePromise(` |
| function templateString() |
| { |
| console.log("The template string should not run and you should not see this log"); |
| return { |
| shouldNotFindThis:56 |
| }; |
| } |
| function shouldNotFindThisFunction() { } |
| function shouldFindThisFunction() { } |
| window["should not find this"] = true; |
| window._foo = true; |
| var myMap = new Map([['first', 1], ['second', 2], ['third', 3], ['shouldNotFindThis', 4]]); |
| var complicatedObject = { |
| 'foo-bar': true, |
| '"double-qouted"': true, |
| "'single-qouted'": true, |
| "notDangerous();": true |
| } |
| var cantTouchThis = false; |
| function dontRunThis() { |
| cantTouchThis = true; |
| } |
| function stall() { |
| while(true); |
| } |
| var thePrefix = true; |
| var thePrefixAndTheSuffix = true; |
| class ClassWithMethod { |
| method(){} |
| } |
| const objWithMethod = new ClassWithMethod(); |
| objWithMethod.methodWithSuffix = true; |
| `); |
| |
| var consoleEditor; |
| |
| /** |
| * @param {string} text |
| * @param {!Array<string>} expected |
| * @param {boolean=} force |
| * @param {boolean=} reportDefault |
| */ |
| async function testCompletions(text, expected, force, reportDefault) { |
| var cursorPosition = text.indexOf('|'); |
| |
| if (cursorPosition < 0) |
| cursorPosition = Infinity; |
| |
| consoleEditor.setText(text.replace('|', '')); |
| consoleEditor.setSelection(TextUtils.TextRange.createFromLocation(0, cursorPosition)); |
| consoleEditor._autocompleteController.autocomplete(force); |
| var message = |
| 'Checking \'' + text.replace('\n', '\\n').replace('\r', '\\r') + '\''; |
| |
| if (force) |
| message += ' forcefully'; |
| |
| TestRunner.addResult(message); |
| const suggestions = await TestRunner.addSnifferPromise( |
| consoleEditor._autocompleteController, '_onSuggestionsShownForTest'); |
| var completions = |
| new Map(suggestions.map(suggestion => [suggestion, suggestion.text])) |
| .inverse(); |
| |
| for (const suggestionText of completions.keysArray()) { |
| const size = completions.get(suggestionText).size; |
| if (size > 1) |
| TestRunner.addResult(`ERROR! ${size} duplicates found for '${suggestionText}'!`) |
| } |
| |
| for (var i = 0; i < expected.length; i++) { |
| if (completions.has(expected[i])) { |
| for (var completion of completions.get(expected[i])) { |
| if (completion.title) |
| TestRunner.addResult( |
| 'Found: ' + expected[i] + ', displayed as ' + completion.title); |
| else |
| TestRunner.addResult('Found: ' + expected[i]); |
| } |
| } else { |
| TestRunner.addResult('Not Found: ' + expected[i]); |
| } |
| } |
| |
| if (reportDefault) { |
| const defaultSuggestion = suggestions.reduce((a, b) => (a.priority || 0) >= (b.priority || 0) ? a : b); |
| if (defaultSuggestion.title) |
| TestRunner.addResult(`Default suggestion: ${defaultSuggestion.text}, displayed as ${defaultSuggestion.title}`); |
| else |
| TestRunner.addResult(`Default suggestion: ${defaultSuggestion.text}`); |
| } |
| |
| if (await TestRunner.evaluateInPagePromise('cantTouchThis') !== false) { |
| TestRunner.addResult('ERROR! Side effects were detected!'); |
| await TestRunner.evaluateInPagePromise('cantTouchThis = false'); |
| } |
| |
| TestRunner.addResult(''); |
| } |
| |
| function sequential(tests) { |
| var promise = Promise.resolve(); |
| |
| for (var i = 0; i < tests.length; i++) |
| promise = promise.then(tests[i]); |
| |
| return promise; |
| } |
| |
| sequential([ |
| () => ConsoleTestRunner.waitUntilConsoleEditorLoaded().then( |
| e => consoleEditor = e), |
| () => testCompletions('window.|foo', ['_foo']), |
| () => testCompletions('window._|foo', ['_foo'], false), |
| () => testCompletions('window._|foo', ['_foo'], true), |
| () => testCompletions('window.do', ['document']), |
| () => testCompletions('win', ['window']), |
| () => testCompletions('window["doc', ['"document"]']), |
| () => testCompletions('window["document"].bo', ['body']), |
| () => testCompletions('window["document"]["body"].textC', ['textContent']), |
| () => testCompletions('document.body.inner', ['innerText', 'innerHTML']), |
| () => testCompletions('document["body"][window.do', ['document']), |
| () => testCompletions( |
| 'document["body"][window["document"].body.childNodes[0].text', |
| ['textContent']), |
| () => testCompletions('templateString`asdf`should', ['shouldNotFindThis']), |
| () => testCompletions('window.document.BODY', ['body']), |
| () => testCompletions('window.dOcUmE', ['document']), |
| () => testCompletions('window.node', ['NodeList', 'AudioNode', 'GainNode']), |
| () => testCompletions('32', ['Float32Array', 'Int32Array']), |
| () => testCompletions('window.32', ['Float32Array', 'Int32Array']), |
| () => testCompletions('', ['window'], false), |
| () => testCompletions('', ['window'], true), |
| () => testCompletions('"string g', ['getComputedStyle'], false), |
| () => testCompletions('`template string docu', ['document'], false), |
| () => testCompletions('`${do', ['document'], false), |
| () => testCompletions('// do', ['document'], false), |
| () => testCompletions('["should', ['shouldNotFindThisFunction']), |
| () => testCompletions('shou', ['should not find this']), |
| () => testCompletions('myMap.get(', ['"first")', '"second")', '"third")']), |
| () => testCompletions( |
| 'myMap.get(\'', ['\'first\')', '\'second\')', '\'third\')']), |
| () => testCompletions('myMap.set(\'firs', ['\'first\', ']), |
| () => testCompletions( |
| 'myMap.set(should', |
| [ |
| 'shouldFindThisFunction', 'shouldNotFindThis', '"shouldNotFindThis")' |
| ]), |
| () => testCompletions( |
| 'myMap.delete(\'', ['\'first\')', '\'second\')', '\'third\')']), |
| () => testCompletions('document. bo', ['body']), |
| () => testCompletions('document.\tbo', ['body']), |
| () => testCompletions('document.\nbo', ['body']), |
| () => testCompletions('document.\r\nbo', ['body']), |
| () => testCompletions('document [ \'bo', ['\'body\']']), |
| () => testCompletions('function hey(should', ['shouldNotFindThisFunction']), |
| () => testCompletions('var should', ['shouldNotFindThisFunction']), |
| () => testCompletions('document[[win', ['window']), |
| () => testCompletions('document[ [win', ['window']), |
| () => testCompletions('document[ [ win', ['window']), |
| () => testCompletions('I|mag', ['Image', 'Infinity']), |
| () => testCompletions('I|mage', ['Image', 'Infinity'], false), |
| () => testCompletions('I|mage', ['Image', 'Infinity'], true), |
| () => testCompletions('var x = (do|);', ['document']), |
| () => testCompletions('complicatedObject["foo', ['"foo-bar"]']), |
| () => testCompletions('complicatedObject["foo-', ['"foo-bar"]']), |
| () => testCompletions('complicatedObject["foo-bar', ['"foo-bar"]']), |
| () => |
| testCompletions('complicatedObject["\'sing', ['"\'single-qouted\'"]']), |
| () => testCompletions( |
| 'complicatedObject[\'\\\'sing', ['\'\\\'single-qouted\\\'\']']), |
| () => testCompletions( |
| 'complicatedObject["\'single-qou', ['"\'single-qouted\'"]']), |
| () => testCompletions( |
| 'complicatedObject["\\"double-qouted\\"', ['"\\"double-qouted\\""]']), |
| () => testCompletions( |
| 'complicatedObject["notDangerous();', ['"notDangerous();"]']), |
| () => testCompletions('queryOb', ['queryObjects']), |
| () => testCompletions('fun', ['function']), |
| () => testCompletions( |
| '"stringwithscary!@#$%^&*()\\"\'`~+-=".char', ['charAt']), |
| () => testCompletions('("hello" + "goodbye").char', ['charAt']), |
| () => testCompletions('({7: "string"})[3 + 4].char', ['charAt']), |
| () => testCompletions('cantTouchThis++; "string".char', ['charAt']), |
| () => testCompletions('cantTouchThis++ + "string".char', ['charAt']), |
| () => testCompletions('var x = "string".char', ['charAt']), |
| () => testCompletions('({abc: 123}).a', ['abc']), |
| () => testCompletions('{dontFindLabels: 123}.dont', ['dontFindLabels']), |
| () => testCompletions( |
| 'const x = 5; {dontFindLabels: 123}.dont', ['dontFindLabels']), |
| () => testCompletions('const x = {abc: 123}.a', ['abc']), |
| () => testCompletions('x = {abc: 123}.', ['abc']), |
| () => testCompletions('[1,2,3].j', ['join']), |
| () => testCompletions('document.body[{abc: "children"}.abc].', ['length']), |
| () => testCompletions('new Date.', ['UTC', 'toUTCString']), |
| () => testCompletions('new Date().', ['UTC', 'toUTCString']), |
| () => testCompletions('const x = {7: "hi"}[3+4].', ['anchor']), |
| () => testCompletions('["length"]["length"].', ['toExponential']), |
| () => testCompletions('(await "no completions").', ['toString']), |
| () => testCompletions('(++cantTouchThis).', []), |
| () => testCompletions('(cantTouchThis -= 2).', []), |
| () => testCompletions('new dontRunThis.', []), |
| () => testCompletions('new dontRunThis().', []), |
| () => testCompletions('(new dontRunThis).', []), |
| () => testCompletions('(dontRunThis`asdf`).', []), |
| () => testCompletions('dontRunThis().', []), |
| () => testCompletions('stall().', []), |
| () => testCompletions( |
| 'shouldNot|FindThisFunction()', ['shouldNotFindThisFunction']), |
| () => testCompletions('thePrefix', ['thePrefix', 'thePrefixAndTheSuffix']), |
| () => testCompletions('objWithMethod.method', ['method', 'methodWithSuffix'], false, true), |
| ]).then(TestRunner.completeTest); |
| })(); |