/******************************************************************************* * Copyright (c) 2005, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.ui.tests.refactoring; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import org.junit.Test; import org.eclipse.jdt.internal.corext.refactoring.rename.RenamingNameSuggestor; public class RenamingNameSuggestorTests { String[] fPrefixes; String[] fSuffixes; RenamingNameSuggestor fSuggestor; private String fHelper(String oldFieldName, String oldTypeName, String newTypeName) { return fSuggestor.suggestNewVariableName(fPrefixes, fSuffixes, oldFieldName, oldTypeName, newTypeName); } private String mHelper(String oldFieldName, String oldTypeName, String newTypeName) { return fSuggestor.suggestNewMethodName(oldFieldName, oldTypeName, newTypeName); } public void mh(String orig, String changed, String oldT, String newT) { assertEquals(changed, mHelper(orig, oldT, newT)); } public void mhf(String orig, String oldT, String newT) { assertNull(mHelper(orig, oldT, newT)); } public void fh(String orig, String changed, String oldT, String newT) { assertEquals(changed, fHelper(orig, oldT, newT)); } public void fhf(String orig, String oldT, String newT) { assertNull(fHelper(orig, oldT, newT)); } public void setStrategy(int strategy) { fSuggestor= new RenamingNameSuggestor(strategy); } @Test public void testOnlyPrefix() { fPrefixes= new String[] { "f", "q" }; fSuffixes= new String[0]; setStrategy(RenamingNameSuggestor.STRATEGY_EXACT); // Prefix can, but need not be specified. assertEquals("fSomeOtherClass", fHelper("fSomeClass", "SomeClass", "SomeOtherClass")); assertEquals("qSomeOtherClass", fHelper("qSomeClass", "SomeClass", "SomeOtherClass")); assertEquals("someOtherClass", fHelper("someClass", "SomeClass", "SomeOtherClass")); //Interface names assertEquals("fNewJavaElement", fHelper("fJavaElement", "IJavaElement", "INewJavaElement")); assertEquals("newJavaElement", fHelper("javaElement", "IJavaElement", "INewJavaElement")); // Unrelated stuff assertNull(fHelper("fSomeClass", "Unrelated", "Unrelated2")); } @Test public void testPrefixAndSuffix() { fPrefixes= new String[] { "f", "q" }; fSuffixes= new String[] { "Suf1" }; setStrategy(RenamingNameSuggestor.STRATEGY_EXACT); // Suffix and Prefix can, but need not be specified. assertEquals("fSomeOtherSuf1", fHelper("fSomeSuf1", "Some", "SomeOther")); assertEquals("someOtherSuf1", fHelper("someSuf1", "Some", "SomeOther")); assertEquals("fSomeOther", fHelper("fSome", "Some", "SomeOther")); assertEquals("someOther", fHelper("some", "Some", "SomeOther")); //Interface names assertEquals("fNewJavaElementSuf1", fHelper("fJavaElementSuf1", "IJavaElement", "INewJavaElement")); assertEquals("newJavaElement", fHelper("javaElement", "IJavaElement", "INewJavaElement")); } @Test public void testOnlySuffix() { fPrefixes= new String[0]; fSuffixes= new String[] { "Suf1" }; setStrategy(RenamingNameSuggestor.STRATEGY_EXACT); //Suffix can, but need not be specified assertEquals("someOtherClassSuf1", fHelper("someClassSuf1", "SomeClass", "SomeOtherClass")); assertEquals("someOtherClass", fHelper("someClass", "SomeClass", "SomeOtherClass")); //Interface names assertEquals("newJavaElementSuf1", fHelper("javaElementSuf1", "IJavaElement", "INewJavaElement")); assertEquals("newJavaElement", fHelper("javaElement", "IJavaElement", "INewJavaElement")); } @Test public void testVeryShortNames() { fPrefixes= new String[] { "f", "q" }; fSuffixes= new String[] { "_" }; setStrategy(RenamingNameSuggestor.STRATEGY_SUFFIX); assertEquals("fB", fHelper("fA", "A", "B")); assertEquals("qB", fHelper("qA", "A", "B")); assertEquals("b", fHelper("a", "A", "B")); assertEquals("b_", fHelper("a_", "A", "B")); fh("mAHahAHa", "mBHahAHa", "A", "B"); // match first occurrence } @Test public void testEmbeddedMatching() { fPrefixes= new String[0]; fSuffixes= new String[0]; setStrategy(RenamingNameSuggestor.STRATEGY_EMBEDDED); mh("getJavaElement", "getNewJavaElement", "JavaElement", "NewJavaElement"); mh("javaElement", "newJavaElement", "JavaElement", "NewJavaElement"); mh("createjavaElement", "createnewJavaElement", "JavaElement", "NewJavaElement"); mh("getJavaElement", "getNewJavaElement", "IJavaElement", "INewJavaElement"); mhf("createJavaElementcache", "JavaElement", "NewJavaElement"); // match with "_" or "$" and other non-letters and non-digits at the next hunk mh("someClass_pm", "someDifferentClass_pm", "SomeClass", "SomeDifferentClass"); mh("someClass$$", "someDifferentClass$$", "SomeClass", "SomeDifferentClass"); // match a second type name fh("createelementsecondElement", "createelementsecondMember", "Element", "Member"); fh("createelementsecondelement", "createelementsecondmember", "Element", "Member"); fhf("createelementsecondelementnomore", "Element", "Member"); } @Test public void testCamelCaseMatching() { fPrefixes= new String[0]; fSuffixes= new String[0]; setStrategy(RenamingNameSuggestor.STRATEGY_SUFFIX); // only the last camel case match mh("getElement", "getMember", "JavaElement", "JavaMember"); mh("getElement", "getMember", "IJavaElement", "IJavaMember"); mh("getElement", "getMember", "AVeryLongJavaElement", "AVeryLongJavaMember"); // two mh("getJavaElement", "getJavaMember", "SimpleJavaElement", "SimpleJavaMember"); mh("getJavaElement", "getGeneralElement", "SimpleJavaElement", "SimpleGeneralElement"); //three mh("getVeryLongJavaElement", "getSomeCompletelyDifferentName", "ExtremelyVeryLongJavaElement", "ExtremelySomeCompletelyDifferentName"); //some fields fh("element", "member", "JavaElement", "JavaMember"); fh("element", "member", "IJavaElement", "IJavaMember"); fh("javaElement", "javaMember", "JavaElement", "JavaMember"); fh("cachedJavaElement", "cachedJavaMember", "JavaElement", "JavaMember"); fh("javaElement", "nonjavaMember", "JavaElement", "NonjavaMember"); // some methods mh("getFreakyClass", "getLast", "FreakyClass", "Last"); mh("Element", "Member", "SomeFreakyElement", "SomeFreakyMember"); mh("createMyASTNode", "createMyNode", "MyASTNode", "MyNode"); // freaky stuff mh("getASTNode", "getASTElement", "ASTNode", "ASTElement"); mh("getASTNode", "getTreeNode", "ASTNode", "TreeNode"); // ;) mh("getASTHeaven2", "getNoBrainer", "ASTHeaven2", "NoBrainer"); fh("java$Element$", "javaElement", "Java$Element$", "JavaElement"); // suffixes inside the name fh("theElementToUse", "theThingToUse", "JavaElement", "JavaThing"); // only match last hunk mh("getJavaSomeElement", "getJavaSomeMember", "JavaElement", "JavaMember"); mhf("getJavaSome", "JavaElement", "JavaMember"); // failures mhf("getElement", "JavaElementLabel", "JavaMemberLabel"); mhf("getElementlabel", "JavaElement", "JavaMember"); fhf("myClass", "A", "B"); // avoid "silly" name suggestions fhf("fElement", "SomeLongElement", "AnotherDifferentElement"); //-> don't suggest renaming fElement to fElement! } @Test public void testUpperCaseCamelCaseMatching() { fPrefixes= new String[] { "f" }; fSuffixes= new String[0]; setStrategy(RenamingNameSuggestor.STRATEGY_EXACT); // complete uppercase camel case hunks fh("fAST", "fAbstractSyntaxTree", "AST", "AbstractSyntaxTree"); fh("AST", "AbstractSyntaxTree", "AST", "AbstractSyntaxTree"); // complete uppercase camel case hunks, but lowercased fh("fAst", "fAbstractSyntaxTree", "AST", "AbstractSyntaxTree"); fh("ast", "abstractSyntaxTree", "AST", "AbstractSyntaxTree"); fh("aST", "abstractSyntaxTree", "AST", "AbstractSyntaxTree"); fh("fASTNode", "fAbstractSTNode", "ASTNode", "AbstractSTNode"); fh("fASTNode", "fASTreeNode", "ASTNode", "ASTreeNode"); /* * do not match: * fh("fAstNode", "fAbstractSTNode", "ASTNode", "AbstractSTNode"); * fh("fAstNode", "fAsTreeNode", "ASTNode", "ASTreeNode"); * * When changing all-uppercase hunks in exact or embedded mode, it is unclear * which hunk in the new type name corresponds to the custom-lowercased hunk * in the old variable name. Rather than guessing the hunk, we only * proceed hunk-by-hunk in suffix mode. */ setStrategy(RenamingNameSuggestor.STRATEGY_EMBEDDED); fh("fAst2", "fAbstractSyntaxTree2", "AST", "AbstractSyntaxTree"); fh("aST2", "abstractSyntaxTree2", "AST", "AbstractSyntaxTree"); setStrategy(RenamingNameSuggestor.STRATEGY_SUFFIX); // partial uppercase camel case hunks fh("fAST", "fMUST", "PersonalAST", "PersonalMUST"); // "downgrading" the new hunks fh("fAst", "fMust", "PersonalAST", "PersonalMUST"); fh("fHUNKPowered", "fMONKPowered", "ReallyHUNKPowered", "ReallyMONKPowered"); fh("fHunkPowered", "fMonkPowered", "ReallyHUNKPowered", "ReallyMONKPowered"); fh("fHunkPowered", "fMonkPowered", "ReallyHUNKPowered", "ReallyMonkPowered"); fh("fHunkPowered", "fHunk2Powered", "HunkPowered", "Hunk2Powered"); fh("powered", "powered2", "HunkPOWERED", "MonkPOWERED2"); // adapted middle hunks fh("astNode", "fastNode", "ASTNode", "FASTNode"); mh("createMyASTNode", "createMySECONDNode", "MyASTNode", "MySECONDNode"); mh("createMyAstNode", "createMySecondNode", "MyASTNode", "MySECONDNode"); // some more methods mh("createAST", "createAbstractSyntaxTree", "AST", "AbstractSyntaxTree"); // match new hunks fh("fASTNode", "fMyASTNode", "ASTNode", "MyASTNode"); fh("fAstNode", "fMyAstNode", "ASTNode", "MyASTNode"); fh("fDifferentAstNode", "fDifferentMyAstNode", "ASTNode", "MyASTNode"); fh("fDifferentAstNodeToUse", "fDifferentMyAstNodeToUse", "ASTNode", "MyASTNode"); // propagating lowercased front fh("astNode", "myAstNode", "ASTNode", "MyASTNode"); } @Test public void testPluralS() { fPrefixes= new String[0]; fSuffixes= new String[0]; setStrategy(RenamingNameSuggestor.STRATEGY_EXACT); fh("items", "things", "Item", "Thing"); fh("handies", "mobilePhones", "Handy", "MobilePhone"); fh("handy", "mobilePhone", "Handy", "MobilePhone"); fh("mobilePhones", "handies", "MobilePhone", "Handy"); fh("mobilePhone", "handy", "MobilePhone", "Handy"); fh("handies", "mandies", "Handy", "Mandy"); setStrategy(RenamingNameSuggestor.STRATEGY_EMBEDDED); fh("itemsOnLoan", "thingsOnLoan", "Item", "Thing"); fh("itemStuff", "thingStuff", "Item", "Thing"); //-> no plural s! fh("someHandiesOnLoan", "someMobilePhonesOnLoan", "Handy", "MobilePhone"); fh("someHandiesOnLoan", "someMandiesOnLoan", "Handy", "Mandy"); setStrategy(RenamingNameSuggestor.STRATEGY_SUFFIX); fh("someItemsOnLoan", "someThingsOnLoan", "ASTItem", "NOASTThing"); fh("someHandiesOnLoan", "someMandiesOnLoan", "Handy", "Mandy"); fh("someHandiesOnLoan", "someMobilePhonesOnLoan", "Handy", "MobilePhone"); fh("somePhonesOnLoan", "someHandiesOnLoan", "MobilePhone", "Handy"); } }