Add simulated parking capacity and Jenkins CI (refs #9)
smartpark-app-ci/pipeline/pr-main This commit looks good

This commit is contained in:
2026-10-08 11:24:57 -04:00
parent ba7eb30138
commit 68613f38df
6 changed files with 207 additions and 1 deletions
@@ -0,0 +1,57 @@
package edu.stevens.smartpark;
/** A single parking location with simulated, in-memory availability. */
public final class ParkingLot {
private final String name;
private final int capacity;
private int availableSpaces;
public ParkingLot(String name, int capacity, int availableSpaces) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("Parking lot name is required");
}
if (capacity < 0) {
throw new IllegalArgumentException("Capacity cannot be negative");
}
if (availableSpaces < 0 || availableSpaces > capacity) {
throw new IllegalArgumentException("Available spaces must be between zero and capacity");
}
this.name = name;
this.capacity = capacity;
this.availableSpaces = availableSpaces;
}
public String getName() {
return name;
}
public int getCapacity() {
return capacity;
}
public int getAvailableSpaces() {
return availableSpaces;
}
public int getOccupiedSpaces() {
return capacity - availableSpaces;
}
public boolean isFull() {
return availableSpaces == 0;
}
public void vehicleEnters() {
if (isFull()) {
throw new IllegalStateException("Parking lot is full");
}
availableSpaces--;
}
public void vehicleLeaves() {
if (availableSpaces == capacity) {
throw new IllegalStateException("Parking lot is already empty");
}
availableSpaces++;
}
}
@@ -0,0 +1,67 @@
package edu.stevens.smartpark;
/** Dependency-free tests that fail the process when parking rules break. */
public final class ParkingLotTest {
private ParkingLotTest() {
}
public static void main(String[] args) {
testArrivalsAndDepartures();
testFullAndEmptyBoundaries();
testInvalidStartingValues();
System.out.println("ParkingLot tests passed");
}
private static void testArrivalsAndDepartures() {
ParkingLot lot = new ParkingLot("Babbio Garage", 120, 42);
check(lot.getName().equals("Babbio Garage"), "name");
check(lot.getCapacity() == 120, "capacity");
check(lot.getOccupiedSpaces() == 78, "initial occupied spaces");
lot.vehicleEnters();
check(lot.getAvailableSpaces() == 41, "arrival decreases availability");
lot.vehicleLeaves();
check(lot.getAvailableSpaces() == 42, "departure restores availability");
}
private static void testFullAndEmptyBoundaries() {
ParkingLot full = new ParkingLot("River Lot", 1, 0);
check(full.isFull(), "zero available spaces means full");
expectIllegalState(full::vehicleEnters);
full.vehicleLeaves();
check(full.getAvailableSpaces() == 1, "departure from full lot");
expectIllegalState(full::vehicleLeaves);
full.vehicleEnters();
check(full.isFull(), "arrival fills the last space");
}
private static void testInvalidStartingValues() {
expectIllegalArgument(() -> new ParkingLot("", 10, 5));
expectIllegalArgument(() -> new ParkingLot("Lot", -1, 0));
expectIllegalArgument(() -> new ParkingLot("Lot", 10, -1));
expectIllegalArgument(() -> new ParkingLot("Lot", 10, 11));
}
private static void check(boolean condition, String description) {
if (!condition) {
throw new AssertionError("Failed: " + description);
}
}
private static void expectIllegalState(Runnable action) {
try {
action.run();
} catch (IllegalStateException expected) {
return;
}
throw new AssertionError("Expected IllegalStateException");
}
private static void expectIllegalArgument(Runnable action) {
try {
action.run();
} catch (IllegalArgumentException expected) {
return;
}
throw new AssertionError("Expected IllegalArgumentException");
}
}