diff --git a/jhotdraw-core/jgiven-reports/org.jhotdraw.draw.figure.BDDRectangle.RoundRectangleFigureBDDTest.json b/jhotdraw-core/jgiven-reports/org.jhotdraw.draw.figure.BDDRectangle.RoundRectangleFigureBDDTest.json new file mode 100644 index 000000000..6378e4cbe --- /dev/null +++ b/jhotdraw-core/jgiven-reports/org.jhotdraw.draw.figure.BDDRectangle.RoundRectangleFigureBDDTest.json @@ -0,0 +1,215 @@ +{ + "className": "org.jhotdraw.draw.figure.BDDRectangle.RoundRectangleFigureBDDTest", + "name": "Round Rectangle Figure BDD", + "scenarios": [ + { + "className": "org.jhotdraw.draw.figure.BDDRectangle.RoundRectangleFigureBDDTest", + "testMethodName": "roundRectangle_resizes_when_bounds_are_set", + "description": "roundRectangle resizes when bounds are set", + "tagIds": [], + "explicitParameters": [], + "derivedParameters": [], + "scenarioCases": [ + { + "caseNr": 1, + "steps": [ + { + "name": "a round rectangle", + "words": [ + { + "value": "Given", + "isIntroWord": true + }, + { + "value": "a round rectangle" + } + ], + "status": "PASSED", + "durationInNanos": 15482200, + "depth": 0, + "parentFailed": false + }, + { + "name": "bounds are set", + "words": [ + { + "value": "When", + "isIntroWord": true + }, + { + "value": "bounds are set" + }, + { + "value": "0.0", + "argumentInfo": { + "argumentName": "x1", + "formattedValue": "0.0" + } + }, + { + "value": "0.0", + "argumentInfo": { + "argumentName": "y1", + "formattedValue": "0.0" + } + }, + { + "value": "120.0", + "argumentInfo": { + "argumentName": "x2", + "formattedValue": "120.0" + } + }, + { + "value": "60.0", + "argumentInfo": { + "argumentName": "y2", + "formattedValue": "60.0" + } + } + ], + "status": "PASSED", + "durationInNanos": 12434500, + "depth": 0, + "parentFailed": false + }, + { + "name": "round rectangle should have size", + "words": [ + { + "value": "Then", + "isIntroWord": true + }, + { + "value": "round rectangle should have size" + }, + { + "value": "120.0", + "argumentInfo": { + "argumentName": "width", + "formattedValue": "120.0" + } + }, + { + "value": "60.0", + "argumentInfo": { + "argumentName": "height", + "formattedValue": "60.0" + } + } + ], + "status": "PASSED", + "durationInNanos": 158418700, + "depth": 0, + "parentFailed": false + } + ], + "explicitArguments": [], + "derivedArguments": [], + "status": "SUCCESS", + "durationInNanos": 240078000 + } + ], + "casesAsTable": false, + "durationInNanos": 240078000 + }, + { + "className": "org.jhotdraw.draw.figure.BDDRectangle.RoundRectangleFigureBDDTest", + "testMethodName": "roundRectangle_arc_can_be_set", + "description": "roundRectangle arc can be set", + "tagIds": [], + "explicitParameters": [], + "derivedParameters": [], + "scenarioCases": [ + { + "caseNr": 1, + "steps": [ + { + "name": "a round rectangle", + "words": [ + { + "value": "Given", + "isIntroWord": true + }, + { + "value": "a round rectangle" + } + ], + "status": "PASSED", + "durationInNanos": 328900, + "depth": 0, + "parentFailed": false + }, + { + "name": "arc is set", + "words": [ + { + "value": "When", + "isIntroWord": true + }, + { + "value": "arc is set" + }, + { + "value": "15.0", + "argumentInfo": { + "argumentName": "width", + "formattedValue": "15.0" + } + }, + { + "value": "25.0", + "argumentInfo": { + "argumentName": "height", + "formattedValue": "25.0" + } + } + ], + "status": "PASSED", + "durationInNanos": 2922000, + "depth": 0, + "parentFailed": false + }, + { + "name": "round rectangle should have arc", + "words": [ + { + "value": "Then", + "isIntroWord": true + }, + { + "value": "round rectangle should have arc" + }, + { + "value": "15.0", + "argumentInfo": { + "argumentName": "arcWidth", + "formattedValue": "15.0" + } + }, + { + "value": "25.0", + "argumentInfo": { + "argumentName": "arcHeight", + "formattedValue": "25.0" + } + } + ], + "status": "PASSED", + "durationInNanos": 1595900, + "depth": 0, + "parentFailed": false + } + ], + "explicitArguments": [], + "derivedArguments": [], + "status": "SUCCESS", + "durationInNanos": 8337700 + } + ], + "casesAsTable": false, + "durationInNanos": 8337700 + } + ], + "tagMap": {} +} \ No newline at end of file diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/GivenRoundRectangle.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/GivenRoundRectangle.java new file mode 100644 index 000000000..e6333075d --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/GivenRoundRectangle.java @@ -0,0 +1,17 @@ +package org.jhotdraw.draw.figure.BDDRectangle; + +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.annotation.ProvidedScenarioState; +import org.jhotdraw.draw.figure.RoundRectangleFigure; + + +public class GivenRoundRectangle extends Stage { + + @ProvidedScenarioState + RoundRectangleFigure roundRectangle; + + public GivenRoundRectangle a_round_rectangle() { + roundRectangle = new RoundRectangleFigure(); + return self(); + } +} diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/RoundRectangleFigureBDDTest.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/RoundRectangleFigureBDDTest.java new file mode 100644 index 000000000..399c03d3d --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/RoundRectangleFigureBDDTest.java @@ -0,0 +1,22 @@ +package org.jhotdraw.draw.figure.BDDRectangle; + +import com.tngtech.jgiven.junit5.ScenarioTest; +import org.junit.jupiter.api.Test; + +public class RoundRectangleFigureBDDTest extends + ScenarioTest { + + @Test + public void roundRectangle_resizes_when_bounds_are_set() { + given().a_round_rectangle(); + when().bounds_are_set(0, 0, 120, 60); + then().round_rectangle_should_have_size(120, 60); + } + + @Test + public void roundRectangle_arc_can_be_set() { + given().a_round_rectangle(); + when().arc_is_set(15, 25); + then().round_rectangle_should_have_arc(15, 25); + } +} diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/ThenRoundRectangle.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/ThenRoundRectangle.java new file mode 100644 index 000000000..fff8a633e --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/ThenRoundRectangle.java @@ -0,0 +1,25 @@ +package org.jhotdraw.draw.figure.BDDRectangle; + +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.annotation.ExpectedScenarioState; +import org.jhotdraw.draw.figure.RoundRectangleFigure; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ThenRoundRectangle extends Stage { + + @ExpectedScenarioState + RoundRectangleFigure roundRectangle; + + public ThenRoundRectangle round_rectangle_should_have_size(double width, double height) { + assertThat(roundRectangle.getBounds().width).isEqualTo(width); + assertThat(roundRectangle.getBounds().height).isEqualTo(height); + return self(); + } + + public ThenRoundRectangle round_rectangle_should_have_arc(double arcWidth, double arcHeight) { + assertThat(roundRectangle.getArcWidth()).isEqualTo(arcWidth); + assertThat(roundRectangle.getArcHeight()).isEqualTo(arcHeight); + return self(); + } +} diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/WhenSettingBounds.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/WhenSettingBounds.java new file mode 100644 index 000000000..63fac0bd5 --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/BDDRectangle/WhenSettingBounds.java @@ -0,0 +1,25 @@ +package org.jhotdraw.draw.figure.BDDRectangle; + + +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.annotation.ExpectedScenarioState; +import org.jhotdraw.draw.figure.RoundRectangleFigure; + + +import java.awt.geom.Point2D; + +public class WhenSettingBounds extends Stage { + + @ExpectedScenarioState + RoundRectangleFigure roundRectangle; + + public WhenSettingBounds bounds_are_set(double x1, double y1, double x2, double y2) { + roundRectangle.setBounds(new Point2D.Double(x1, y1), new Point2D.Double(x2, y2)); + return self(); + } + + public WhenSettingBounds arc_is_set(double width, double height) { + roundRectangle.setArc(width, height); + return self(); + } +} diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/RoundRectangleFigureTest.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/RoundRectangleFigureTest.java new file mode 100644 index 000000000..8970b59fa --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/figure/RoundRectangleFigureTest.java @@ -0,0 +1,139 @@ +package org.jhotdraw.draw.figure; + +import org.junit.Before; +import org.junit.Test; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import static org.junit.Assert.*; + +public class RoundRectangleFigureTest { + + private RoundRectangleFigure roundRect; + + @Before + public void setUp() { + roundRect = new RoundRectangleFigure(10, 20, 30, 40); + } + + // BEST CASE SCENARIOS + @Test + public void testGetBounds() { + Rectangle2D.Double b = roundRect.getBounds(); + assertEquals(10, b.x, 0.001); + assertEquals(20, b.y, 0.001); + assertEquals(30, b.width, 0.001); + assertEquals(40, b.height, 0.001); + } + + @Test + public void testSetBoundsBestCase() { + Point2D.Double anchor = new Point2D.Double(0, 0); + Point2D.Double lead = new Point2D.Double(50, 100); + + roundRect.setBounds(anchor, lead); + + Rectangle2D.Double b = roundRect.getBounds(); + assertEquals(0, b.x, 0.001); + assertEquals(0, b.y, 0.001); + assertEquals(50, b.width, 0.001); + assertEquals(100, b.height, 0.001); + } + + @Test + public void testContainsPointInside() { + Point2D.Double inside = new Point2D.Double(20, 40); + assertTrue(roundRect.contains(inside)); + } + + @Test + public void testTransformTranslate() { + AffineTransform tx = AffineTransform.getTranslateInstance(10, 10); + + roundRect.transform(tx); + Rectangle2D.Double b = roundRect.getBounds(); + + assertEquals(20, b.x, 0.001); + assertEquals(30, b.y, 0.001); + } + + // BOUNDARY CASES + @Test + public void testSetBoundsNegativeCoordinates() { + Point2D.Double anchor = new Point2D.Double(50, 50); + Point2D.Double lead = new Point2D.Double(0, 0); + + roundRect.setBounds(anchor, lead); + Rectangle2D.Double b = roundRect.getBounds(); + + assertEquals(0, b.x, 0.001); + assertEquals(0, b.y, 0.001); + assertEquals(50, b.width, 0.001); + assertEquals(50, b.height, 0.001); + } + + @Test + public void testMinimumWidthHeightIsPointOne() { + Point2D.Double anchor = new Point2D.Double(10, 10); + Point2D.Double lead = new Point2D.Double(10, 10); // same point → zero size + + roundRect.setBounds(anchor, lead); + Rectangle2D.Double b = roundRect.getBounds(); + + assertEquals(0.1, b.width, 0.001); + assertEquals(0.1, b.height, 0.001); + } + + @Test + public void testContainsOutsidePoint() { + Point2D.Double outside = new Point2D.Double(200, 200); + assertFalse(roundRect.contains(outside)); + } + + @Test + public void testTransformScale() { + AffineTransform tx = AffineTransform.getScaleInstance(2, 2); + roundRect.transform(tx); + + Rectangle2D.Double b = roundRect.getBounds(); + + assertEquals(20, b.x, 0.001); + assertEquals(40, b.y, 0.001); + assertEquals(60, b.width, 0.001); + assertEquals(80, b.height, 0.001); + } + + // INVARIANTS + @Test + public void testInvariantRoundRectWidthHeightNeverNegative() { + roundRect.setBounds(new Point2D.Double(5,5), new Point2D.Double(5,5)); + Rectangle2D.Double b = roundRect.getBounds(); + + assert b.width >= 0.1 : "Width invariant violated"; + assert b.height >= 0.1 : "Height invariant violated"; + } + + // ARC PROPERTIES + @Test + public void testArcWidthHeight() { + roundRect.setArc(15, 25); + + assertEquals(15, roundRect.getArcWidth(), 0.001); + assertEquals(25, roundRect.getArcHeight(), 0.001); + } + + // COPY/CLONE + @Test + public void testCloneCreatesDeepCopy() { + RoundRectangleFigure copy = roundRect.clone(); + + Rectangle2D.Double b1 = roundRect.getBounds(); + Rectangle2D.Double b2 = copy.getBounds(); + + assertEquals(b1.x, b2.x, 0.001); + assertEquals(b1.y, b2.y, 0.001); + assertNotSame(roundRect.getTransformRestoreData(), copy.getTransformRestoreData()); + } +}