]> git.uio.no Git - ifi-stolz-refaktor.git/commitdiff
Adding tests for LongestCommonPrefixExtractor.
authorErlend Kristiansen <erlenkr@ifi.uio.no>
Mon, 2 Sep 2013 13:44:46 +0000 (15:44 +0200)
committerErlend Kristiansen <erlenkr@ifi.uio.no>
Mon, 2 Sep 2013 13:51:04 +0000 (15:51 +0200)
At the same time removing PropertyExtractorExecutor.

LongestCommonPrefixExtractor now works on ExpressionStatements only, and
when the expression is a MethodInvocation.

software/no.uio.ifi.refaktor.tests/src/no/uio/ifi/refaktor/tests/LongestCommonPrefixExtractorTest.java [new file with mode: 0644]
software/no.uio.ifi.refaktor.tests/src/no/uio/ifi/refaktor/tests/PropertyExtractorExecutorTest.java [deleted file]
software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/extractors/LongestCommonPrefixExtractor.java
software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/extractors/PropertyExtractor.java
software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/extractors/PropertyExtractorExecutor.java [deleted file]
software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/extractors/SelectedNodeTextExtractor.java
software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/handlers/TestPropertyExtractorHandler.java
software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/utils/ParseUtils.java
software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/utils/SmartTextSelection.java

