Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a5f2b4288 | ||
|
|
7040a00708 | ||
|
|
68613f38df | ||
|
|
ba7eb30138 | ||
|
|
d601968d32 | ||
|
|
fa8fb79b63 | ||
|
|
b7aaebc7d6 |
@@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
*.class
|
||||||
Vendored
+34
@@ -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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user