Add parameterized ShapeContractTest for Shape interface invariants
All checks were successful
CI / build-and-test (pull_request) Successful in 18s
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
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user