diff --git a/software/no.uio.ifi.refaktor.tests/src/no/uio/ifi/refaktor/tests/LongestCommonPrefixExtractorTest.java b/software/no.uio.ifi.refaktor.tests/src/no/uio/ifi/refaktor/tests/LongestCommonPrefixExtractorTest.java
new file mode 100644 (file)
index 0000000..94eaf37
--- /dev/null
@@ -0,0 +1,126 @@
+package no.uio.ifi.refaktor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import no.uio.ifi.refaktor.extractors.LongestCommonPrefixExtractor;
+import no.uio.ifi.refaktor.utils.SmartTextSelection;
+
+import org.eclipse.jface.text.Document;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LongestCommonPrefixExtractorTest {
+
+       private String classStart;
+       private String methodText;
+       private String endStartFoo;
+       private String startFoo;
+       private String testCode;
+       private String singleStatement;
+       private String testExpression;
+       private String blockText;
+
+       @Before
+       public void setUp() throws Exception {
+               classStart = "class TestClass {";
+               endStartFoo = "b.c.d();a.b.c.f();";
+               startFoo = "a." + endStartFoo;
+               singleStatement = "a.b.c.g(a.c);";
+               testExpression = "a.b.d.f()";
+               blockText = "{" + startFoo + "if(" + testExpression + "){" + singleStatement + "return a.b.d();}}";
+               methodText = "public void foo() " + blockText;
+               testCode = classStart + methodText + "}";
+       }
+
+       @Test
+       public void testSelectionIsValidStartFoo() {
+               makeStartFooExtractor();
+       }
+       
+       @Test
+       public void testExtractPropertyStartFoo() {
+               LongestCommonPrefixExtractor extractor = makeStartFooExtractor();
+               extractor.extractProperty();
+               assertEquals("a.b.c", extractor.stringProperty());
+       }
+
+       private LongestCommonPrefixExtractor makeStartFooExtractor() {
+               SmartTextSelection selection = new SmartTextSelection(new Document(testCode), testCode.indexOf(startFoo), startFoo.length());
+               LongestCommonPrefixExtractor extractor = new LongestCommonPrefixExtractor(selection);
+               assertTrue(extractor.selectionIsValid());
+               return extractor;
+       }
+       
+       @Test
+       public void testSelectionIsValidEndStartFoo() {
+               SmartTextSelection selection = new SmartTextSelection(new Document(testCode), testCode.indexOf(endStartFoo), endStartFoo.length());
+               LongestCommonPrefixExtractor extractor = new LongestCommonPrefixExtractor(selection);
+               assertFalse("Partial selection of statements shall not be allowed", extractor.selectionIsValid());
+       }
+       
+       @Test
+       public void testSelectionIsValidSingleStatement() {
+               makeSingleStatementExtractor();
+       }
+       
+       @Test 
+       public void testExtractPropertySingleStatement() {
+               LongestCommonPrefixExtractor extractor = makeSingleStatementExtractor();
+               extractor.extractProperty();
+               assertEquals("a.b.c", extractor.stringProperty());
+       }
+
+       private LongestCommonPrefixExtractor makeSingleStatementExtractor() {
+               SmartTextSelection selection = new SmartTextSelection(new Document(testCode), testCode.indexOf(singleStatement), singleStatement.length());
+               LongestCommonPrefixExtractor extractor = new LongestCommonPrefixExtractor(selection);
+               assertTrue("Single statements shall be allowed", extractor.selectionIsValid());
+               return extractor;
+       }
+       
+       @Test
+       public void testSelectionIsValidTestExpression() {
+               SmartTextSelection selection = new SmartTextSelection(new Document(testCode), testCode.indexOf(testExpression), testExpression.length());
+               LongestCommonPrefixExtractor extractor = new LongestCommonPrefixExtractor(selection);
+               assertFalse("Expressions shall not be allowed", extractor.selectionIsValid());
+       }
+       
+       @Test
+       public void testSelectionIsValidMethodText() {
+               makeMethodTextExtractor();
+       }
+       
+       @Test 
+       public void testExtractPropertyMethodText() {
+               LongestCommonPrefixExtractor extractor = makeMethodTextExtractor();
+               extractor.extractProperty();
+               assertEquals("a.b.c", extractor.stringProperty());
+       }
+
+       private LongestCommonPrefixExtractor makeMethodTextExtractor() {
+               SmartTextSelection selection = new SmartTextSelection(new Document(testCode), testCode.indexOf(methodText), methodText.length());
+               LongestCommonPrefixExtractor extractor = new LongestCommonPrefixExtractor(selection);
+               assertTrue("Selecting whole methods should be allowed", extractor.selectionIsValid());
+               return extractor;
+       }
+       
+       @Test
+       public void testSelectionIsValidBlockText() {
+               makeBlockTextExtractor();
+       }
+
+       @Test
+       public void textExtractPropertyBlockText() {
+               LongestCommonPrefixExtractor extractor = makeBlockTextExtractor();
+               extractor.extractProperty();
+               assertEquals("a.b.c", extractor.stringProperty());
+       }
+       
+       private LongestCommonPrefixExtractor makeBlockTextExtractor() {
+               SmartTextSelection selection = new SmartTextSelection(new Document(testCode), testCode.indexOf(blockText), blockText.length());
+               LongestCommonPrefixExtractor extractor = new LongestCommonPrefixExtractor(selection);
+               assertTrue("Selecting blocks should be allowed", extractor.selectionIsValid());
+               return extractor;
+       }
+
+}
diff --git a/software/no.uio.ifi.refaktor.tests/src/no/uio/ifi/refaktor/tests/PropertyExtractorExecutorTest.java b/software/no.uio.ifi.refaktor.tests/src/no/uio/ifi/refaktor/tests/PropertyExtractorExecutorTest.java
deleted file mode 100644 (file)
index 37b1045..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-package no.uio.ifi.refaktor.tests;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import no.uio.ifi.refaktor.extractors.PropertyExtractor;
-import no.uio.ifi.refaktor.extractors.PropertyExtractorExecutor;
-import no.uio.ifi.refaktor.utils.ParseUtils;
-import no.uio.ifi.refaktor.utils.SmartTextSelection;
-
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jface.text.Document;
-import org.junit.Before;
-import org.junit.Test;
-
-public class PropertyExtractorExecutorTest {
-       
-       private String methodText;
-       private SmartTextSelection selection;
-       private SimplePropertyExtractor extractor;
-       private PropertyExtractorExecutor executor;
-
-       class SimplePropertyExtractor extends PropertyExtractor {
-
-               private String property;
-
-               public SimplePropertyExtractor(SmartTextSelection selection) {
-                       super(selection);
-               }
-               
-               @Override
-               public boolean selectionIsValid() {
-                       return getSelection() != null && getSelection().getText().equals(methodText);
-               }
-
-               public String property() {
-                       return property;
-               }
-               
-               public boolean visit(MethodDeclaration node) {
-                       property = ParseUtils.getNodeText(node, getDocument());
-                       return false;
-               }
-       }
-
-       @Before
-       public void setUp() throws Exception {
-               methodText = "public void foo() { System.out.println(\"bar\"); }";
-               String classStart = "class TestCode { ";
-               String testCode = classStart + methodText  + "}";
-               selection = new SmartTextSelection(new Document(testCode), classStart.length(), methodText.length());
-               extractor = new SimplePropertyExtractor(selection);
-               executor = new PropertyExtractorExecutor(extractor);
-       }
-
-       @Test
-       public void testExtractProperty() {
-               assertEquals("The selection range may have been poorly defined.", methodText, selection.getText());
-               executor.extractProperty();
-               assertEquals(selection.getText(), extractor.property());
-       }
-
-       @Test
-       public void testSelectionIsValid() {
-               assertTrue(executor.selectionIsValid());
-       }
-
-}
index 7df3089c1269e8b6d259c5314da0b440e36063d6..aff74eacd43396e505573ba341474652dedcd0b5 100644 (file)
 package no.uio.ifi.refaktor.extractors;
 
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+
 import no.uio.ifi.refaktor.utils.ParseUtils;
 import no.uio.ifi.refaktor.utils.SmartTextSelection;
 
