// Copyright 2015 ThoughtWorks, Inc. // This file is part of Gauge-Java. // This program is free software. // // It is dual-licensed under: // 1) the GNU General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version; // or // 2) the Eclipse Public License v1.0. // // You can redistribute it and/or modify it under the terms of either license. // We would then provide copied of each license in a separate .txt file with the name of the license as the title of the file. package com.thoughtworks.gauge.refactor; import com.thoughtworks.gauge.StepValue; import com.thoughtworks.gauge.registry.StepRegistry; import gauge.messages.Messages; import junit.framework.TestCase; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import static org.mockito.Mockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) @PrepareForTest(StepRegistry.class) public class JavaRefactoringTest extends TestCase { public void testRefactoringWithAlias() throws Exception { mockStatic(StepRegistry.class); when(StepRegistry.hasAlias("old step")).thenReturn(true); when(StepRegistry.getFileName("old step")).thenReturn("foo"); StepValue oldStepValue = new StepValue("old step", "", new ArrayList<String>()); StepValue newStepValue = new StepValue("", "", new ArrayList<String>()); RefactoringResult result = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()).performRefactoring(); assertEquals(false, result.passed()); assertEquals("Refactoring for steps having aliases are not supported.", result.errorMessage()); } public void testRefactoringWithDuplicateImplementations() throws Exception { HashSet<Method> set = mock(HashSet.class); mockStatic(StepRegistry.class); when(StepRegistry.getAll("old step")).thenReturn(set); when(set.size()).thenReturn(2); when(StepRegistry.getFileName("old step")).thenReturn("foo"); StepValue oldStepValue = new StepValue("old step", "", new ArrayList<String>()); StepValue newStepValue = new StepValue("", "", new ArrayList<String>()); RefactoringResult result = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()).performRefactoring(); assertEquals(false, result.passed()); assertEquals("Duplicate step implementation found.", result.errorMessage()); } public void testJavaElementForSimpleRefactoring() throws Exception { StepValue oldStepValue = new StepValue("A step with no params", "A step with no params", new ArrayList<String>()); StepValue newStepValue = new StepValue("step changed", "step changed", new ArrayList<String>()); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"step changed\")" + System.getProperty("line.separator") + " public void someStepStep() {" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("A step with no params")); } public void testJavaElementForRefactoringWithNewParameter() throws Exception { StepValue oldStepValue = new StepValue("A step with no params", "A step with no params", new ArrayList<String>()); StepValue newStepValue = new StepValue("step with {}", "step with <param 1>", Arrays.asList("param 1")); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); Messages.ParameterPosition parameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(-1).setNewPosition(0).build(); ArrayList<Messages.ParameterPosition> parameterPositions = new ArrayList<Messages.ParameterPosition>(); parameterPositions.add(parameterPosition); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, parameterPositions); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"step with <param 1>\")" + System.getProperty("line.separator") + " public void someStepStep(String argParam1) {" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("A step with no params")); } public void testJavaElementForRefactoringWithNewParameterWhenParametersPresent() throws Exception { StepValue oldStepValue = new StepValue("Tell {} to {}", "Tell <greeting> to <name>", Arrays.asList("greeting", "name")); StepValue newStepValue = new StepValue("Tell {} to {} {}", "Tell <greeting> to <name> <DD>", Arrays.asList("greeting", "name", "DD")); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); Messages.ParameterPosition parameterPosition1 = Messages.ParameterPosition.newBuilder().setOldPosition(0).setNewPosition(0).build(); Messages.ParameterPosition parameterPosition2 = Messages.ParameterPosition.newBuilder().setOldPosition(1).setNewPosition(1).build(); Messages.ParameterPosition parameterPosition3 = Messages.ParameterPosition.newBuilder().setOldPosition(-1).setNewPosition(2).build(); ArrayList<Messages.ParameterPosition> parameterPositions = new ArrayList<Messages.ParameterPosition>(); parameterPositions.add(parameterPosition1); parameterPositions.add(parameterPosition2); parameterPositions.add(parameterPosition3); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, parameterPositions); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"Tell <greeting> to <name> <DD>\")" + System.getProperty("line.separator") + " public void helloWorld(String greeting, String name, String argDd) {" + System.getProperty("line.separator") + " System.out.println(greeting + \", \" + name);" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("\"Tell <greeting> to <name>\"")); } private File getImplFile(String fileName) { return new File(String.format("src%stest%sresources", File.separator, File.separator), fileName); } public void testJavaElementForRefactoringWithParametersRemoved() throws Exception { StepValue oldStepValue = new StepValue("step {} and a table {}", "step <a> and a table <table>", new ArrayList<String>()); StepValue newStepValue = new StepValue("{} changed {} and added {}", "<table> changed <c> and added <a>", Arrays.asList("b", "a", "c")); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); Messages.ParameterPosition firstParameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(0).setNewPosition(2).build(); Messages.ParameterPosition secondParameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(1).setNewPosition(0).build(); Messages.ParameterPosition thirdParameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(-1).setNewPosition(1).build(); ArrayList<Messages.ParameterPosition> parameterPositions = new ArrayList<Messages.ParameterPosition>(); parameterPositions.add(firstParameterPosition); parameterPositions.add(secondParameterPosition); parameterPositions.add(thirdParameterPosition); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, parameterPositions); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"<table> changed <c> and added <a>\")" + System.getProperty("line.separator") + " public void stepWithTable(Table table, String argC, float a) {" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("step <a> and a table <table>")); } public void testJavaElementForRefactoringForStepWithUnicodeCharacters() throws Exception { StepValue oldStepValue = new StepValue("† ‡ µ ¢ step with {} and {}", "† ‡ µ ¢ step with <Û> and <į>", Arrays.asList("Û", "į")); StepValue newStepValue = new StepValue("† ‡ µ ¢ step with {}", "† ‡ µ ¢ step with <Û>", Arrays.asList("Û")); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); Messages.ParameterPosition firstParameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(0).setNewPosition(0).build(); ArrayList<Messages.ParameterPosition> parameterPositions = new ArrayList<Messages.ParameterPosition>(); parameterPositions.add(firstParameterPosition); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, parameterPositions); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"\\u2020 \\u2021 \\u00B5 \\u00A2 step with <\\u00DB>\")" + System.getProperty("line.separator") + " public void stepWith(String a) {" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("† ‡ µ ¢ step with <Û> and <į>")); } public void testJavaElementForRefactoringWithSlash() throws Exception { StepValue oldStepValue = new StepValue("A step with \\", "A step with \\", new ArrayList<String>()); StepValue newStepValue = new StepValue("step changed to \\", "step changed to \\", new ArrayList<String>()); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"step changed to \\\\\")" + System.getProperty("line.separator") + " public void stepWithSlash() {" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("A step with \\")); } public void testJavaElementForRefactoringWithTab() throws Exception { StepValue oldStepValue = new StepValue("A step 123", "A step 123", new ArrayList<String>()); StepValue newStepValue = new StepValue("step changed to \t", "step changed to \t", new ArrayList<String>()); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"step changed to \\t\")" + System.getProperty("line.separator") + " public void stepWithTab() {" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("A step 123")); } public void testJavaElementForRefactoringWithParametersRemovedAndAdded() throws Exception { StepValue oldStepValue = new StepValue("step {} and a table {}", "step <a> and a table <table>", new ArrayList<String>()); StepValue newStepValue = new StepValue("{} changed {} and added {}", "<b> changed <a> and added <c>", Arrays.asList("b", "a", "c")); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); Messages.ParameterPosition firstParameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(-1).setNewPosition(0).build(); Messages.ParameterPosition secondParameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(0).setNewPosition(1).build(); Messages.ParameterPosition thirdParameterPosition = Messages.ParameterPosition.newBuilder().setOldPosition(-1).setNewPosition(2).build(); ArrayList<Messages.ParameterPosition> parameterPositions = new ArrayList<Messages.ParameterPosition>(); parameterPositions.add(firstParameterPosition); parameterPositions.add(secondParameterPosition); parameterPositions.add(thirdParameterPosition); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, parameterPositions); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"<b> changed <a> and added <c>\")" + System.getProperty("line.separator") + " public void stepWithTable(String argB, float a, String argC) {" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("step <a> and a table <table>")); } public void testResultForRefactoringWhenFileNotFound() throws Exception { StepValue oldStepValue = new StepValue("A step with no params", "A step with no params", new ArrayList<String>()); StepValue newStepValue = new StepValue("step changed", "step changed", new ArrayList<String>()); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); RefactoringResult result = refactoring.performRefactoring(); assertEquals(result.passed(), false); assertEquals(result.errorMessage(), "Step Implementation Not Found: Unable to find a file Name to refactor"); assertEquals(result.fileChanged(), ""); } public void testResultForRefactoringWhenFileDoesNotExist() throws Exception { StepValue oldStepValue = new StepValue("A step with no params", "A step with no params", new ArrayList<String>()); StepValue newStepValue = new StepValue("step changed", "step changed", new ArrayList<String>()); mockStatic(StepRegistry.class); when(StepRegistry.getFileName("A step with no params")).thenReturn("foobar"); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); RefactoringResult result = refactoring.performRefactoring(); assertEquals(result.passed(), false); assertEquals(result.errorMessage(), "Step Implementation Not Found: Unable to find file: foobar"); assertEquals(result.fileChanged(), ""); } public void testJavaElementForRefactoringWithMethodWithComments() throws Exception { StepValue oldStepValue = new StepValue("A step with comments", "A step with comments", new ArrayList<String>()); StepValue newStepValue = new StepValue("with comments", "with comments", new ArrayList<String>()); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"with comments\")" + System.getProperty("line.separator") + " public void someStepWithComments() {" + System.getProperty("line.separator") + " //comment1" + System.getProperty("line.separator") + " //comment2" + System.getProperty("line.separator") + " /*\n" + " comment3\n" + " comment4\n" + " */" + System.getProperty("line.separator") + " /*\n" + " comment6\n" + " comment7\n" + " comment8\n" + " */" + System.getProperty("line.separator") + " System.out.println(\"\");" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("A step with comments")); } public void testRefactoringWithOrphanComments() throws RefactoringException { StepValue oldStepValue = new StepValue("A step with comments", "A step with comments", new ArrayList<String>()); StepValue newStepValue = new StepValue("with comments", "with comments", new ArrayList<String>()); String implFile = String.format("test%sfiles%sformatted%sStepImplWithComments.java", File.separator, File.separator, File.separator); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); String expectedValue = " @Step(\"with comments\")" + System.getProperty("line.separator") + " public void someStepWithComments() {" + System.getProperty("line.separator") + " //comment1" + System.getProperty("line.separator") + " //comment2" + System.getProperty("line.separator") + " /*\n" + " comment3\n" + " comment4\n" + " */" + System.getProperty("line.separator") + " /*\n" + " comment6\n" + " comment7\n" + " comment8\n" + " */" + System.getProperty("line.separator") + " System.out.println(\"\");" + System.getProperty("line.separator") + " //comment9" + System.getProperty("line.separator") + " //comment10" + System.getProperty("line.separator") + " /*\n" + " comment11\n" + " comment12\n" + " */" + System.getProperty("line.separator") + " /*\n" + " comment13\n" + " comment14\n" + " comment15\n" + " */" + System.getProperty("line.separator") + " }"; String actualValue = element.getText(); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(actualValue.contains(expectedValue)); assertFalse(actualValue.contains("A step with comments")); } public void testJavaElementForRefactoringWithUnFormattedMethod() throws Exception { StepValue oldStepValue = new StepValue("A step with no params", "A step with no params", new ArrayList<String>()); StepValue newStepValue = new StepValue("A step with no paramss", "A step with no paramss", new ArrayList<String>()); String implFile = String.format("test%sfiles%sunformatted%sUnFormattedStepImpl.java", File.separator, File.separator, File.separator); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains("public class StepImpl {" + System.getProperty("line.separator") + "" + System.getProperty("line.separator") + " @Step(\"A step with no paramss\")" + System.getProperty("line.separator") + " public void someStepStep() {" + System.getProperty("line.separator") + " }" + System.getProperty("line.separator") + "}" + System.getProperty("line.separator"))); } public void testJavaElementForRefactoringWithMethodHavingNewLineCharInString() throws Exception { StepValue oldStepValue = new StepValue("A step with newLine", "A step with newLine", new ArrayList<String>()); StepValue newStepValue = new StepValue("step changed", "step changed", new ArrayList<String>()); String implFile = String.format("test%sfiles%sformatted%sStepImpl.java", File.separator, File.separator, File.separator); JavaRefactoring refactoring = new JavaRefactoring(oldStepValue, newStepValue, new ArrayList<Messages.ParameterPosition>()); JavaRefactoringElement element = refactoring.createJavaRefactoringElement(implFile); assertEquals(getImplFile(implFile).getName(), element.getFile().getName()); assertTrue(element.getText().contains(" @Step(\"step changed\")" + System.getProperty("line.separator") + " public void someStepStep() {" + System.getProperty("line.separator") + " System.out.println(\"\\n\");" + System.getProperty("line.separator") + " }")); assertFalse(element.getText().contains("A step with newLine")); } }