/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.engine.services.internal.correction; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.dart.engine.ast.AsExpression; import com.google.dart.engine.ast.AstFactory; import com.google.dart.engine.ast.AstNode; import com.google.dart.engine.ast.BinaryExpression; import com.google.dart.engine.ast.Block; import com.google.dart.engine.ast.BlockFunctionBody; import com.google.dart.engine.ast.ClassDeclaration; import com.google.dart.engine.ast.CompilationUnit; import com.google.dart.engine.ast.ConstructorDeclaration; import com.google.dart.engine.ast.Expression; import com.google.dart.engine.ast.ExpressionStatement; import com.google.dart.engine.ast.FunctionDeclaration; import com.google.dart.engine.ast.FunctionExpression; import com.google.dart.engine.ast.Identifier; import com.google.dart.engine.ast.IfStatement; import com.google.dart.engine.ast.InstanceCreationExpression; import com.google.dart.engine.ast.IntegerLiteral; import com.google.dart.engine.ast.MethodDeclaration; import com.google.dart.engine.ast.MethodInvocation; import com.google.dart.engine.ast.PrefixedIdentifier; import com.google.dart.engine.ast.SimpleIdentifier; import com.google.dart.engine.ast.Statement; import com.google.dart.engine.ast.VariableDeclaration; import com.google.dart.engine.ast.VariableDeclarationStatement; import com.google.dart.engine.context.AnalysisContext; import com.google.dart.engine.element.ClassElement; import com.google.dart.engine.element.CompilationUnitElement; import com.google.dart.engine.element.ConstructorElement; import com.google.dart.engine.element.Element; import com.google.dart.engine.element.ElementKind; import com.google.dart.engine.element.ExecutableElement; import com.google.dart.engine.element.FieldElement; import com.google.dart.engine.element.FunctionElement; import com.google.dart.engine.element.FunctionTypeAliasElement; import com.google.dart.engine.element.LocalVariableElement; import com.google.dart.engine.element.MethodElement; import com.google.dart.engine.element.ParameterElement; import com.google.dart.engine.element.PropertyAccessorElement; import com.google.dart.engine.element.TypeParameterElement; import com.google.dart.engine.internal.context.AnalysisContextImpl; import com.google.dart.engine.internal.context.TimestampedData; import com.google.dart.engine.scanner.TokenType; import com.google.dart.engine.services.change.Edit; import com.google.dart.engine.services.change.SourceChange; import com.google.dart.engine.services.internal.correction.CorrectionUtils.InsertDesc; import com.google.dart.engine.source.Source; import com.google.dart.engine.source.SourceFactory; import com.google.dart.engine.type.Type; import com.google.dart.engine.utilities.source.SourceRange; import com.google.dart.engine.utilities.source.SourceRangeFactory; import static com.google.dart.engine.ast.AstFactory.binaryExpression; import static com.google.dart.engine.ast.AstFactory.identifier; import static com.google.dart.engine.ast.AstFactory.label; import static com.google.dart.engine.ast.AstFactory.namedExpression; import static com.google.dart.engine.ast.AstFactory.postfixExpression; import static com.google.dart.engine.ast.AstFactory.prefixExpression; import static com.google.dart.engine.ast.AstFactory.propertyAccess; import static com.google.dart.engine.utilities.source.SourceRangeFactory.rangeStartEnd; import static com.google.dart.engine.utilities.source.SourceRangeFactory.rangeStartLength; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.lang.reflect.Method; import java.nio.CharBuffer; import java.util.List; import java.util.Set; public class CorrectionUtilsTest extends AbstractDartTest { private static void assert_getVariableNameSuggestions(Type expectedType, Expression expression, Set<String> nameSuggestExclude, String[] expected) { String[] suggestions = CorrectionUtils.getVariableNameSuggestions( expectedType, expression, nameSuggestExclude); assertThat(suggestions).isEqualTo(expected); } public void test_addEdit_badRange() throws Exception { parseTestUnit("// 12345"); Edit edit = new Edit(400, 3, "abc"); // mock SourceChange SourceChange change = mock(SourceChange.class); when(change.getSource()).thenReturn(testSource); // add Edit String description = "desc"; try { CorrectionUtils.addEdit(getAnalysisContext(), change, description, "234", edit); fail(); } catch (IllegalStateException e) { } // verify verify(change, never()).addEdit(edit, description); } public void test_addEdit_badRangeContent() throws Exception { parseTestUnit("// 12345"); Edit edit = new Edit(4, 3, "abc"); // mock SourceChange SourceChange change = mock(SourceChange.class); when(change.getSource()).thenReturn(testSource); // add Edit String description = "desc"; try { CorrectionUtils.addEdit(getAnalysisContext(), change, description, "err", edit); fail(); } catch (IllegalStateException e) { } // verify verify(change, never()).addEdit(edit, description); } public void test_addEdit_OK() throws Exception { parseTestUnit("// 12345"); Edit edit = new Edit(4, 3, "abc"); // mock SourceChange SourceChange change = mock(SourceChange.class); when(change.getSource()).thenReturn(testSource); // add Edit String description = "desc"; CorrectionUtils.addEdit(getAnalysisContext(), change, description, "234", edit); // verify verify(change).addEdit(edit, description); } public void test_allListsEqual_0() throws Exception { List<List<Integer>> lists = ImmutableList.<List<Integer>> of( Lists.newArrayList(0, 1, 2), Lists.newArrayList(0, -1, -2)); assertTrue(CorrectionUtils.allListsEqual(lists, 0)); assertFalse(CorrectionUtils.allListsEqual(lists, 1)); } public void test_allListsEqual_1() throws Exception { List<List<Integer>> lists = ImmutableList.<List<Integer>> of( Lists.newArrayList(-1, 0, 1, 2), Lists.newArrayList(1, 0, -1, -2), Lists.newArrayList(-10, 0, 10, 20)); assertFalse(CorrectionUtils.allListsEqual(lists, 0)); assertTrue(CorrectionUtils.allListsEqual(lists, 1)); } public void test_applyReplaceEdits() throws Exception { String s = "0123456789"; String result = CorrectionUtils.applyReplaceEdits( s, ImmutableList.of(new Edit(7, 1, "A"), new Edit(1, 2, "BBB"), new Edit(4, 1, "C"))); assertEquals("0BBB3C56A89", result); } /** * Test for {@link CorrectionUtils#covers(SourceRange, DartNode)}. */ public void test_covers_SourceRange_DartNode() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class A {", "}", ""); assertFalse(CorrectionUtils.covers(rangeStartLength(0, 1), testUnit)); assertTrue(CorrectionUtils.covers(rangeStartLength(0, 1000), testUnit)); } public void test_createIndentEdit() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " if (true) {", " print(0);", " }", "} // marker"); CorrectionUtils utils = getTestCorrectionUtils(); SourceRange range = rangeStartEnd(findOffset(" if (true"), findOffset("} // marker")); Edit edit = utils.createIndentEdit(range, " ", ""); assertEquals( makeSource( "// filler filler filler filler filler filler filler filler filler filler", "main() {", "if (true) {", " print(0);", "}", "} // marker"), CorrectionUtils.applyReplaceEdits(testCode, ImmutableList.of(edit))); } public void test_findNode() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " String v = null;", "}", ""); CorrectionUtils utils = getTestCorrectionUtils(); // no any node { AstNode node = utils.findNode(Integer.MAX_VALUE); assertNull(node); } // "String" node { AstNode node = utils.findNode(findOffset("String ")); assertNotNull(node); } } public void test_getChildren() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class A {", " var myField;", " myMethod() {}", "}", "var topField;", "topFunction() {}", ""); CompilationUnitElement unitElement = testUnit.getElement(); ClassElement classElement = ((ClassDeclaration) testUnit.getDeclarations().get(0)).getElement(); ExecutableElement topFunctionElement = ((FunctionDeclaration) testUnit.getDeclarations().get(2)).getElement(); // not found assertThat(CorrectionUtils.getChildren(unitElement, "noSuchElement")).isEmpty(); // find "A" assertThat(CorrectionUtils.getChildren(unitElement, "A")).containsOnly(classElement); // find "topFunction" assertThat(CorrectionUtils.getChildren(unitElement, "topFunction")).containsOnly( topFunctionElement); // find all "A" members { List<Element> children = CorrectionUtils.getChildren(classElement); // 1(field) + 2(getter + setter) + 1(default constructor) + 1(method) assertThat(children).hasSize(5); } // find "A.myMethod" { List<Element> children = CorrectionUtils.getChildren(classElement, "myMethod"); assertThat(children).hasSize(1); MethodElement child = (MethodElement) Iterables.get(children, 0); assertEquals("myMethod", child.getDisplayName()); } } public void test_getCommentRanges() throws Exception { parseTestUnit( "main() {", " print(1);", " /* marker-1", " print(2);", " marker-2 */", " print(3);", " /* marker-3", " print(4);", " marker-4 */", "}", ""); CorrectionUtils utils = getTestCorrectionUtils(); List<SourceRange> commentRanges = utils.getCommentRanges(); assertThat(commentRanges).hasSize(2); assertEquals( SourceRangeFactory.rangeStartEnd(findOffset("/* marker-1"), findEnd("marker-2 */")), commentRanges.get(0)); assertEquals( SourceRangeFactory.rangeStartEnd(findOffset("/* marker-3"), findEnd("marker-4 */")), commentRanges.get(1)); } public void test_getDeltaOffset() throws Exception { assertEquals(1, CorrectionUtils.getDeltaOffset(new Edit(0, 5, "123456"))); assertEquals(-2, CorrectionUtils.getDeltaOffset(new Edit(0, 5, "123"))); } public void test_getElementKindName_ClassElement() throws Exception { ClassElement element = mock(ClassElement.class); when(element.getKind()).thenReturn(ElementKind.CLASS); assertEquals("class", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_CompilationUnitElement() throws Exception { CompilationUnitElement element = mock(CompilationUnitElement.class); when(element.getKind()).thenReturn(ElementKind.COMPILATION_UNIT); assertEquals("compilation unit", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_ConstructorElement() throws Exception { ConstructorElement element = mock(ConstructorElement.class); when(element.getKind()).thenReturn(ElementKind.CONSTRUCTOR); assertEquals("constructor", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_FieldElement() throws Exception { FieldElement element = mock(FieldElement.class); when(element.getKind()).thenReturn(ElementKind.FIELD); assertEquals("field", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_FunctionElement() throws Exception { FunctionElement element = mock(FunctionElement.class); when(element.getKind()).thenReturn(ElementKind.FUNCTION); assertEquals("function", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_LocalVariableElement() throws Exception { LocalVariableElement element = mock(LocalVariableElement.class); when(element.getKind()).thenReturn(ElementKind.LOCAL_VARIABLE); assertEquals("local variable", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_MethodElement() throws Exception { MethodElement element = mock(MethodElement.class); when(element.getKind()).thenReturn(ElementKind.METHOD); assertEquals("method", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_TypeAliasElement() throws Exception { FunctionTypeAliasElement element = mock(FunctionTypeAliasElement.class); when(element.getKind()).thenReturn(ElementKind.FUNCTION_TYPE_ALIAS); assertEquals("function type alias", CorrectionUtils.getElementKindName(element)); } public void test_getElementKindName_TypeParameterElement() throws Exception { TypeParameterElement element = mock(TypeParameterElement.class); when(element.getKind()).thenReturn(ElementKind.TYPE_PARAMETER); assertEquals("type parameter", CorrectionUtils.getElementKindName(element)); } public void test_getElementQualifiedName() throws Exception { ClassElement enclosingClass = mock(ClassElement.class); when(enclosingClass.getKind()).thenReturn(ElementKind.CLASS); when(enclosingClass.getDisplayName()).thenReturn("A"); // ClassElement assertEquals("A", CorrectionUtils.getElementQualifiedName(enclosingClass)); // MethodElement { MethodElement method = mock(MethodElement.class); when(method.getKind()).thenReturn(ElementKind.METHOD); when(method.getEnclosingElement()).thenReturn(enclosingClass); when(method.getDisplayName()).thenReturn("myMethod"); assertEquals("A.myMethod", CorrectionUtils.getElementQualifiedName(method)); } // FieldElement { FieldElement field = mock(FieldElement.class); when(field.getKind()).thenReturn(ElementKind.FIELD); when(field.getEnclosingElement()).thenReturn(enclosingClass); when(field.getDisplayName()).thenReturn("myField"); assertEquals("A.myField", CorrectionUtils.getElementQualifiedName(field)); } } public void test_getEnclosingExecutableElement_constructor() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class A {", " A() {", " print(0);", " }", "}", ""); ConstructorDeclaration constructorNode = findNode("A()", ConstructorDeclaration.class); ConstructorElement constructorElement = constructorNode.getElement(); SimpleIdentifier node = findIdentifier("print(0)"); assertSame(constructorNode, CorrectionUtils.getEnclosingExecutableNode(node)); assertSame(constructorElement, CorrectionUtils.getEnclosingExecutableElement(node)); } public void test_getEnclosingExecutableElement_function() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "fff(p) {", " var v;", " zzz(p) {}", " print(0);", "}", ""); FunctionDeclaration functionNode = findNode("fff(p)", FunctionDeclaration.class); ExecutableElement functionElement = functionNode.getElement(); SimpleIdentifier node = findIdentifier("print(0)"); assertSame(functionNode, CorrectionUtils.getEnclosingExecutableNode(node)); assertSame(functionElement, CorrectionUtils.getEnclosingExecutableElement(node)); } public void test_getEnclosingExecutableElement_method() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class A {", " method() {", " print(0);", " }", "}", ""); MethodDeclaration methodNode = findNode("method()", MethodDeclaration.class); MethodElement methodElement = (MethodElement) methodNode.getElement(); SimpleIdentifier node = findIdentifier("print(0)"); assertSame(methodNode, CorrectionUtils.getEnclosingExecutableNode(node)); assertSame(methodElement, CorrectionUtils.getEnclosingExecutableElement(node)); } public void test_getEnclosingExecutableElement_null() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 42;", ""); SimpleIdentifier node = findIdentifier("v = 42"); assertSame(null, CorrectionUtils.getEnclosingExecutableNode(node)); assertSame(null, CorrectionUtils.getEnclosingExecutableElement(node)); } /** * Test for {@link CorrectionUtils#getEndOfLine()}. */ public void test_getEndOfLine_unix() throws Exception { parseTestUnit("// aaa\n// bbb\n// ccc"); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals("\n", utils.getEndOfLine()); } /** * Test for {@link CorrectionUtils#getEndOfLine()}. */ public void test_getEndOfLine_windows() throws Exception { parseTestUnit("// aaa\r\n// bbb\r\n// ccc"); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals("\r\n", utils.getEndOfLine()); } public void test_getExportedElement() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var myVariable;", "myFunction() {}", "class MyClass {}", ""); // OK assertNotNull(CorrectionUtils.getExportedElement(testLibraryElement, "myVariable")); assertNotNull(CorrectionUtils.getExportedElement(testLibraryElement, "myFunction")); assertNotNull(CorrectionUtils.getExportedElement(testLibraryElement, "MyClass")); // no LibraryElement assertNull(CorrectionUtils.getExportedElement(null, "MyClass")); // no such name assertNull(CorrectionUtils.getExportedElement(testLibraryElement, "OtherName")); } public void test_getIndent() throws Exception { parseTestUnit(); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals("", utils.getIndent(0)); assertEquals(" ", utils.getIndent(1)); assertEquals(" ", utils.getIndent(2)); } public void test_getIndentSource_direction_left() throws Exception { parseTestUnit(""); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals("a\nb\nc\n", utils.getIndentSource(" a\n b\n c\n", false)); assertEquals(" a\n b\n c\n", utils.getIndentSource(" a\n b\n c\n", false)); } public void test_getIndentSource_direction_right() throws Exception { parseTestUnit(""); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(" a\n b\n c\n", utils.getIndentSource("a\nb\nc\n", true)); assertEquals(" a\n b\n c\n", utils.getIndentSource(" a\n b\n c\n", true)); } public void test_getIndentSource_SourceRange() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " if (true) {", " print(0);", " }", "} // marker"); CorrectionUtils utils = getTestCorrectionUtils(); SourceRange range = rangeStartEnd(findOffset(" if (true"), findOffset("} // marker")); String result = utils.getIndentSource(range, " ", ""); assertEquals("if (true) {\n print(0);\n}\n", toUnixEol(result)); } public void test_getIndentSource_String() throws Exception { parseTestUnit(""); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(makeSource(// "{", " var v;", "}", ""), utils.getIndentSource(makeSource(// " {", " var v;", " }", ""), " ", "")); assertEquals(makeSource(// " {", " var v;", " }", ""), utils.getIndentSource(makeSource(// "{", " var v;", "}", ""), "", " ")); assertEquals(makeSource(// " {", " ", " var v;", " }", ""), utils.getIndentSource(makeSource(// "{", "", " var v;", "}", ""), "", " ")); assertEquals(makeSource(// " {", " var v;", " }", ""), utils.getIndentSource(makeSource(// " {", " var v;", " }", ""), " ", " ")); // don't change multiline strings assertEquals(makeSource(// " {", " var v = '''", "first line", "second line", " ''';", " var v2 = 5;", " }", ""), utils.getIndentSource(makeSource(// "{", " var v = '''", "first line", "second line", " ''';", " var v2 = 5;", "}", ""), "", " ")); // when the line starts not _within_ of a string, we still can indent it assertEquals(makeSource(// " {", " '''aaa", "bbb'''.length;", " var v2 = 5;", " }", ""), utils.getIndentSource(makeSource(// "{", "'''aaa", "bbb'''.length;", " var v2 = 5;", "}", ""), "", " ")); } public void test_getInsertDescImport_emptyUnit() throws Exception { parseTestUnit(); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescImport(); assertEquals(0, desc.offset); assertEquals("", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getInsertDescImport_hasExport() throws Exception { parseTestUnit("export 'dart:math';"); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescImport(); assertEquals(findEnd("export 'dart:math';"), desc.offset); assertEquals("\n", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getInsertDescImport_hasImport() throws Exception { parseTestUnit("import 'dart:math';"); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescImport(); assertEquals(findEnd("import 'dart:math';"), desc.offset); assertEquals("\n", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getInsertDescImport_hasLibrary() throws Exception { parseTestUnit("library app;"); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescImport(); assertEquals(findEnd("library app;"), desc.offset); assertEquals("\n\n", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getInsertDescPart_emptyUnit() throws Exception { parseTestUnit(); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescPart(); assertEquals(0, desc.offset); assertEquals("", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getInsertDescPart_hasLibrary() throws Exception { parseTestUnit("library app;"); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescPart(); assertEquals(findEnd("library app;"), desc.offset); assertEquals("\n\n", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getInsertDescTop_emptyUnit() throws Exception { parseTestUnit(); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescTop(); assertEquals(0, desc.offset); assertEquals("", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getInsertDescTop_hashBang() throws Exception { parseTestUnit( "#!/bin/dart", "", "// filler filler filler filler filler filler filler filler filler filler", "main() {}"); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescTop(); assertEquals(findOffset("main()"), desc.offset); assertEquals("\n", toUnixEol(desc.prefix)); assertEquals("\n", toUnixEol(desc.suffix)); } public void test_getInsertDescTop_hasUnitMembers() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {}"); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescTop(); assertEquals(findOffset("main()"), desc.offset); assertEquals("\n", toUnixEol(desc.prefix)); assertEquals("\n", toUnixEol(desc.suffix)); } public void test_getInsertDescTop_leadingComments_noUnitMembers() throws Exception { parseTestUnit("// filler filler filler filler filler filler filler filler filler filler"); CorrectionUtils utils = getTestCorrectionUtils(); InsertDesc desc = utils.getInsertDescTop(); assertEquals(testCode.length(), desc.offset); assertEquals("\n", toUnixEol(desc.prefix)); assertEquals("", toUnixEol(desc.suffix)); } public void test_getLineContentEnd() throws Exception { parseTestUnit(Joiner.on("\n").join( formatLines( "// filler filler filler filler filler filler filler filler filler filler", "// 1 \t ", "// 2\r", "// 3", "", "// 4"))); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(findOffset("// 2"), utils.getLineContentEnd(findEnd("// 1"))); assertEquals(findOffset("// 3"), utils.getLineContentEnd(findEnd("// 2"))); assertEquals(findOffset("\n// 4"), utils.getLineContentEnd(findEnd("// 3"))); } public void test_getLineContentStart() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "// 1", " \t // 2", "// 3"); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(findOffset("// 1"), utils.getLineContentStart(findOffset("// 1"))); assertEquals(findOffset(" \t // 2"), utils.getLineContentStart(findOffset("// 2"))); } public void test_getLineNext() throws Exception { parseTestUnit(Joiner.on("\n").join( formatLines( "// filler filler filler filler filler filler filler filler filler filler", "// 1", "// 2\r", "// 3"))); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(findOffset("// 1"), utils.getLineNext(findOffset(" filler"))); assertEquals(findOffset("// 2"), utils.getLineNext(findOffset("/ 1"))); assertEquals(findOffset("// 3"), utils.getLineNext(findOffset("/ 2"))); } /** * Test for {@link CorrectionUtils#getLinePrefix(int)}. */ public void test_getLinePrefix() throws Exception { parseTestUnit("//000\n //111\n \n "); CorrectionUtils utils = getTestCorrectionUtils(); // 0 assertEquals("", utils.getLinePrefix(0)); assertEquals("", utils.getLinePrefix(1)); assertEquals("", utils.getLinePrefix(2)); // 1 assertEquals(" ", utils.getLinePrefix(6)); assertEquals(" ", utils.getLinePrefix(7)); assertEquals(" ", utils.getLinePrefix(8)); assertEquals(" ", utils.getLinePrefix(9)); assertEquals(" ", utils.getLinePrefix(10)); // 2 assertEquals(" ", utils.getLinePrefix(14)); assertEquals(" ", utils.getLinePrefix(15)); assertEquals(" ", utils.getLinePrefix(16)); // 3 assertEquals(" ", utils.getLinePrefix(19)); } public void test_getLinesPrefix() throws Exception { assertEquals("", CorrectionUtils.getLinesPrefix("")); assertEquals("", CorrectionUtils.getLinesPrefix("noPrefix")); assertEquals(" ", CorrectionUtils.getLinesPrefix(" space2")); assertEquals(" \t ", CorrectionUtils.getLinesPrefix(" \t space-tab-space")); assertEquals(" ", CorrectionUtils.getLinesPrefix(" space2-NS-space ")); } public void test_getLinesRange_SourceRange() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "// 1", " \t // 2 \t ", "// 3"); CorrectionUtils utils = getTestCorrectionUtils(); // use lines start/end already { int rs = findOffset("// 1"); int re = findOffset("// 2"); assertEquals(rangeStartEnd(rs, re), utils.getLinesRange(rangeStartEnd(rs, re))); } // use start/end with offsets from lines { int as = findOffset("// 2"); int ae = findEnd("// 2"); int rs = findOffset(" \t // 2"); int re = findOffset("// 3"); assertEquals(rangeStartEnd(rs, re), utils.getLinesRange(rangeStartEnd(as, ae))); } } public void test_getLinesRange_Statements() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() { // marker", " var a;", " var b;", " var c;", "}", ""); CorrectionUtils utils = getTestCorrectionUtils(); Block block = findNode("{ // marker", Block.class); Statement statementA = findNode("var a", Statement.class); Statement statementB = findNode("var b", Statement.class); Statement statementC = findNode("var c", Statement.class); { SourceRange expected = rangeStartEnd(statementA.getOffset() - 2, statementC.getOffset() - 2); SourceRange range = utils.getLinesRange(statementA, statementB); assertEquals(expected, range); } { SourceRange expected = rangeStartEnd( statementC.getOffset() - 2, block.getRightBracket().getOffset()); SourceRange range = utils.getLinesRange(statementC); assertEquals(expected, range); } } /** * Test for {@link CorrectionUtils#getLineThis(int)}. */ public void test_getLineThis() throws Exception { parseTestUnit("//aaa\r\n//bbbb\r\n//ccccc"); CorrectionUtils utils = getTestCorrectionUtils(); // 0 assertEquals(0, utils.getLineThis(0)); assertEquals(0, utils.getLineThis(1)); assertEquals(0, utils.getLineThis(2)); // 5 assertEquals(7, utils.getLineThis(7)); assertEquals(7, utils.getLineThis(8)); assertEquals(7, utils.getLineThis(9)); assertEquals(7, utils.getLineThis(10)); // 11 assertEquals(15, utils.getLineThis(15)); assertEquals(15, utils.getLineThis(16)); assertEquals(15, utils.getLineThis(17)); assertEquals(15, utils.getLineThis(18)); assertEquals(15, utils.getLineThis(19)); } public void test_getLocalOrParameterVariableElement_local() throws Exception { LocalVariableElement element = mock(LocalVariableElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(element, CorrectionUtils.getLocalOrParameterVariableElement(identifier)); } public void test_getLocalOrParameterVariableElement_method() throws Exception { Element element = mock(MethodElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(null, CorrectionUtils.getLocalOrParameterVariableElement(identifier)); } public void test_getLocalOrParameterVariableElement_parameter() throws Exception { ParameterElement element = mock(ParameterElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(element, CorrectionUtils.getLocalOrParameterVariableElement(identifier)); } public void test_getLocalVariableElement_local() throws Exception { LocalVariableElement element = mock(LocalVariableElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(element, CorrectionUtils.getLocalVariableElement(identifier)); } public void test_getLocalVariableElement_parameter() throws Exception { ParameterElement element = mock(ParameterElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(null, CorrectionUtils.getLocalVariableElement(identifier)); } public void test_getNearestCommonAncestor_innerBlock() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " print(1);", " {", " print(2);", " }", "}", ""); SimpleIdentifier node1 = findIdentifier("print(2)"); SimpleIdentifier node2 = findIdentifier("print(1)"); List<AstNode> nodes = ImmutableList.<AstNode> of(node1, node2); AstNode result = CorrectionUtils.getNearestCommonAncestor(nodes); assertEquals("{print(1); {print(2);}}", result.toSource()); } public void test_getNearestCommonAncestor_noNodes() throws Exception { ImmutableList<AstNode> nodes = ImmutableList.<AstNode> of(); AstNode result = CorrectionUtils.getNearestCommonAncestor(nodes); assertNull(result); } public void test_getNearestCommonAncestor_sameBlock() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " print(1);", " print(2);", "}", ""); SimpleIdentifier node1 = findIdentifier("print(1)"); SimpleIdentifier node2 = findIdentifier("print(2)"); List<AstNode> nodes = ImmutableList.<AstNode> of(node1, node2); AstNode result = CorrectionUtils.getNearestCommonAncestor(nodes); assertEquals("{print(1); print(2);}", result.toSource()); } public void test_getNearestCommonAncestor_singleNode() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " print(1);", "}", ""); SimpleIdentifier node1 = findIdentifier("print(1)"); List<AstNode> nodes = ImmutableList.<AstNode> of(node1); AstNode result = CorrectionUtils.getNearestCommonAncestor(nodes); assertSame(node1.getParent(), result); } /** * Test for {@link CorrectionUtils#getNodePrefix(DartNode)}. */ public void test_getNodePrefix_block_noPrefix() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "f() {", "var a;", "}", ""); assert_getNodePrefix("var a;", ""); } /** * Test for {@link CorrectionUtils#getNodePrefix(DartNode)}. */ public void test_getNodePrefix_block_withPrefix() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "f() {", " var a;", "}", ""); assert_getNodePrefix("var a;", " "); } /** * Test for {@link CorrectionUtils#getNodePrefix(DartNode)}. */ public void test_getNodePrefix_FunctionExpression() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "foo(x) {}", "main() {", " foo(() => true);", "}", ""); // find node FunctionExpression node = findNode("() => true", FunctionExpression.class); // assert prefix CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(" ", utils.getNodePrefix(node)); } /** * Test for {@link CorrectionUtils#getNodePrefix(DartNode)}. */ public void test_getNodePrefix_noPrefix() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "f() {", " var b;var a;", "}", ""); assert_getNodePrefix("var a;", ""); } public void test_getNodeQualifier_PrefixedIdentifier() throws Exception { SimpleIdentifier name = AstFactory.identifier(""); // no parent assertSame(null, CorrectionUtils.getNodeQualifier(name)); // not PrefixedIdentifier { AstFactory.namedExpression("label", name); assertSame(null, CorrectionUtils.getNodeQualifier(name)); } // not "identifier" in PrefixedIdentifier { AstFactory.identifier(name, AstFactory.identifier("otherName")); assertSame(null, CorrectionUtils.getNodeQualifier(name)); } // OK, "identifier" in PrefixedIdentifier { SimpleIdentifier target = AstFactory.identifier("A"); AstFactory.identifier(target, name); assertSame(target, CorrectionUtils.getNodeQualifier(name)); } } public void test_getNodeQualifier_PropertyAccess() throws Exception { SimpleIdentifier name = AstFactory.identifier(""); // no parent assertSame(null, CorrectionUtils.getNodeQualifier(name)); // not PropertyAccess { AstFactory.namedExpression("label", name); assertSame(null, CorrectionUtils.getNodeQualifier(name)); } // not "name" in PropertyAccess { AstFactory.propertyAccess(name, "otherName"); assertSame(null, CorrectionUtils.getNodeQualifier(name)); } // OK, "name" in PropertyAccess { Expression target = AstFactory.thisExpression(); AstFactory.propertyAccess(target, name); assertSame(target, CorrectionUtils.getNodeQualifier(name)); } } public void test_getNonWhitespaceForward() throws Exception { String code = " \t//0123456789 "; parseTestUnit(code); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(2, utils.getNonWhitespaceForward(0)); assertEquals(2, utils.getNonWhitespaceForward(1)); assertEquals(2, utils.getNonWhitespaceForward(2)); assertEquals(3, utils.getNonWhitespaceForward(3)); assertEquals(code.length(), utils.getNonWhitespaceForward(code.indexOf("9") + 1)); } public void test_getParameterElement_local() throws Exception { LocalVariableElement element = mock(LocalVariableElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(null, CorrectionUtils.getParameterElement(identifier)); } public void test_getParameterElement_parameter() throws Exception { ParameterElement element = mock(ParameterElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(element, CorrectionUtils.getParameterElement(identifier)); } public void test_getParameterSource() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "import 'dart:async' as pref;", "topLevel(double a, int b(double p1, pref.Future p2), dynamic c, d) {", "}", ""); CorrectionUtils utils = getTestCorrectionUtils(); // 'a' { ParameterElement p = findIdentifierElement("a, "); assertEquals("double a", utils.getParameterSource(p.getType(), p.getName())); } // 'b' { ParameterElement p = findIdentifierElement("b(double "); assertEquals( "int b(double p1, pref.Future p2)", utils.getParameterSource(p.getType(), p.getName())); } // 'c' { ParameterElement p = findIdentifierElement("c, "); assertEquals("c", utils.getParameterSource(p.getType(), p.getName())); } // 'd' { ParameterElement p = findIdentifierElement("d) {"); assertEquals("d", utils.getParameterSource(p.getType(), p.getName())); } } public void test_getParentPrecedence() throws Exception { SimpleIdentifier a = identifier("a"); SimpleIdentifier b = identifier("b"); // binary { binaryExpression(a, TokenType.PLUS, b); assertEquals(TokenType.PLUS.getPrecedence(), CorrectionUtils.getParentPrecedence(a)); } // no operator { SimpleIdentifier expr = identifier("c"); assertEquals(-1, CorrectionUtils.getParentPrecedence(expr)); } } public void test_getParents() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " print(0);", "}", ""); SimpleIdentifier node = findIdentifier("print(0)"); // prepare parents List<AstNode> parents = CorrectionUtils.getParents(node); // check first/last nodes assertThat(parents).hasSize(7); assertSame(testUnit, parents.get(0)); assertSame(node.getParent(), parents.get(6)); // check expected path assertThat(parents.get(1)).isInstanceOf(FunctionDeclaration.class); assertThat(parents.get(2)).isInstanceOf(FunctionExpression.class); assertThat(parents.get(3)).isInstanceOf(BlockFunctionBody.class); assertThat(parents.get(4)).isInstanceOf(Block.class); assertThat(parents.get(5)).isInstanceOf(ExpressionStatement.class); assertThat(parents.get(6)).isInstanceOf(MethodInvocation.class); } public void test_getPrecedence() throws Exception { SimpleIdentifier a = identifier("a"); SimpleIdentifier b = identifier("b"); // binary assertEquals( TokenType.PLUS.getPrecedence(), CorrectionUtils.getPrecedence(binaryExpression(a, TokenType.PLUS, b))); assertEquals( TokenType.STAR.getPrecedence(), CorrectionUtils.getPrecedence(binaryExpression(a, TokenType.STAR, b))); // prefix assertEquals( TokenType.BANG.getPrecedence(), CorrectionUtils.getPrecedence(prefixExpression(TokenType.BANG, a))); // postfix assertEquals( TokenType.PLUS_PLUS.getPrecedence(), CorrectionUtils.getPrecedence(postfixExpression(a, TokenType.PLUS_PLUS))); // no operator assertEquals(Integer.MAX_VALUE, CorrectionUtils.getPrecedence(a)); } public void test_getPropertyAccessorElement_accessor() throws Exception { PropertyAccessorElement element = mock(PropertyAccessorElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(element, CorrectionUtils.getPropertyAccessorElement(identifier)); } public void test_getPropertyAccessorElement_local() throws Exception { LocalVariableElement element = mock(LocalVariableElement.class); SimpleIdentifier identifier = AstFactory.identifier("name"); identifier.setStaticElement(element); // check assertSame(null, CorrectionUtils.getPropertyAccessorElement(identifier)); } public void test_getQualifiedPropertyTarget_invocation() throws Exception { SimpleIdentifier target = identifier("target"); SimpleIdentifier name = identifier("name"); new MethodInvocation(target, null, name, null); assertSame(null, CorrectionUtils.getQualifiedPropertyTarget(name)); } public void test_getQualifiedPropertyTarget_prefixedIdentifier() throws Exception { SimpleIdentifier prefix = identifier("prefix"); SimpleIdentifier name = identifier("name"); identifier(prefix, name); assertSame(prefix, CorrectionUtils.getQualifiedPropertyTarget(name)); } public void test_getQualifiedPropertyTarget_propertyAccess() throws Exception { SimpleIdentifier target = identifier("target"); SimpleIdentifier name = identifier("name"); propertyAccess(target, name); assertSame(target, CorrectionUtils.getQualifiedPropertyTarget(name)); } public void test_getRecommendedFileNameForClass() throws Exception { assertEquals("test.dart", CorrectionUtils.getRecommentedFileNameForClass("Test")); assertEquals("my_test.dart", CorrectionUtils.getRecommentedFileNameForClass("MyTest")); assertEquals( "my_super_test.dart", CorrectionUtils.getRecommentedFileNameForClass("MySuperTest")); assertEquals("http_server.dart", CorrectionUtils.getRecommentedFileNameForClass("HTTPServer")); } public void test_getSingleStatement() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " var singleStatement;", " { // marker-1", " var blockWithSingleStatement;", " }", " { // marker-2", " var blockWith;", " var severalStatements;", " }", "}"); { Statement statement = findNode("var singleStatement", Statement.class); assertSame(statement, CorrectionUtils.getSingleStatement(statement)); } { Block block = findNode("{ // marker-1", Block.class); Statement statement = findNode("var blockWithSingleStatement", Statement.class); assertSame(statement, CorrectionUtils.getSingleStatement(block)); } { Block block = findNode("{ // marker-2", Block.class); assertSame(null, CorrectionUtils.getSingleStatement(block)); } } public void test_getStatements() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " var singleStatement;", " { // marker-1", " var blockWithSingleStatement;", " }", " { // marker-2", " var statementA;", " var statementB;", " }", "}"); { Statement statement = findNode("var singleStatement", Statement.class); assertThat(CorrectionUtils.getStatements(statement)).containsExactly(statement); } { Block block = findNode("{ // marker-1", Block.class); Statement statement = findNode("var blockWithSingleStatement", Statement.class); assertThat(CorrectionUtils.getStatements(block)).containsExactly(statement); } { Block block = findNode("{ // marker-2", Block.class); Statement statementA = findNode("var statementA;", Statement.class); Statement statementB = findNode("var statementB", Statement.class); assertThat(CorrectionUtils.getStatements(block)).containsExactly(statementA, statementB); } } /** * Test for {@link CorrectionUtils#getText()}. */ public void test_getText() throws Exception { String code = "// 0123456789"; parseTestUnit(code); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(code, utils.getText()); } /** * Test for {@link CorrectionUtils#getText(AstNode)}. */ public void test_getText_ASTNode() throws Exception { parseTestUnit("class AAA {}"); AstNode node = findNode("AAA {", Identifier.class); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals("AAA", utils.getText(node)); } /** * Test for {@link CorrectionUtils#getText(int, int)}. */ public void test_getText_ints() throws Exception { parseTestUnit("// 0123456789"); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals("0123", utils.getText(3, 4)); } /** * Test for {@link CorrectionUtils#getText(SourceRange)}. */ public void test_getText_SourceRange() throws Exception { parseTestUnit("// 0123456789"); CorrectionUtils utils = getTestCorrectionUtils(); assertEquals("0123", utils.getText(rangeStartLength(3, 4))); } public void test_getTypeSource_Expression() throws Exception { parseTestUnit("// 0123456789"); CorrectionUtils utils = getTestCorrectionUtils(); // prepare mocks Type type = mock(Type.class); Expression expression = mock(Expression.class); when(expression.getBestType()).thenReturn(type); // null assertEquals(null, utils.getTypeSource((Expression) null)); // int when(type.toString()).thenReturn("int"); assertEquals("int", utils.getTypeSource(expression)); // dynamic when(type.toString()).thenReturn("dynamic"); assertEquals(null, utils.getTypeSource(expression)); // List<dynamic> when(type.toString()).thenReturn("List<dynamic>"); assertEquals("List", utils.getTypeSource(expression)); // List<String> when(type.toString()).thenReturn("List<String>"); assertEquals("List<String>", utils.getTypeSource(expression)); // Map<dynamic, dynamic> when(type.toString()).thenReturn("Map<dynamic, dynamic>"); assertEquals("Map", utils.getTypeSource(expression)); // Map<int, String> when(type.toString()).thenReturn("Map<int, String>"); assertEquals("Map<int, String>", utils.getTypeSource(expression)); } public void test_getTypeSource_Expression_importedWithPrefix() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "import 'dart:async' as pref;", "main() {", " pref.Future f = null;", "}", ""); CorrectionUtils utils = getTestCorrectionUtils(); SimpleIdentifier identifier = findIdentifier("f = "); assertEquals("pref.Future", utils.getTypeSource(identifier)); } public void test_getTypeSource_Expression_importedWithPrefix_typeArgument() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "import 'dart:async' as pref;", "main() {", " Map<pref.Future, List<pref.Future>> f = null;", "}", ""); CorrectionUtils utils = getTestCorrectionUtils(); SimpleIdentifier identifier = findIdentifier("f = "); assertEquals("Map<pref.Future, List<pref.Future>>", utils.getTypeSource(identifier)); } public void test_getTypeSource_Type() throws Exception { parseTestUnit("// 0123456789"); CorrectionUtils utils = getTestCorrectionUtils(); // prepare mocks Type type = mock(Type.class); // int when(type.toString()).thenReturn("int"); assertEquals("int", utils.getTypeSource(type)); // dynamic when(type.toString()).thenReturn("dynamic"); assertEquals("dynamic", utils.getTypeSource(type)); // List<dynamic> when(type.toString()).thenReturn("List<dynamic>"); assertEquals("List", utils.getTypeSource(type)); // Map<dynamic, dynamic> when(type.toString()).thenReturn("Map<dynamic, dynamic>"); assertEquals("Map", utils.getTypeSource(type)); } public void test_getUnit() throws Exception { parseTestUnit(""); CorrectionUtils utils = getTestCorrectionUtils(); assertSame(testUnit, utils.getUnit()); } public void test_getVariableNameSuggestions_expectedType() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class TreeNode {}", "main() {", " TreeNode node = null;", "}"); Expression expression = findNode("null;", Expression.class); Type expectedType = ((VariableDeclaration) expression.getParent()).getElement().getType(); assert_getVariableNameSuggestions( expectedType, expression, ImmutableSet.of(""), formatLines("treeNode", "node")); } public void test_getVariableNameSuggestions_expectedType_double() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class TreeNode {}", "main() {", " double res = 0.0;", "}"); Expression expression = findNode("0;", Expression.class); Type expectedType = ((VariableDeclaration) expression.getParent()).getElement().getType(); // first choice for "double" is "d" assert_getVariableNameSuggestions( expectedType, expression, ImmutableSet.of(""), formatLines("d")); // if "d" is used, try "e", "f", etc assert_getVariableNameSuggestions( expectedType, expression, ImmutableSet.of("d", "e"), formatLines("f")); } public void test_getVariableNameSuggestions_expectedType_int() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class TreeNode {}", "main() {", " int res = 0;", "}"); Expression expression = findNode("0;", Expression.class); Type expectedType = ((VariableDeclaration) expression.getParent()).getElement().getType(); // first choice for "int" is "i" assert_getVariableNameSuggestions( expectedType, expression, ImmutableSet.of(""), formatLines("i")); // if "i" is used, try "j", "k", etc assert_getVariableNameSuggestions( expectedType, expression, ImmutableSet.of("i", "j"), formatLines("k")); } public void test_getVariableNameSuggestions_expectedType_String() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "class TreeNode {}", "main() {", " String res = '';", "}"); Expression expression = findNode("'';", Expression.class); Type expectedType = ((VariableDeclaration) expression.getParent()).getElement().getType(); // first choice for "String" is "s" assert_getVariableNameSuggestions( expectedType, expression, ImmutableSet.of(""), formatLines("s")); } public void test_getVariableNameSuggestions_invocationArgument_named() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "foo({a, b, c}) {}", "main() {", " foo(a: 111, c: 333, b: 222);", "}"); assert_getVariableNameSuggestions( null, findNode("111", Expression.class), ImmutableSet.of(""), formatLines("a")); assert_getVariableNameSuggestions( null, findNode("222", Expression.class), ImmutableSet.of(""), formatLines("b")); assert_getVariableNameSuggestions( null, findNode("333", Expression.class), ImmutableSet.of(""), formatLines("c")); } public void test_getVariableNameSuggestions_invocationArgument_optional() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "foo(a, [b = 2, c = 3]) {}", "main() {", " foo(111, 222, 333);", "}"); assert_getVariableNameSuggestions( null, findNode("111", Expression.class), ImmutableSet.of(""), formatLines("a")); assert_getVariableNameSuggestions( null, findNode("222", Expression.class), ImmutableSet.of(""), formatLines("b")); assert_getVariableNameSuggestions( null, findNode("333", Expression.class), ImmutableSet.of(""), formatLines("c")); } public void test_getVariableNameSuggestions_invocationArgument_positional() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "foo(a, b) {}", "main() {", " foo(111, 222);", "}"); assert_getVariableNameSuggestions( null, findNode("111", Expression.class), ImmutableSet.of(""), formatLines("a")); assert_getVariableNameSuggestions( null, findNode("222", Expression.class), ImmutableSet.of(""), formatLines("b")); } public void test_getVariableNameSuggestions_Node_cast() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " var sortedNodes;", " var res = sortedNodes as String;", "}"); assert_getVariableNameSuggestions( null, findNode("sortedNodes as String", AsExpression.class), ImmutableSet.of(""), formatLines("sortedNodes", "nodes")); } public void test_getVariableNameSuggestions_Node_methodInvocation() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var doc;", "main() {", " var res = doc.getSortedNodes();", "}"); assert_getVariableNameSuggestions( null, findNode("doc.getSortedNodes()", MethodInvocation.class), ImmutableSet.of(""), formatLines("sortedNodes", "nodes")); } /** * "get" is valid, but not nice name. */ public void test_getVariableNameSuggestions_Node_name_get() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var doc;", "main() {", " var res = doc.get();", "}"); assert_getVariableNameSuggestions( null, findNode("doc.get()", MethodInvocation.class), ImmutableSet.of(""), formatLines()); } public void test_getVariableNameSuggestions_Node_noPrefix() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var doc;", "main() {", " var res = doc.sortedNodes();", "}"); assert_getVariableNameSuggestions( null, findNode("doc.sortedNodes()", MethodInvocation.class), ImmutableSet.of(""), formatLines("sortedNodes", "nodes")); } public void test_getVariableNameSuggestions_Node_privateName() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var doc;", "main() {", " doc._name;", " doc._computeSuffix();", "}"); assert_getVariableNameSuggestions( null, findNode("doc._name", PrefixedIdentifier.class), ImmutableSet.of(""), formatLines("name")); assert_getVariableNameSuggestions( null, findNode("doc._computeSuffix()", MethodInvocation.class), ImmutableSet.of(""), formatLines("computeSuffix", "suffix")); } public void test_getVariableNameSuggestions_Node_propertyAccess() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var doc;", "main() {", " var res = doc.sortedNodes;", "}"); // TODO(scheglov) would be good if resolver rewrite this to PropertyAccess assert_getVariableNameSuggestions( null, findNode("doc.sortedNodes", PrefixedIdentifier.class), ImmutableSet.of(""), formatLines("sortedNodes", "nodes")); } public void test_getVariableNameSuggestions_Node_simpleName() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " var sortedNodes = null;", " var res = sortedNodes;", "}"); assert_getVariableNameSuggestions( null, findNode("sortedNodes;", Expression.class), ImmutableSet.of(""), formatLines("sortedNodes", "nodes")); } public void test_getVariableNameSuggestions_Node_unqualifiedInvocation() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "getSortedNodes() {}", "main() {", " var res = getSortedNodes();", "}"); assert_getVariableNameSuggestions( null, findNode("getSortedNodes();", MethodInvocation.class), ImmutableSet.of(""), formatLines("sortedNodes", "nodes")); } public void test_getVariableNameSuggestions_Node_unresolvedInstanceCreation() throws Exception { verifyNoTestUnitErrors = false; parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "import 'dart:math' as p;", "main() {", " new NoSuchClass();", " new p.NoSuchClass();", " new NoSuchClass.named();", "}"); assert_getVariableNameSuggestions( null, findNode("new NoSuchClass()", InstanceCreationExpression.class), ImmutableSet.of(""), formatLines("noSuchClass", "suchClass", "class")); assert_getVariableNameSuggestions( null, findNode("new p.NoSuchClass()", InstanceCreationExpression.class), ImmutableSet.of(""), formatLines("noSuchClass", "suchClass", "class")); assert_getVariableNameSuggestions( null, findNode("new NoSuchClass.named()", InstanceCreationExpression.class), ImmutableSet.of(""), formatLines("noSuchClass", "suchClass", "class")); } public void test_getVariableNameSuggestions_Node_withExclude() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " var sortedTreeNodes = null;", " var res = sortedTreeNodes;", "}"); assert_getVariableNameSuggestions( null, findNode("sortedTreeNodes", Expression.class), ImmutableSet.of("treeNodes"), formatLines("sortedTreeNodes", "treeNodes2", "nodes")); } public void test_getVariableNameSuggestions_String() throws Exception { { Set<String> nameSuggestExclude = ImmutableSet.of(""); String[] suggestions = CorrectionUtils.getVariableNameSuggestions( "Goodbye, cruel world!", nameSuggestExclude); assertThat(suggestions).isEqualTo(new String[] {"goodbyeCruelWorld", "cruelWorld", "world"}); } { Set<String> nameSuggestExclude = ImmutableSet.of("world"); String[] suggestions = CorrectionUtils.getVariableNameSuggestions( "Goodbye, cruel world!", nameSuggestExclude); assertThat(suggestions).isEqualTo(new String[] {"goodbyeCruelWorld", "cruelWorld", "world2"}); } } public void test_getVariableNameSuggestions_String_multipleUpper() throws Exception { List<String> suggestions = getVariableNameSuggestions_String("sortedHTMLNodes"); assertThat(suggestions).containsExactly("sortedHTMLNodes", "htmlNodes", "nodes"); } public void test_getVariableNameSuggestions_String_simpleCamel() throws Exception { List<String> suggestions = getVariableNameSuggestions_String("sortedNodes"); assertThat(suggestions).containsExactly("sortedNodes", "nodes"); } public void test_getVariableNameSuggestions_String_simpleName() throws Exception { List<String> suggestions = getVariableNameSuggestions_String("name"); assertThat(suggestions).containsExactly("name"); } public void test_invertCondition_compare() throws Exception { assert_invertCondition("0 < 1", "0 >= 1"); assert_invertCondition("0 > 1", "0 <= 1"); assert_invertCondition("0 <= 1", "0 > 1"); assert_invertCondition("0 >= 1", "0 < 1"); assert_invertCondition("0 == 1", "0 != 1"); assert_invertCondition("0 != 1", "0 == 1"); } public void test_invertCondition_complex() throws Exception { assert_invertCondition("b1 && b2 || b3", "(!b1 || !b2) && !b3"); assert_invertCondition("b1 || b2 && b3", "!b1 && (!b2 || !b3)"); assert_invertCondition("(!b1 || !b2) && !b3", "b1 && b2 || b3"); assert_invertCondition("!b1 && (!b2 || !b3)", "b1 || b2 && b3"); } public void test_invertCondition_is() throws Exception { assert_invertCondition("v1 is int", "v1 is! int"); assert_invertCondition("v1 is! int", "v1 is int"); } public void test_invertCondition_literals() throws Exception { assert_invertCondition("true", "false"); assert_invertCondition("false", "true"); } public void test_invertCondition_logical() throws Exception { assert_invertCondition("b1 && b2", "!b1 || !b2"); assert_invertCondition("!b1 && !b2", "b1 || b2"); assert_invertCondition("b1 || b2", "!b1 && !b2"); assert_invertCondition("!b1 || !b2", "b1 && b2"); } public void test_invertCondition_simple() throws Exception { assert_invertCondition("b1", "!b1"); assert_invertCondition("!b1", "b1"); assert_invertCondition("!((b1))", "b1"); assert_invertCondition("(((b1)))", "!b1"); } public void test_isJustWhitespace() throws Exception { parseTestUnit("// 0123"); CorrectionUtils utils = getTestCorrectionUtils(); assertTrue(utils.isJustWhitespace(rangeStartLength(2, 1))); assertTrue(utils.isJustWhitespace(rangeStartLength(2, 2))); assertFalse(utils.isJustWhitespace(rangeStartLength(0, 1))); assertFalse(utils.isJustWhitespace(rangeStartLength(2, 3))); } public void test_isJustWhitespaceOrComment() throws Exception { parseTestUnit("var a; // 0123"); CorrectionUtils utils = getTestCorrectionUtils(); // whitespace assertTrue(utils.isJustWhitespaceOrComment(rangeStartLength(6, 1))); assertTrue(utils.isJustWhitespaceOrComment(rangeStartLength(6, 2))); // whitespace + comment assertTrue(utils.isJustWhitespaceOrComment(rangeStartLength(6, 4))); assertTrue(utils.isJustWhitespaceOrComment(rangeStartLength(6, 5))); // not whitespace assertFalse(utils.isJustWhitespaceOrComment(rangeStartLength(0, 1))); assertFalse(utils.isJustWhitespaceOrComment(rangeStartLength(3, 2))); } public void test_isNamedExpressionName_name() throws Exception { SimpleIdentifier labelIdentifier = identifier("name"); namedExpression(label(labelIdentifier), identifier("value")); assertTrue(CorrectionUtils.isNamedExpressionName(labelIdentifier)); } public void test_isNamedExpressionName_value() throws Exception { SimpleIdentifier labelIdentifier = identifier("name"); SimpleIdentifier valueIdentifier = identifier("value"); namedExpression(label(labelIdentifier), valueIdentifier); assertFalse(CorrectionUtils.isNamedExpressionName(valueIdentifier)); } public void test_new_withCharBuffer() throws Exception { AnalysisContext context = new AnalysisContextImpl(); context.setSourceFactory(new SourceFactory()); Source source = mock(Source.class); CompilationUnit unit = mock(CompilationUnit.class); CompilationUnitElement unitElement = mock(CompilationUnitElement.class); when(unitElement.getContext()).thenReturn(context); when(unit.getElement()).thenReturn(unitElement); when(unitElement.getSource()).thenReturn(source); // mock content final CharBuffer charBuffer = mock(CharBuffer.class); when(charBuffer.toString()).thenReturn("// 0123"); when(source.getContents()).thenReturn(new TimestampedData<CharSequence>(0L, charBuffer)); // create CorrectionUtils, ask content CorrectionUtils utils = new CorrectionUtils(unit); // verify that content was requested verify(source).getContents(); assertEquals("// 0123", utils.getText()); } public void test_selectionIncludesNonWhitespaceOutsideNode() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 111 + 222 + 333;", ""); CorrectionUtils utils = getTestCorrectionUtils(); AstNode node = findNode("222", IntegerLiteral.class); // "selection" does not cover node { SourceRange selection = rangeStartEnd(findOffset("22 "), findEnd("22 ")); assertFalse(utils.selectionIncludesNonWhitespaceOutsideNode(selection, node)); } // same range { SourceRange selection = rangeStartEnd(findOffset("222"), findEnd("222")); assertFalse(utils.selectionIncludesNonWhitespaceOutsideNode(selection, node)); } // leading whitespace { SourceRange selection = rangeStartEnd(findOffset(" 222"), findEnd("222")); assertFalse(utils.selectionIncludesNonWhitespaceOutsideNode(selection, node)); } // trailing whitespace { SourceRange selection = rangeStartEnd(findOffset("222"), findEnd("222 ")); assertFalse(utils.selectionIncludesNonWhitespaceOutsideNode(selection, node)); } // non-whitespace leading token { SourceRange selection = rangeStartEnd(findOffset("+ 222"), findEnd("222")); assertTrue(utils.selectionIncludesNonWhitespaceOutsideNode(selection, node)); } // non-whitespace trailing token { SourceRange selection = rangeStartEnd(findOffset("222"), findEnd("222 +")); assertTrue(utils.selectionIncludesNonWhitespaceOutsideNode(selection, node)); } } public void test_validateBinaryExpressionRange_OK_leadingComment() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = /* foo */ 111 + 222;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("/* foo */ 111"), findEnd("111")); assertTrue(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_OK_leadingWhitespace() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 111 + 222;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset(" 111"), findEnd(" 111")); assertTrue(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_OK_startOnFirst_endOnLast() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 1 + 2 + 3;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("1"), findEnd("3")); assertTrue(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_OK_trailingComment() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 111 /* foo */+ 222;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("111 /* foo */"), findEnd("111 /* foo */")); assertTrue(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_OK_trailingWhitespace() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 111 + 222;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("111"), findEnd("111 ")); assertTrue(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_wrong_leadingToken() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 111 + 222;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("+ 222"), findEnd("+ 222")); assertFalse(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_wrong_notAssociative() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 1 - 2;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("1"), findEnd("2")); assertFalse(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_wrong_startInOperandMiddle() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 111 + 222;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("11 +"), findEnd("= 111")); assertFalse(utils.validateBinaryExpressionRange(node, selection)); } public void test_validateBinaryExpressionRange_wrong_trailingToken() throws Exception { parseTestUnit( "// filler filler filler filler filler filler filler filler filler filler", "var v = 111 + 222;", ""); CorrectionUtils utils = getTestCorrectionUtils(); BinaryExpression node = findVariableInitializer("v = "); // validate SourceRange selection = rangeStartEnd(findOffset("111 +"), findEnd("111 +")); assertFalse(utils.validateBinaryExpressionRange(node, selection)); } /** * Asserts that {@link ExtractUtils#getNodePrefix(DartNode)} in {@link #testUnit} has expected * prefix. */ private void assert_getNodePrefix(String nodePattern, String expectedPrefix) throws Exception { // find node VariableDeclarationStatement node = findNode(nodePattern, VariableDeclarationStatement.class); // assert prefix CorrectionUtils utils = getTestCorrectionUtils(); assertEquals(expectedPrefix, utils.getNodePrefix(node)); } private void assert_invertCondition(String exprSource, String expected) throws Exception { String initial = makeSource( "// filler filler filler filler filler filler filler filler filler filler", "main() {", " int v1, v2, v3, v4, v5;", " bool b1, b2, b3, b4, b5;", " if (" + exprSource + ") // marker", " 0;", " else", " 1;", "}", ""); parseTestUnit(initial); IfStatement ifStatement = findNode("if (", IfStatement.class); Expression condition = ifStatement.getCondition(); String resultSource = getTestCorrectionUtils().invertCondition(condition); assertEquals(expected, resultSource); } @SuppressWarnings("unchecked") private <T extends AstNode> T findVariableInitializer(String pattern) { return (T) findNode(pattern, VariableDeclaration.class).getInitializer(); } /** * Calls {@link StubUtility#getVariableNameSuggestions(String)}. */ @SuppressWarnings("unchecked") private List<String> getVariableNameSuggestions_String(String name) throws Exception { Method method = CorrectionUtils.class.getDeclaredMethod( "getVariableNameSuggestions", String.class); method.setAccessible(true); return (List<String>) method.invoke(null, name); } }