Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Unified Diff: editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/index/IndexContributorTest.java

Issue 11787017: Initial implementation of MemoryIndexStoreImpl and IndexContributor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/index/IndexContributorTest.java
diff --git a/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/index/IndexContributorTest.java b/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/index/IndexContributorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e34890083bf3ba2c5066a7022ff9d101a0f666cb
--- /dev/null
+++ b/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/index/IndexContributorTest.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2012, 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.internal.index;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.dart.engine.EngineTestCase;
+import com.google.dart.engine.ast.ASTNode;
+import com.google.dart.engine.ast.ClassDeclaration;
+import com.google.dart.engine.ast.CompilationUnit;
+import com.google.dart.engine.ast.ExtendsClause;
+import com.google.dart.engine.ast.FunctionDeclaration;
+import com.google.dart.engine.ast.FunctionTypeAlias;
+import com.google.dart.engine.ast.ImplementsClause;
+import com.google.dart.engine.ast.NodeList;
+import com.google.dart.engine.ast.PrefixedIdentifier;
+import com.google.dart.engine.ast.SimpleIdentifier;
+import com.google.dart.engine.ast.TopLevelVariableDeclaration;
+import com.google.dart.engine.ast.TypeName;
+import com.google.dart.engine.ast.VariableDeclaration;
+import com.google.dart.engine.ast.VariableDeclarationList;
+import com.google.dart.engine.element.ClassElement;
+import com.google.dart.engine.element.CompilationUnitElement;
+import com.google.dart.engine.element.Element;
+import com.google.dart.engine.element.ElementLocation;
+import com.google.dart.engine.element.ElementProxy;
+import com.google.dart.engine.element.FieldElement;
+import com.google.dart.engine.element.FunctionElement;
+import com.google.dart.engine.element.LibraryElement;
+import com.google.dart.engine.element.TypeAliasElement;
+import com.google.dart.engine.element.VariableElement;
+import com.google.dart.engine.index.IndexStore;
+import com.google.dart.engine.index.Location;
+import com.google.dart.engine.index.Relationship;
+import com.google.dart.engine.source.Source;
+import com.google.dart.engine.type.Type;
+
+import org.mockito.ArgumentCaptor;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+public class IndexContributorTest extends EngineTestCase {
+ private static class ExpectedLocation {
+ Element element;
+ int offset;
+ String name;
+
+ ExpectedLocation(Element element, int offset, String name) {
+ this.element = element;
+ this.offset = offset;
+ this.name = name;
+ }
+ }
+
+ /**
+ * Information about single relation recorded into {@link IndexStore}.
+ */
+ private static class RecordedRelation {
+ final ElementProxy element;
+ final Relationship relation;
+ final Location location;
+
+ public RecordedRelation(ElementProxy element, Relationship relation, Location location) {
+ this.element = element;
+ this.relation = relation;
+ this.location = location;
+ }
+ }
+
+ /**
+ * Asserts that given {@link ElementProxy} represents given {@link Element}.
+ */
+ private static void assertElementProxy(Element expected, ElementProxy actual) {
+ assertEquals(new ElementProxy(expected), actual);
+ }
+
+ /**
+ * Asserts that actual {@link Location} has given properties.
+ */
+ private static void assertLocation(Location actual, Element expectedElement, int expectedOffset,
+ String expectedNameForLength) {
+ assertElementProxy(expectedElement, actual.getElement());
+ assertEquals(expectedOffset, actual.getOffset());
+ assertEquals(expectedNameForLength.length(), actual.getLength());
+ assertSame(null, actual.getImportPrefix());
+ }
+
+ /**
+ * Asserts that actual {@link Location} has given properties.
+ */
+ private static void assertLocation(Location actual, ExpectedLocation expected) {
+ assertLocation(actual, expected.element, expected.offset, expected.name);
+ }
+
+ private static void assertRecordedRelation(RecordedRelation recordedRelation,
+ Element expectedElement, Relationship expectedRelationship, ExpectedLocation expectedLocation) {
+ assertElementProxy(expectedElement, recordedRelation.element);
+ assertSame(expectedRelationship, recordedRelation.relation);
+ assertLocation(recordedRelation.location, expectedLocation);
+ }
+
+ private static <T extends Element> T mockElement(Class<T> clazz, Element enclosingElement,
+ ElementLocation location, int offset, String name) {
+ T element = mockElement(clazz, location, offset, name);
+ when(element.getEnclosingElement()).thenReturn(enclosingElement);
+ return element;
+ }
+
+ private static <T extends Element> T mockElement(Class<T> clazz, ElementLocation location,
+ int offset, String name) {
+ T element = mock(clazz);
+ when(element.getLocation()).thenReturn(location);
+ when(element.getNameOffset()).thenReturn(offset);
+ when(element.getName()).thenReturn(name);
+ return element;
+ }
+
+ private static <T extends ASTNode> NodeList<T> mockNodeList(ASTNode owner, T... nodes) {
Brian Wilkerson 2013/01/07 21:27:18 This isn't a mock, it's a real node list, so the n
scheglov 2013/01/07 22:45:41 Done.
+ NodeList<T> nodeList = new NodeList<T>(owner);
+ for (int i = 0; i < nodes.length; i++) {
+ nodeList.add(nodes[i]);
+ }
+ return nodeList;
+ }
+
+ private static SimpleIdentifier mockSimpleIdentifier(Element element, int offset, String name) {
+ SimpleIdentifier identifier = mock(SimpleIdentifier.class);
+ when(identifier.getElement()).thenReturn(element);
+ when(identifier.getOffset()).thenReturn(offset);
+ when(identifier.getLength()).thenReturn(name.length());
+ return identifier;
+ }
+
+ private static TypeName mockTypeName(Type type, int offset, String name) {
+ TypeName typeName = mock(TypeName.class);
+ when(typeName.getType()).thenReturn(type);
+ when(typeName.getOffset()).thenReturn(offset);
+ when(typeName.getLength()).thenReturn(name.length());
+ return typeName;
+ }
+
+ private static VariableDeclarationList mockVariableDeclaration(VariableDeclaration var) {
+ VariableDeclarationList variableList = mock(VariableDeclarationList.class);
+ NodeList<VariableDeclaration> variableNodeList = mockNodeList(variableList, var);
+ when(variableList.getVariables()).thenReturn(variableNodeList);
+ return variableList;
+ }
+
+ private IndexStore store = mock(IndexStore.class);
+ private IndexContributor index = new IndexContributor(store);
+ private Source unitSource = mock(Source.class);
+ private CompilationUnit unitNode = mock(CompilationUnit.class);
+ private LibraryElement libraryElement = mock(LibraryElement.class);
+ private ElementLocation libraryLocation = mock(ElementLocation.class);
+
+ private CompilationUnitElement unitElement = mock(CompilationUnitElement.class);
+
+ public void test_accessByQualified_field() throws Exception {
+ FunctionElement enclosingFunction = mock(FunctionElement.class);
+ FieldElement fieldElement = mockElement(FieldElement.class, null, 10, "myField");
+ SimpleIdentifier field = mockSimpleIdentifier(fieldElement, 50, "myField");
+ // wrap into PrefixedIdentifier
+ PrefixedIdentifier prefixedIdentifier = mock(PrefixedIdentifier.class);
+ when(prefixedIdentifier.getIdentifier()).thenReturn(field);
+ when(field.getParent()).thenReturn(prefixedIdentifier);
+ // index
+ index.enterScope(enclosingFunction);
+ index.visitSimpleIdentifier(field);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(1);
+ assertRecordedRelation(
+ relations.get(0),
+ fieldElement,
+ IndexConstants.IS_ACCESSED_BY_QUALIFIED,
+ new ExpectedLocation(enclosingFunction, 50, "myField"));
+ }
+
+ public void test_accessByUnqualified_field() throws Exception {
+ FunctionElement enclosingFunction = mock(FunctionElement.class);
+ FieldElement fieldElement = mockElement(FieldElement.class, null, 10, "myField");
+ SimpleIdentifier field = mockSimpleIdentifier(fieldElement, 50, "myField");
+ // index
+ index.enterScope(enclosingFunction);
+ index.visitSimpleIdentifier(field);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(1);
+ assertRecordedRelation(
+ relations.get(0),
+ fieldElement,
+ IndexConstants.IS_ACCESSED_BY_UNQUALIFIED,
+ new ExpectedLocation(enclosingFunction, 50, "myField"));
+ }
+
+ public void test_ClassDeclaration() throws Exception {
Brian Wilkerson 2013/01/07 21:27:18 A more consistent naming scheme might be good. Som
scheglov 2013/01/07 22:45:41 Agree. Actually after breaking this big test into
+ ClassDeclaration classNodeA = mock(ClassDeclaration.class);
+ ElementLocation classLocationA = mock(ElementLocation.class);
+ ClassElement classElementA = mockElement(ClassElement.class, classLocationA, 42, "ABCDE");
+ when(classNodeA.getElement()).thenReturn(classElementA);
+ when(classElementA.getEnclosingElement()).thenReturn(unitElement);
+ // class A {}
+ {
+ // index ClassDeclaration
+ index.visitClassDeclaration(classNodeA);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(1);
+ assertRecordedRelation(
+ relations.get(0),
+ libraryElement,
+ IndexConstants.DEFINES_CLASS,
+ new ExpectedLocation(classElementA, 42, "ABCDE"));
+ }
+ // class A extends B {} class B {}
Brian Wilkerson 2013/01/07 21:27:18 You certainly don't have to, but my inclination wo
scheglov 2013/01/07 22:45:41 Done.
+ {
+ // class B {}
+ ElementLocation classLocationB = mock(ElementLocation.class);
+ ClassElement classElementB = mockElement(
+ ClassElement.class,
+ libraryElement,
+ classLocationB,
+ 1042,
+ "B");
+ Type typeB = mock(Type.class);
+ when(typeB.getElement()).thenReturn(classElementB);
+ // "extends B"
+ TypeName extendsTypeNameA = mockTypeName(typeB, 142, "B");
+ ExtendsClause extendsClauseA = new ExtendsClause(null, extendsTypeNameA);
+ when(classNodeA.getExtendsClause()).thenReturn(extendsClauseA);
+ // index ClassDeclaration
+ reset(store);
+ index.visitClassDeclaration(classNodeA);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(2);
+ assertRecordedRelation(
+ relations.get(1),
+ classElementB,
+ IndexConstants.IS_EXTENDED_BY,
+ new ExpectedLocation(classElementA, 142, "B"));
+ }
+ // class A implements MyInterface {} class MyInterface {}
+ {
+ // class B {}
+ ElementLocation classLocationB = mock(ElementLocation.class);
+ ClassElement classElementB = mockElement(
+ ClassElement.class,
+ libraryElement,
+ classLocationB,
+ 2042,
+ "MyInterface");
+ Type typeB = mock(Type.class);
+ when(typeB.getElement()).thenReturn(classElementB);
+ // "implements B"
+ when(classNodeA.getExtendsClause()).thenReturn(null);
+ TypeName implementsTypeNameA = mockTypeName(typeB, 242, "MyInterface");
+ ImplementsClause implementsClauseA = new ImplementsClause(
+ null,
+ ImmutableList.of(implementsTypeNameA));
+ when(classNodeA.getImplementsClause()).thenReturn(implementsClauseA);
+ // index ClassDeclaration
+ reset(store);
+ index.visitClassDeclaration(classNodeA);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(2);
+ assertRecordedRelation(
+ relations.get(1),
+ classElementB,
+ IndexConstants.IS_IMPLEMENTED_BY,
+ new ExpectedLocation(classElementA, 242, "MyInterface"));
+ }
+ }
+
+ public void test_createElementLocation() throws Exception {
+ ElementLocation elementLocation = mock(ElementLocation.class);
+ Element element = mockElement(Element.class, elementLocation, 42, "myName");
+ Location location = IndexContributor.createElementLocation(element);
+ assertLocation(location, element, 42, "myName");
+ }
+
+ public void test_createElementLocation_null() throws Exception {
+ assertSame(null, IndexContributor.createElementLocation(null));
+ }
+
+ public void test_FunctionDeclaration() throws Exception {
+ FunctionElement functionElement = mockElement(FunctionElement.class, null, 42, "myFunction");
+ FunctionDeclaration function = mock(FunctionDeclaration.class);
+ when(function.getElement()).thenReturn(functionElement);
+ // index
+ index.visitFunctionDeclaration(function);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(1);
+ assertRecordedRelation(
+ relations.get(0),
+ libraryElement,
+ IndexConstants.DEFINES_FUNCTION,
+ new ExpectedLocation(functionElement, 42, "myFunction"));
+ }
+
+ public void test_FunctionTypeAlias() throws Exception {
+ TypeAliasElement functionElement = mockElement(TypeAliasElement.class, null, 42, "MyFunction");
+ FunctionTypeAlias function = mock(FunctionTypeAlias.class);
+ when(function.getElement()).thenReturn(functionElement);
+ // index
+ index.visitFunctionTypeAlias(function);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(1);
+ assertRecordedRelation(
+ relations.get(0),
+ libraryElement,
+ IndexConstants.DEFINES_FUNCTION_TYPE,
+ new ExpectedLocation(functionElement, 42, "MyFunction"));
+ }
+
+ public void test_TopLevelVariableDeclaration() throws Exception {
+ // VariableDeclaration
+ ElementLocation varLocation = mock(ElementLocation.class);
+ VariableElement varElement = mockElement(VariableElement.class, varLocation, 42, "myVar");
+ VariableDeclaration var = mock(VariableDeclaration.class);
+ when(var.getElement()).thenReturn(varElement);
+ // TopLevelVariableDeclaration
+ TopLevelVariableDeclaration topDeclaration = mock(TopLevelVariableDeclaration.class);
+ VariableDeclarationList variableList = mockVariableDeclaration(var);
+ when(topDeclaration.getVariables()).thenReturn(variableList);
+ index.visitTopLevelVariableDeclaration(topDeclaration);
+ // verify
+ List<RecordedRelation> relations = captureRecordedRelations();
+ assertThat(relations).hasSize(1);
+ assertRecordedRelation(
+ relations.get(0),
+ libraryElement,
+ IndexConstants.DEFINES_VARIABLE,
+ new ExpectedLocation(varElement, 42, "myVar"));
+ }
+
+ public void test_unresolvedUnit() throws Exception {
+ index = new IndexContributor(store);
+ // no CompilationUnitElement, but no NPE
+ unitNode = mock(CompilationUnit.class);
+ index.visitCompilationUnit(unitNode);
+ verify(unitNode).getElement();
+ verifyNoMoreInteractions(unitNode);
+ // no enclosing element
+ assertSame(null, index.peekElement());
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ when(libraryElement.getLocation()).thenReturn(libraryLocation);
+ when(libraryElement.getDefiningCompilationUnit()).thenReturn(unitElement);
+ when(unitNode.getElement()).thenReturn(unitElement);
+ when(unitElement.getSource()).thenReturn(unitSource);
+ when(unitElement.getEnclosingElement()).thenReturn(libraryElement);
+ index.visitCompilationUnit(unitNode);
+ }
+
+ private List<RecordedRelation> captureRecordedRelations() {
+ ArgumentCaptor<ElementProxy> argElement = ArgumentCaptor.forClass(ElementProxy.class);
+ ArgumentCaptor<Relationship> argRel = ArgumentCaptor.forClass(Relationship.class);
+ ArgumentCaptor<Location> argLocation = ArgumentCaptor.forClass(Location.class);
+ verify(store, atLeast(0)).recordRelationship(
+ argElement.capture(),
+ argRel.capture(),
+ argLocation.capture());
+ List<RecordedRelation> relations = Lists.newArrayList();
+ int count = argElement.getAllValues().size();
+ for (int i = 0; i < count; i++) {
+ relations.add(new RecordedRelation(
+ argElement.getAllValues().get(i),
+ argRel.getAllValues().get(i),
+ argLocation.getAllValues().get(i)));
+ }
+ return relations;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698