1 Commits

Author SHA1 Message Date
a8b908ca1d fix: SText.updateMeasuredBounds() must mutate internal bounds, not defensive copy
All checks were successful
CI / build-and-test (pull_request) Successful in 16s
Closes #27
2026-03-27 23:56:42 +01:00
6 changed files with 37 additions and 131 deletions

1
.envrc
View File

@@ -1 +0,0 @@
use flake

View File

@@ -1,54 +0,0 @@
# new-shapes
A shape editor desktop application built with Java Swing. Supports rectangles, circles, triangles, text, shape collections, resize handles, and export to HTML/SVG.
## Prerequisites
- JDK >= 16 (project targets Java 16)
- A graphical display (X11/Wayland) since this is a Swing GUI application
## Bootstrap
### With Nix (recommended)
If you have [direnv](https://direnv.net/) installed, the environment activates automatically:
```sh
direnv allow # one-time, then auto-activates on cd
```
Otherwise, enter the dev shell manually:
```sh
nix develop
```
Both provide JDK 17 and Maven 3.9.x preconfigured. No other setup needed.
### Without Nix
Install JDK 16+ and use the bundled Maven wrapper — no separate Maven installation required:
```sh
./mvnw --version # downloads Maven 3.9.12 on first run
```
## Run the application
```sh
./mvnw compile exec:java -Dexec.mainClass="ovh.gasser.newshapes.App"
```
## Run tests
```sh
./mvnw test
```
To run the full verification pipeline (compile, test, JaCoCo coverage check with 50% minimum line coverage):
```sh
./mvnw verify
```
Coverage reports are generated in `target/site/jacoco/`.

27
flake.lock generated
View File

@@ -1,27 +0,0 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1774386573,
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -1,48 +0,0 @@
{
description = "new-shapes - Java Swing shape editor";
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
# JDK 16 (project target) is non-LTS and unavailable in nixpkgs.
# JDK 17 (LTS) is fully backward-compatible with --source 16 --target 16.
javaVersion = 17;
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forEachSystem = f:
nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.default ];
};
});
in
{
overlays.default = final: prev:
let
jdk = prev."jdk${toString javaVersion}";
in
{
inherit jdk;
# Override Maven to use the same JDK version
maven = prev.maven.override { jdk_headless = jdk; };
};
devShells = forEachSystem ({ pkgs }: {
default = pkgs.mkShell {
packages = with pkgs; [
jdk
maven
];
shellHook = ''
echo "new-shapes dev shell"
echo " Java: $(java -version 2>&1 | head -1)"
echo " Maven: $(mvn -version 2>&1 | head -1)"
'';
};
});
};
}

View File

@@ -57,7 +57,7 @@ public class SText extends AbstractShape {
}
public void updateMeasuredBounds(int width, int height) {
getBounds().setSize(Math.max(width, 0), Math.max(height, 0));
bounds.setSize(Math.max(width, 0), Math.max(height, 0));
}
@Override

View File

@@ -44,4 +44,40 @@ class STextTest {
SText text = SText.create(0, 0, null);
assertEquals(SText.PLACEHOLDER_TEXT, text.getText());
}
@Test
void testUpdateMeasuredBoundsActuallyUpdatesBounds() {
SText text = SText.create(10, 20, "Hello");
text.updateMeasuredBounds(200, 30);
Rectangle bounds = text.getBounds();
assertEquals(200, bounds.width, "updateMeasuredBounds must update width");
assertEquals(30, bounds.height, "updateMeasuredBounds must update height");
}
@Test
void testUpdateMeasuredBoundsDoesNotChangePosition() {
SText text = SText.create(10, 20, "Hello");
text.updateMeasuredBounds(200, 30);
Rectangle bounds = text.getBounds();
assertEquals(10, bounds.x, "updateMeasuredBounds must not change x");
assertEquals(20, bounds.y, "updateMeasuredBounds must not change y");
}
@Test
void testUpdateMeasuredBoundsNegativeClampedToZero() {
SText text = SText.create(0, 0, "Hello");
text.updateMeasuredBounds(-5, -10);
Rectangle bounds = text.getBounds();
assertEquals(0, bounds.width, "negative width must be clamped to 0");
assertEquals(0, bounds.height, "negative height must be clamped to 0");
}
@Test
void testUpdateMeasuredBoundsZeroIsAllowed() {
SText text = SText.create(0, 0, "Hello");
text.updateMeasuredBounds(0, 0);
Rectangle bounds = text.getBounds();
assertEquals(0, bounds.width);
assertEquals(0, bounds.height);
}
}