What version of OpenRewrite are you using?
rewrite-testing-frameworks 3.39.0
- OpenRewrite Gradle plugin 7.35.0
- JDK 21
- Active recipe:
org.openrewrite.java.testing.assertj.Assertj
How are you running OpenRewrite?
Gradle plugin, ./gradlew rewriteRun.
What is the smallest, simplest way to reproduce the problem?
Given (here value is an int):
assertThat(value).isNotSameAs(0);
A first rewriteRun produces:
assertThat(value).isNotEqualTo(0);
Running rewriteRun again, with no source edits in between, produces:
assertThat(value).isNotZero();
So the aggregate does not reach a fixed point in a single invocation:
AssertJPrimitiveRulesRecipes$AssertThatIsNotEqualToRecipe rewrites isNotSameAs(0) → isNotEqualTo(0) on the first run;
AssertJIntegerRulesRecipes$AbstractIntegerAssertIsNotZeroRecipe only collapses isNotEqualTo(0) → isNotZero() on the next run.
Both rules are part of the same Assertj aggregate, but the output of (1) is not fed into (2) within one rewriteRun. (Same for isSameAs(0) → isEqualTo(0) → isZero().)
What did you expect to see?
Either the Assertj aggregate converges in a single rewriteRun, or it is documented that the recipe must be run until stable. As-is, consumers silently get sub-optimal output (isNotEqualTo(0) instead of isNotZero()) unless they happen to run the recipe twice.
What happened instead?
A single rewriteRun leaves isNotEqualTo(0) / isEqualTo(0) that a second run then simplifies to isNotZero() / isZero(). We observed this on ~5 files when migrating the TestNG suite; running the recipe a second time was required to fully converge.
Additional context
Note: the first step above (isNotSameAs → isNotEqualTo) is itself questionable when the operands are reference types rather than primitives — filed separately against the rule source (PicnicSupermarket/error-prone-support). This report is specifically about the non-convergence of the aggregate in a single run, which is independent of that.
What version of OpenRewrite are you using?
rewrite-testing-frameworks3.39.0org.openrewrite.java.testing.assertj.AssertjHow are you running OpenRewrite?
Gradle plugin,
./gradlew rewriteRun.What is the smallest, simplest way to reproduce the problem?
Given (here
valueis anint):A first
rewriteRunproduces:Running
rewriteRunagain, with no source edits in between, produces:So the aggregate does not reach a fixed point in a single invocation:
AssertJPrimitiveRulesRecipes$AssertThatIsNotEqualToReciperewritesisNotSameAs(0)→isNotEqualTo(0)on the first run;AssertJIntegerRulesRecipes$AbstractIntegerAssertIsNotZeroRecipeonly collapsesisNotEqualTo(0)→isNotZero()on the next run.Both rules are part of the same
Assertjaggregate, but the output of (1) is not fed into (2) within onerewriteRun. (Same forisSameAs(0)→isEqualTo(0)→isZero().)What did you expect to see?
Either the
Assertjaggregate converges in a singlerewriteRun, or it is documented that the recipe must be run until stable. As-is, consumers silently get sub-optimal output (isNotEqualTo(0)instead ofisNotZero()) unless they happen to run the recipe twice.What happened instead?
A single
rewriteRunleavesisNotEqualTo(0)/isEqualTo(0)that a second run then simplifies toisNotZero()/isZero(). We observed this on ~5 files when migrating the TestNG suite; running the recipe a second time was required to fully converge.Additional context
Note: the first step above (
isNotSameAs→isNotEqualTo) is itself questionable when the operands are reference types rather than primitives — filed separately against the rule source (PicnicSupermarket/error-prone-support). This report is specifically about the non-convergence of the aggregate in a single run, which is independent of that.