All checks were successful
CI / build-and-test (pull_request) Successful in 18s
Verify clone(), getBounds(), and translate() contracts across all Shape implementations (SRectangle, SCircle, STriangle, SText, SCollection) using @ParameterizedTest + @MethodSource. Also adds junit-jupiter-params dependency to pom.xml. Closes #8
74 lines
2.6 KiB
Java
74 lines
2.6 KiB
Java
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");
|
|
}
|
|
}
|