Skip to content

Assertion with java.awt.Path2D object usingRecursiveComparison().isEqualsTo() fails in 3.23.0+ #2678

@dinox0r

Description

@dinox0r

Describe the bug

The following assertion passes for versions ≤ 3.22.0:

import java.awt.geom.Path2D;

import static org.assertj.core.api.Assertions.assertThat;

public class Main {
  @SuppressWarnings("DuplicatedCode")
  public static void main(String... args) {
    var path1 = new Path2D.Float();
    path1.moveTo(0, 0);
    path1.lineTo(10, 0);
    path1.curveTo(13, 2, 13, 5, 10, 7);
    path1.lineTo(0, 7);
    path1.curveTo(-3, 5, -3, 2, 0, 0);
    path1.closePath();

    var path2 = new Path2D.Float();
    path2.moveTo(0, 0);
    path2.lineTo(10, 0);
    path2.curveTo(13, 2, 13, 5, 10, 7);
    path2.lineTo(0, 7);
    path2.curveTo(-3, 5, -3, 2, 0, 0);
    path2.closePath();

    assertThat(path1)
        .usingRecursiveComparison()
        .isEqualTo(path2);
  }
}

But from version 3.23.0+, we get the following instead:

Exception in thread "main" java.lang.AssertionError: 
Expecting actual:
  java.awt.geom.Path2D$Float@6325a3ee
to be equal to:
  java.awt.geom.Path2D$Float@1d16f93d
when recursively comparing field by field, but found the following difference:

Top level actual and expected objects differ:
- actual value  : java.awt.geom.Path2D$Float@6325a3ee
- expected value: java.awt.geom.Path2D$Float@1d16f93d

The recursive comparison was performed with this configuration:
- no overridden equals methods were used in the comparison (except for java types)
- these types were compared with the following comparators:
  - java.lang.Double -> DoubleComparator[precision=1.0E-15]
  - java.lang.Float -> FloatComparator[precision=1.0E-6]
  - java.nio.file.Path -> lexicographic comparator (Path natural order)
- actual and expected objects and their fields were compared field by field recursively even if they were not of the same type, this allows for example to compare a Person to a PersonDto (call strictTypeChecking(true) to change that behavior).

	at Main.main(Main.java:26)

Additional context

After debugging a bit, it seems that the problem is in the RecursiveComparisonDifferenceCalculator.mustCompareFieldsRecursively():

private boolean mustCompareFieldsRecursively(DualValue dualValue) {

  return !recursiveComparisonConfiguration.hasCustomComparator(dualValue)   // <- evals to 'true'
         && !shouldHonorEquals(dualValue, recursiveComparisonConfiguration) // <- evals to 'true'
         && dualValue.hasNoContainerValues(); 
         //            ^
         //            | 
         //  This evaluates to 'false'. I believe is because the class Path2D.Float
         //  has its data in arrays and not in java collection type containers.

}
  • assertj core version: 3.22.0+
  • java version: Java 11
  • test framework version: JUnit 4

Test case reproducing the bug

Add a test case showing the bug that we can run

public class SomeTest {
  @Test
  public void test() {
    var path1 = new Path2D.Float();
    path1.moveTo(0, 0);
    path1.lineTo(10, 0);
    path1.curveTo(13, 2, 13, 5, 10, 7);
    path1.lineTo(0, 7);
    path1.curveTo(-3, 5, -3, 2, 0, 0);
    path1.closePath();

    var path2 = new Path2D.Float();
    path2.moveTo(0, 0);
    path2.lineTo(10, 0);
    path2.curveTo(13, 2, 13, 5, 10, 7);
    path2.lineTo(0, 7);
    path2.curveTo(-3, 5, -3, 2, 0, 0);
    path2.closePath();

    assertThat(path1)
        .usingRecursiveComparison()
        .isEqualTo(path2);
  }
}

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions