Author SHA1 Message Date
smartpark-ci 1a5f2b4288 Repair parking availability test (refs #9)
smartpark-app-ci/pipeline/pr-main This commit looks good
2026-10-08 16:24:10 -04:00
smartpark-ci 7040a00708 Demonstrate failing Jenkins check (refs #9)
smartpark-app-ci/pipeline/pr-main There was a failure building this commit
2026-10-08 16:12:43 -04:00
smartpark-ci 68613f38df Add simulated parking capacity and Jenkins CI (refs #9)
smartpark-app-ci/pipeline/pr-main This commit looks good
2026-10-08 11:24:57 -04:00
vincentpenalosa ba7eb30138 Merge pull request 'Expand SmartPark product README' (#7) from issue-2-smartpark-readme into main
Reviewed-on: https://git.137-184-97-250.nip.io/stevens-smartpark/smartpark-app/pulls/7
Reviewed-by: vincentpenalosa <vpenalos@stevens.edu>

good overview of the project
2026-09-30 23:38:48 +00:00
nicasaoi d601968d32 Removed extra spaces in Planned Parking Information 2026-09-30 23:37:08 +00:00
nicasaoi fa8fb79b63 Added Current Project Status for SmartPark product README 2026-09-30 22:25:37 +00:00
nicasaoi b7aaebc7d6 Expand SmartPark product README 2026-09-30 22:15:09 +00:00
6 changed files with 262 additions and 2 deletions
+2
View File
@@ -0,0 +1,2 @@
build/
*.class
Vendored
+34
View File
@@ -0,0 +1,34 @@
pipeline {
agent any
options {
skipDefaultCheckout()
disableConcurrentBuilds()
timeout(time: 10, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '10'))
}
stages {
stage('Checkout') {
steps {
checkout scm
sh 'git rev-parse HEAD'
}
}
stage('Compile and lint') {
steps {
sh '''
mkdir -p build/classes
javac -Xlint:all -Werror -d build/classes \
src/main/java/edu/stevens/smartpark/ParkingLot.java \
src/test/java/edu/stevens/smartpark/ParkingLotTest.java
'''
}
}
stage('Unit tests') {
steps {
sh 'java -cp build/classes edu.stevens.smartpark.ParkingLotTest'
}
}
}
}
+84 -2
View File
@@ -1,3 +1,85 @@
# smartpark-app
# Stevens SmartPark
Campus parking information system
Stevens SmartPark is a proposed campus parking information system for Stevens Institute of Technology.
The goal of the project is to make it easier for students to view parking information for major campus parking locations before deciding where to park.
# Intended Users
The initial system is intended for Stevens students who need parking information for campus parking areas.
# Proposed Parking Locations
The project currently focuses on these five proposed locations:
- Babbio Garage
- River Lot
- 8th Street Lot
- Castle Point Hall Lot
- Howe Center Lot
# Planned Parking Information
For each parking location, the planned application may display information such as:
- available parking spaces
- total parking spaces
- whether the location is open or closed
- opening and closing times
- overnight parking rules
- handicapped parking availability
- electric-vehicle charging availability and, when applicable, pricing
# Simulated Parking Activity
Real-time Stevens parking data may not be available to the project, so the application is planned to support simulated parking activity.
For example, when a simulated vehicle enters a parking location, the available-space count can decrease by one. When a simulated vehicle leaves, the available-space count can increase by one.
Any parking capacity or availability values used during development are **sample data** and should not be interpreted as live Stevens parking information.
Example:
```text
Parking Location: Babbio Garage
Total Spaces: 120 # sample data
Available Spaces: 42 # sample data
Open: Yes
Opening Time: 7:00 AM
Closing Time: 11:00 PM
Overnight Parking: No
EV Charging: Available
```
# Current Project Status
The SmartPark application itself and live Stevens campus parking data are not currently deployed.
The team's currently deployed operational work hub is Gitea, which is being used for source control, issues, pull requests, reviews, and project history.
## Simulated parking-capacity core
`ParkingLot` is a small, in-memory Java 21 component for the proposed SmartPark
application. It records a lot name, total capacity, and available spaces.
`vehicleEnters()` decreases availability; `vehicleLeaves()` increases it. The
component rejects counts outside the range from zero to capacity and prevents
arrivals at a full lot or departures from an empty lot. It does not fetch live
campus data, save state, or expose a web interface.
The repository's `Jenkinsfile` compiles this component with all Java compiler
warnings treated as errors, then runs automated boundary and transition tests.
The only build dependency is JDK 21, already present in the selected Jenkins
image. A clean local run from the repository root is:
```bash
mkdir -p build/classes
javac -Xlint:all -Werror -d build/classes \
src/main/java/edu/stevens/smartpark/ParkingLot.java \
src/test/java/edu/stevens/smartpark/ParkingLotTest.java
java -cp build/classes edu.stevens.smartpark.ParkingLotTest
```
Expected test output is `ParkingLot tests passed`. A nonzero exit status means
the compile or test step failed. The generated `build/` directory is ignored by
Git. The Jenkins pipeline is intended for trusted team changes only; it runs
on the Jenkins controller because this small assignment deployment has no
separate build agent.
+18
View File
@@ -0,0 +1,18 @@
services:
jenkins:
image: jenkins/jenkins:2.580.1-jdk21
restart: unless-stopped
mem_limit: 768m
environment:
JAVA_OPTS: "-Xms128m -Xmx384m"
volumes:
- jenkins_home:/var/jenkins_home
networks:
- color-net
volumes:
jenkins_home:
networks:
color-net:
external: true
@@ -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");
}
}