-import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.NodeFinder;
+import org.eclipse.jdt.core.dom.Statement;
 
 public class LongestCommonPrefixExtractor extends PropertyExtractor {
-       
+
+       protected class SelectionAttributesCollector extends ASTVisitor {
+
+               private SmartTextSelection selection;
+               private LinkedList<ASTNode> selectedStatements;
+               private NodeFinder nodeFinder;
+
+               public SelectionAttributesCollector(SmartTextSelection selection) {
+                       this.selection = selection;
+                       this.selectedStatements = new LinkedList<ASTNode>();
+                       nodeFinder = ParseUtils.getNodeFinder(selection);
+                       findSelectedStatements(getCoveringNode());
+               }
+
+               private ASTNode getCoveringNode() {
+                       return nodeFinder.getCoveringNode();
+               }
+               
+               private ASTNode getCoveredNode() {
+                       return nodeFinder.getCoveredNode();
+               }
+               
+               public boolean isSingleNodeSelection() {
+                       return getCoveringNode() == getCoveredNode();
+               }
+
+               public ASTNode getSelectedNode() {
+                       if (!isSingleNodeSelection())
+                               return null;
+                       return getCoveredNode();
+               }
+
+               public void findSelectedStatements(ASTNode node) {
+                       node.accept(this);
+                       Collections.sort(selectedStatements, new Comparator<ASTNode>(){
+                               @Override
+                               public int compare(ASTNode node1, ASTNode node2) {
+                                       if (node1.equals(node2))
+                                               return 0;
+                                       else if (node1.getStartPosition() < node2.getStartPosition())
+                                               return -1;
+                                       else if (node1.getStartPosition() > node2.getStartPosition())
+                                               return 1;
+                                       else
+                                               return 0;
+                               }});
+               }
+
+               @Override
+               public boolean preVisit2(ASTNode node) {
+                       if (node instanceof Statement && nodeInSelection(node, selection)) {
+                               selectedStatements.add(node);
+                               // Only visit top-level statements
+                               return false;
+                       }
+
+                       if (node instanceof MethodDeclaration || node instanceof Block )
+                               return true;
+
+                       return false;
+               }
+
+               public boolean selectedNodeHasBlockStructure() {
+                       return isSingleNodeSelection() && 
+                                       (getSelectedNode() instanceof MethodDeclaration || getSelectedNode() instanceof Block);
+               }
+
+               public boolean noStatementsSelected() {
+                       return selectedStatements.isEmpty();
+               }
+               
+               private boolean selectionMatchesStatementsStartAndEnd() {
+                       return selectedStatements.getFirst().getStartPosition() == selection.getOffset() 
+                                       && nodeEnd(selectedStatements.getLast()) == selection.getEnd();
+               }
+               
+               private int nodeEnd(ASTNode astNode) {
+                       return astNode.getStartPosition() + astNode.getLength();
+               }
+       }
+
        protected String property;
+       private SelectionAttributesCollector selectionAttributesCollector;
 
        public LongestCommonPrefixExtractor(SmartTextSelection selection) {
                super(selection);
+               selectionAttributesCollector = new SelectionAttributesCollector(selection);
        }
-       
-       //TODO: what about simple names?
 
        @Override
-       public boolean visit(QualifiedName node) {
+       public boolean visit(ExpressionStatement node) {
                if (!nodeInSelection(node))
                        return false;
-               
-               String nodeText = ParseUtils.getNodeText(node, getSelection().getDocument()).trim();
-               
+
+               String prefix = getPrefix(node);
+
                if (property == null) {
-                       property = nodeText;
+                       property = prefix;
                } else {
-                       property = longestCommonPrefix(property, nodeText);
+                       property = longestCommonPrefix(property, prefix);
                }
                return false;
        }
 
+       public String getPrefix(ExpressionStatement node) {
+               Expression expression = node.getExpression();
+               if (expression instanceof MethodInvocation)
+                       return ParseUtils.getNodeText(((MethodInvocation) expression).getExpression(), getDocument()).trim();
+               return ParseUtils.getNodeText(node, getDocument()).trim();
+       }
+
        private String longestCommonPrefix(String attribute, String nodeText) {
                String commonPrefix = attribute.substring(0, numberOfCommonCharacters(attribute, nodeText));
                if (commonPrefix.endsWith(".")) {
@@ -52,7 +151,7 @@ public class LongestCommonPrefixExtractor extends PropertyExtractor {
        private boolean belowStringLengths(int index, String attribute, String nodeText) {
                return index < attribute.length() && index < nodeText.length();
        }
-       
+
        private boolean charsMatchingAt(String attribute, String nodeText, int index) {
                return attribute.charAt(index) == nodeText.charAt(index);
        }
@@ -60,4 +159,23 @@ public class LongestCommonPrefixExtractor extends PropertyExtractor {
        public String stringProperty() {
                return property;
        }
+
+       @Override
+       public boolean selectionIsValid() {
+               if (!super.selectionIsValid())
+                       return false;
+
+               if (selectionAttributesCollector.noStatementsSelected())
+                       return false;
+               
+               if (selectionAttributesCollector.selectedNodeHasBlockStructure())
+                       return true;
+               
+               return selectionAttributesCollector.selectionMatchesStatementsStartAndEnd();
+       }
+
+       @Override
+       protected ASTNode getStartNode() {
+               return selectionAttributesCollector.getCoveringNode();
+       }
 }
\ No newline at end of file
index 00c1893304cfb1504f38730bed5c8300eeabac37..b4571740db3144d473d388e6f364ae03dd23b7c8 100644 (file)
@@ -1,10 +1,12 @@
 package no.uio.ifi.refaktor.extractors;
 
+import no.uio.ifi.refaktor.utils.ParseUtils;
 import no.uio.ifi.refaktor.utils.SmartTextSelection;
 
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTVisitor;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
 
 public abstract class PropertyExtractor extends ASTVisitor {
        
@@ -22,8 +24,11 @@ public abstract class PropertyExtractor extends ASTVisitor {
        public IDocument getDocument() {
                return selection.getDocument();
        }
-
        protected boolean nodeInSelection(ASTNode node) {
+               return nodeInSelection(node, getSelection());
+       }
+       
+       protected boolean nodeInSelection(ASTNode node, ITextSelection selection) {
                return selection.getOffset() <= node.getStartPosition() &&
                                (node.getStartPosition() + node.getLength()) <= (selection.getOffset() + selection.getLength());
        }
@@ -32,10 +37,14 @@ public abstract class PropertyExtractor extends ASTVisitor {
                return selection != null;
        }
 
-       public void extractProperty(ASTNode startNode) {
+       public void extractProperty() {
                if (!selectionIsValid())
                        throw new RuntimeException(this.getClass().getCanonicalName() + ": Trying to extract property from invalid selection!");
-               startNode.accept(this);
+               getStartNode().accept(this);
+       }
+
+       protected ASTNode getStartNode() {
+               return ParseUtils.getNodeFinder(selection).getCoveringNode();
        }
 
 }
diff --git a/software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/extractors/PropertyExtractorExecutor.java b/software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/extractors/PropertyExtractorExecutor.java
deleted file mode 100644 (file)
index a5c6c74..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package no.uio.ifi.refaktor.extractors;
-
-import no.uio.ifi.refaktor.utils.ParseUtils;
-
-import org.eclipse.jdt.core.dom.ASTNode;
-
-public class PropertyExtractorExecutor {
-
-       private PropertyExtractor extractor;
-
-       public PropertyExtractorExecutor(PropertyExtractor extractor) {
-               this.extractor = extractor;
-       }
-
-       public void extractProperty() {
-               extractor.extractProperty(getCoveringNode());
-       }
-
-       private ASTNode getCoveringNode() {
-               return ParseUtils.getNodeFinder(extractor.getDocument(), extractor.getSelection()).getCoveringNode();
-       }
-
-       public boolean selectionIsValid() {
-               return extractor.selectionIsValid();
-       }
-
-}
-
index f8c3b777736d6d066bc070ef6a8402cc7c13a4b0..25d0801ae8459f83e723deadf0cde64a1d526c60 100644 (file)
@@ -22,5 +22,4 @@ public class SelectedNodeTextExtractor extends PropertyExtractor {
        public String stringProperty() {
                return property;
        }
-
 }
index 7f4bbf57865dd83534d9f14f4b3ac5e87a3080cc..1e733b570d1388156f34ab8ac7d71eca19bd0556 100644 (file)
@@ -1,7 +1,6 @@
 package no.uio.ifi.refaktor.handlers;
 
 import no.uio.ifi.refaktor.extractors.LongestCommonPrefixExtractor;
-import no.uio.ifi.refaktor.extractors.PropertyExtractorExecutor;
 import no.uio.ifi.refaktor.utils.ParseUtils;
 import no.uio.ifi.refaktor.utils.SmartTextSelection;
 
@@ -27,10 +26,9 @@ public class TestPropertyExtractorHandler extends SelectionAbstractHandler {
                editor.getSite().getSelectionProvider().setSelection(smartTextSelection);
                
                LongestCommonPrefixExtractor extractor = new LongestCommonPrefixExtractor(smartTextSelection);
-               PropertyExtractorExecutor executor = new PropertyExtractorExecutor(extractor);
                String dialogText;
-               if (executor.selectionIsValid()) {
-                       executor.extractProperty();
+               if (extractor.selectionIsValid()) {
+                       extractor.extractProperty();
                        dialogText = extractor.stringProperty();
                } else {
                        dialogText = "Selection is invalid";
index 3ea11cec5019043e840a93d36f54999c3e06ad67..065254c26e604ca3a021e44a0bb9b5bc489e6d67 100644 (file)
@@ -85,5 +85,9 @@ public class ParseUtils {
                return new NodeFinder(cu.getRoot(), selection.getOffset(), selection.getLength());
        }
 
+       public static NodeFinder getNodeFinder(SmartTextSelection selection) {
+               return getNodeFinder(selection.getDocument(), selection);
+       }
+
 
 }
index 4019f384af07073ebd7d47edb0b0c39df8903672..db2e53c4a28640fa61a6e44ab2b557757802b8dc 100644 (file)
@@ -23,4 +23,8 @@ public class SmartTextSelection extends TextSelection implements ITextSelection
                return document;
        }
 
+       public int getEnd() {
+               return getOffset() + getLength();
+       }
+
 }