openrewrite / rewrite-testing-frameworks

OpenRewrite recipes that perform common Java testing migration tasks.
Apache License 2.0
68 stars 57 forks source link

RemoveTryCatchFailBlocks fails when converting try-catch block with empty Assert.fail() method #537

Open vijay-chavakula opened 6 days ago

vijay-chavakula commented 6 days ago

What version of OpenRewrite are you using?

I am using

<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.14.0</version>
</dependency>
<dependency>
    <groupId>org.openrewrite.recipe</groupId>
    <artifactId>rewrite-testing-frameworks</artifactId>
    <version>2.4.1</version>
</dependency>

How are you running OpenRewrite?

I am using the Maven plugin, and my project is a multi module project.

What is the smallest, simplest way to reproduce the problem?

Run org.openrewrite.java.testing.junit5.RemoveTryCatchFailBlocks; on code like this, where Assert.fail() method is called inside a try catch.

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.fail;

public class OpenrewriteTest
{
    @Test
    public void smokeTest()
    {
        try{
          System.out.println("Testing");
        }catch(Exception e){
           fail();
        } 
    }
}

What did you expect to see?

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions;

public class OpenrewriteTest
{
    @Test
    public void smokeTest()
    {
       Assertions.assertDoesNotThrow(() -> {
           System.out.println("Testing");
       }, "");
    }
}

What did you see instead?

Errors

What is the full stack trace of any errors you encountered?

[ERROR] Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.14.0:run (default-cli) on project RequestManager: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:5.14.0:run failed: Error while visiting RequestManager-App\src\test\java\com\jpmorgan\regops\scra\requestmanager\
controller\DocCategoriesAndTypesControllerTest.java: java.lang.IllegalArgumentException: Could not parse as Java
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.lambda$compileTemplate$11(JavaTemplateParser.java:245)
[ERROR]   java.base/java.util.Optional.orElseThrow(Optional.java:408)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.compileTemplate(JavaTemplateParser.java:245)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.lambda$parseBlockStatements$7(JavaTemplateParser.java:157)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.cacheIfContextFree(JavaTemplateParser.java:269)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateParser.parseBlockStatements(JavaTemplateParser.java:155)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.maybeReplaceStatement(JavaTemplateJavaExtension.java:461)
[ERROR]   org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:455)
timtebeek commented 6 days ago

Hi! I've replicated your example as a runnable test, and added that into RemoveTryCatchFailBlocksTest, where it passes normally.

@Test
@Issue("https://github.com/openrewrite/rewrite-testing-frameworks/issues/537")
void removeTryCatchBlockWithoutMessageStaticImport() {
    //language=java
    rewriteRun(
      java(
        """
          import org.junit.jupiter.api.Test;
          import static org.junit.jupiter.api.Assertions.fail;

          class MyTest {
              @Test
              public void testMethod() {
                  try {
                      System.out.println("unsafe code");
                  } catch (Exception e) {
                      fail();
                  }
              }
          }
          """,
        """
          import org.junit.jupiter.api.Assertions;
          import org.junit.jupiter.api.Test;

          class MyTest {
              @Test
              public void testMethod() {
                  Assertions.assertDoesNotThrow(() -> {
                      System.out.println("unsafe code");
                  });
              }
          }
          """
      )
    );
}

That might mean there's something different about your case; did you take your case from the file that fails to parse?

DocCategoriesAndTypesControllerTest.java: java.lang.IllegalArgumentException: Could not parse as Java

If so it might help to analyze any parser exceptions, or missing types, as outlined here. If we're able to fix the underlying issue, you should then see the changes you're after. Could you let me know if that turns up any new leads?

vijay-chavakula commented 6 days ago

Is it possible to try with below code block @timtebeek on which it is failing exactly, even i tried to upgrade to latest bom but same parsing issue for this file.

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import static org.junit.jupiter.api.Assertions.fail;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(MockitoExtension.class)
@ActiveProfiles("test")
@Slf4j
@AutoConfigureMockMvc(addFilters = false)
public class DocCategoriesAndTypesControllerTest {

