Skip to content

Add SimplifyHasSizeFromIsEqualToAssertion recipe#1034

Merged
timtebeek merged 1 commit into
mainfrom
tim/simplify-hassize-from-isequalto
Jun 20, 2026
Merged

Add SimplifyHasSizeFromIsEqualToAssertion recipe#1034
timtebeek merged 1 commit into
mainfrom
tim/simplify-hassize-from-isequalto

Conversation

@timtebeek

@timtebeek timtebeek commented Jun 20, 2026

Copy link
Copy Markdown
Member

What's changed

Adds a focused recipe that simplifies literal-first AssertJ size assertions — where the meaningful expression sits on the isEqualTo(...) side rather than inside assertThat(...):

// before
assertThat(4).isEqualTo(predecessors.size());
assertThat(1).isEqualTo(g.getIndependentNodes().size());
assertThat(2).isEqualTo(s.length());
// after
assertThat(predecessors).hasSize(4);
assertThat(g.getIndependentNodes()).hasSize(1);
assertThat(s).hasSize(2);

This is the always-safe Case A from the issue. The underlying comparison is on a primitive int (Iterable.size(), Map.size(), CharSequence.length(), or array .length), so reversing the assertion into hasSize(...) is unconditionally behavior-preserving.

Case B (arbitrary object equality, e.g. assertThat("1").isEqualTo(list.get(0))) is intentionally left untouched, since reversing it would change which equals() is invoked and is unsafe for asymmetric/broken equals implementations.

Guards

  • Only fires when assertThat(...) holds a non-negative int literal (negative hasSize throws at runtime, so reversal there would change behavior).
  • Only matches structural size/length calls on the isEqualTo argument; other int-returning methods (e.g. indexOf) are left alone.

The recipe is wired into the AssertJ best practices composite next to SimplifyHasSizeAssertion, and recipes.csv was regenerated via ./gradlew recipeCsvGenerate.

Handles literal-first AssertJ size assertions where the meaningful
expression sits on the isEqualTo(...) side, e.g.
assertThat(4).isEqualTo(coll.size()) -> assertThat(coll).hasSize(4).

This is the always-safe "Case A" from the issue: the comparison is on a
primitive int (size()/length()/array length), so reversing the
assertion is behavior-preserving. Object-equality reversal (Case B) is
intentionally left untouched since it depends on equals() symmetry.

Fixes #1031
@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Jun 20, 2026
@timtebeek timtebeek merged commit 9a16f57 into main Jun 20, 2026
1 check passed
@timtebeek timtebeek deleted the tim/simplify-hassize-from-isequalto branch June 20, 2026 11:58
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

SimplifyChainedAssertJAssertion: also simplify "literal-first" assertions where the expression is in isEqualTo(...)

1 participant