package ovh.gasser.newshapes.shapes; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import java.awt.Rectangle; import static org.junit.jupiter.api.Assertions.*; /** * Parameterized contract tests verifying Shape interface invariants * across all implementations (SRectangle, SCircle, STriangle, SText, SCollection). */ class ShapeContractTest { @ParameterizedTest(name = "{0}") @MethodSource("ovh.gasser.newshapes.shapes.ShapeFactory#allShapes") void cloneReturnsIndependentCopy(Shape shape) { Shape cloned = shape.clone(); // clone must not be the same instance assertNotSame(shape, cloned, "clone() must return a new instance"); // clone must have equal bounds assertEquals(shape.getBounds(), cloned.getBounds(), "clone() must preserve bounds"); // mutating the clone must not affect the original Rectangle originalBounds = shape.getBounds(); cloned.translate(999, 999); assertEquals(originalBounds, shape.getBounds(), "Translating the clone must not affect the original's bounds"); } @ParameterizedTest(name = "{0}") @MethodSource("ovh.gasser.newshapes.shapes.ShapeFactory#allShapes") void getBoundsReturnsCopy(Shape shape) { Rectangle bounds1 = shape.getBounds(); Rectangle bounds2 = shape.getBounds(); // successive calls must return equal bounds assertEquals(bounds1, bounds2, "getBounds() must return consistent values"); // but not the same object (defensive copy) assertNotSame(bounds1, bounds2, "getBounds() must return a copy, not internal state"); // mutating the returned Rectangle must not affect the shape bounds1.translate(500, 500); assertEquals(bounds2, shape.getBounds(), "Mutating the returned Rectangle must not affect the shape"); } @ParameterizedTest(name = "{0}") @MethodSource("ovh.gasser.newshapes.shapes.ShapeFactory#allShapes") void translateMutatesInPlace(Shape shape) { Rectangle before = shape.getBounds(); int dx = 7, dy = -3; shape.translate(dx, dy); Rectangle after = shape.getBounds(); assertEquals(before.x + dx, after.x, "translate() must shift x by dx"); assertEquals(before.y + dy, after.y, "translate() must shift y by dy"); assertEquals(before.width, after.width, "translate() must not change width"); assertEquals(before.height, after.height, "translate() must not change height"); } }