    @Autowired
    private MockMvc mvc;

    @InjectMocks
    DocCategoriesAndTypesController docCategoriesAndTypesController;

    private final HttpHeaders httpHeaders = new HttpHeaders();
    static final String BASE_URL = "api/v1/employee";

    @BeforeEach
    public void setup() {

        httpHeaders.set("trace-id", "123456789");
        httpHeaders.set("session-id", "DocCategoriesAndTypesControllerTest");

        MockitoAnnotations.openMocks(this);
        mvc = MockMvcBuilders.standaloneSetup(docCategoriesAndTypesController).build();
    }

    @Test
    public void testDocTypes()  {
        String url = BASE_URL + "/documents";

        try {

            MockHttpServletRequestBuilder builder =
                    MockMvcRequestBuilders.get(url)
                            .contentType(MediaType.APPLICATION_JSON_VALUE)
                            .accept(MediaType.APPLICATION_JSON)
                            .characterEncoding("UTF-8")
                            .headers(httpHeaders)
                            .content("hello world");

            this.mvc.perform(builder)
                    .andDo(MockMvcResultHandlers.print())
                    .andExpect(status().isOk())
                    .andExpect(content().contentType(MediaType.APPLICATION_JSON));

        } catch (Exception ex) {
            fail();
        }
    }
}
timtebeek commented 6 days ago

Thanks for sharing the file! Nothing immediately jumps out at me as a clear parsing issue, but it's not as easy to parse that in isolation for me given that I lack the required dependencies. Would you mind running through these steps?

It could also be that a particular file is not parsed correctly. In such cases you'll see log line output which files failed to parse. You can use the Find source files with ParseExceptionResult markers diagnostic recipe to find & report these issues. Note that this again produces a data table for you to inspect.

If you're using Maven the one-off command would be

mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.activeRecipes=org.openrewrite.FindParseFailures -Drewrite.exportDatatables=true

That should then give us a data table in target/ such that we can analyze the stacktrace on our way to fixing the parser issue.

vijay-chavakula commented 5 days ago

Thanks for comments @timtebeek , can i know which folder under /target will have data tables and any specific name of the file to attach here?

timtebeek commented 5 days ago

Sure! That should create data tables under target/rewrite/datatables/<date_time>, as described here. image

I'd be interested to see the contents of target/rewrite/datatables/<date_time>/org.openrewrite.table.ParseFailures.csv

vijay-chavakula commented 4 days ago

with the command given above i couldn't generate and rewrite folder under tagert/

trying to paste the stacktrace one again.

Caused by: java.lang.RuntimeException: Error while visiting RequestManager-App\src\test\java\com\example\controller\DocCategoriesAndTypesControllerTest.java: java.lang.IllegalArgumentException: Could not parse as Java
  org.openrewrite.java.internal.template.JavaTemplateParser.lambda$compileTemplate$13(JavaTemplateParser.java:251)
  java.base/java.util.Optional.orElseThrow(Optional.java:408)
  org.openrewrite.java.internal.template.JavaTemplateParser.compileTemplate(JavaTemplateParser.java:251)
  org.openrewrite.java.internal.template.JavaTemplateParser.lambda$parseBlockStatements$9(JavaTemplateParser.java:163)
  org.openrewrite.java.internal.template.JavaTemplateParser.cacheIfContextFree(JavaTemplateParser.java:277)
  org.openrewrite.java.internal.template.JavaTemplateParser.parseBlockStatements(JavaTemplateParser.java:158)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.maybeReplaceStatement(JavaTemplateJavaExtension.java:469)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:463)
  org.openrewrite.java.internal.template.JavaTemplateJavaExtension$1.visitStatement(JavaTemplateJavaExtension.java:56)
  org.openrewrite.java.JavaVisitor.visitTry(JavaVisitor.java:1192)
  org.openrewrite.java.tree.J$Try.acceptJava(J.java:5329)
  org.openrewrite.java.tree.J.accept(J.java:59)
  org.openrewrite.TreeVisitor.visit(TreeVisitor.java:283)
  org.openrewrite.TreeVisitor.visit(TreeVisitor.java:184)
  org.openrewrite.java.JavaTemplate.apply(JavaTemplate.java:64)
  org.openrewrite.java.testing.junit5.RemoveTryCatchFailBlocks$RemoveTryCatchBlocksFromUnitsTestsVisitor.replaceWithAssertDoesNotThrowWithoutStringExpression(RemoveTryCatchFailBlocks.java:128)
  ...
    at org.openrewrite.maven.AbstractRewriteMojo$ResultsContainer$1.lambda$preVisit$0 (AbstractRewriteMojo.java:427)
    at java.util.Optional.ifPresent (Optional.java:183)
    at org.openrewrite.maven.AbstractRewriteMojo$ResultsContainer$1.preVisit (AbstractRewriteMojo.java:424)
    at org.openrewrite.maven.AbstractRewriteMojo$ResultsContainer$1.preVisit (AbstractRewriteMojo.java:420)
    at org.openrewrite.maven.AbstractRewriteMojo_ResultsContainer_1_JavaVisitor.preVisit (AbstractRewriteMojo_ResultsContainer_1_JavaVisitor.zig:81)
    at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:280)
    at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:366)
    at org.openrewrite.java.JavaVisitor.visitRightPadded (JavaVisitor.java:1375)
    at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4 (JavaVisitor.java:401)
    at org.openrewrite.internal.ListUtils.map (ListUtils.java:176)
    at org.openrewrite.java.JavaVisitor.visitBlock (JavaVisitor.java:400)
    at org.openrewrite.java.tree.J$Block.acceptJava (J.java:838)
    at org.openrewrite.java.tree.J.accept (J.java:59)
    at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:283)
    at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:366)
    at org.openrewrite.java.JavaVisitor.visitMethodDeclaration (JavaVisitor.java:883)
    at org.openrewrite.java.tree.J$MethodDeclaration.acceptJava (J.java:3672)
    at org.openrewrite.java.tree.J.accept (J.java:59)
    at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:283)
    at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:366)
    at org.openrewrite.java.JavaVisitor.visitRightPadded (JavaVisitor.java:1375)
    at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4 (JavaVisitor.java:401)
    at org.openrewrite.internal.ListUtils.map (ListUtils.java:176)
    at org.openrewrite.java.JavaVisitor.visitBlock (JavaVisitor.java:400)
    at org.openrewrite.java.tree.J$Block.acceptJava (J.java:838)
    at org.openrewrite.java.tree.J.accept (J.java:59)
    at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:283)
    at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:366)
    at org.openrewrite.java.JavaVisitor.visitClassDeclaration (JavaVisitor.java:488)
    at org.openrewrite.java.tree.J$ClassDeclaration.acceptJava (J.java:1290)
    at org.openrewrite.java.tree.J.accept (J.java:59)
    at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:283)
    at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:366)
    at org.openrewrite.java.JavaVisitor.lambda$visitCompilationUnit$10 (JavaVisitor.java:501)
    at org.openrewrite.internal.ListUtils.map (ListUtils.java:176)
    at org.openrewrite.java.JavaVisitor.visitCompilationUnit (JavaVisitor.java:501)
    at org.openrewrite.java.tree.J$CompilationUnit.acceptJava (J.java:1592)
    at org.openrewrite.java.tree.J.accept (J.java:59)
    at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:283)
    at org.openrewrite.maven.AbstractRewriteMojo$ResultsContainer.getRecipeErrors (AbstractRewriteMojo.java:431)
    at org.openrewrite.maven.AbstractRewriteMojo$ResultsContainer.getFirstException (AbstractRewriteMojo.java:411)
    at org.openrewrite.maven.AbstractRewriteRunMojo.execute (AbstractRewriteRunMojo.java:63)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
    at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
    at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
    at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:906)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:283)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:206)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles: