Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mikolajkapica committed Jun 25, 2024
1 parent 0bd12d5 commit e8e329c
Show file tree
Hide file tree
Showing 7 changed files with 417 additions and 7 deletions.
40 changes: 40 additions & 0 deletions api/src/main/scala/system/schedulers/PriorityScheduler.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package system.schedulers

import server.Schemas.PickupRequest
import system.Direction
import system.ElevatorCab

object PriorityScheduler {

def findBestCab(elevatorCabs: List[ElevatorCab], request: PickupRequest, floorQuantity: Int)
: ElevatorCab = {
val scoredCabs = elevatorCabs.map { cab =>
val distanceScore = Math.abs(cab.currentFloor - request.fromFloor)
val directionScore =
if (
cab.direction == Direction.Idle ||
cab.direction == Direction.MovingUp && request.direction > 0 && cab.currentFloor <= request.fromFloor ||
cab.direction == Direction.MovingDown && request.direction < 0 && cab.currentFloor >= request.fromFloor
)
0
else
Int.MaxValue
val requestsSizeScore = cab.dropRequests.size * .5
(cab, distanceScore + directionScore + requestsSizeScore)
}

val bestCab = scoredCabs.minBy(_._2)._1
bestCab
}

}

// val requestThatCanChangeDirection = cab
// .dropRequests
// .minBy(r =>
// if (request.direction > 0)
// r.targetFloor
// else
// -r.targetFloor
// )
// Math.abs(request.fromFloor - requestThatCanChangeDirection.targetFloor)
7 changes: 0 additions & 7 deletions api/src/test/scala/AppSuite.scala

This file was deleted.

83 changes: 83 additions & 0 deletions api/src/test/scala/system/BuildingSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import org.scalatest.funsuite.AnyFunSuite
import server.Schemas.DropRequest
import server.Schemas.PickupRequest
import system.Building
import system.ElevatorCab

import scala.collection.immutable.HashMap
import scala.collection.immutable.SortedSet

class BuildingTest extends AnyFunSuite {
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor)

test("Add person waiting on a specific floor") {
val initialFloors = HashMap(1 -> 0, 2 -> 0, 3 -> 0)
val building = Building(initialFloors, List(), List())

val updatedBuilding = building.addPersonWaitingOnFloor(2)

assert(updatedBuilding.floors(1) == 0)
assert(updatedBuilding.floors(2) == 1)
assert(updatedBuilding.floors(3) == 0)
}

test("Add multiple pickup requests") {
val initialFloors = HashMap(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)
val pickupRequests = List(
PickupRequest(2, 1),
PickupRequest(3, -1),
PickupRequest(2, 1),
)
val building = Building(initialFloors, List(), List())

val updatedBuilding = building.addPickupRequests(pickupRequests)

assert(updatedBuilding.floors(1) == 0)
assert(updatedBuilding.floors(2) == 2)
assert(updatedBuilding.floors(3) == 1)
assert(updatedBuilding.floors(4) == 0)
assert(updatedBuilding.outsideRequests == pickupRequests)
}

test("Add person waiting on an already populated floor") {
val initialFloors = HashMap(1 -> 1, 2 -> 3, 3 -> 0)
val building = Building(initialFloors, List(), List())

val updatedBuilding = building.addPersonWaitingOnFloor(2)

assert(updatedBuilding.floors(1) == 1)
assert(updatedBuilding.floors(2) == 4)
assert(updatedBuilding.floors(3) == 0)
}

test("Add pickup requests with existing requests") {
val initialFloors = HashMap(1 -> 1, 2 -> 2, 3 -> 0)
val existingRequests = List(PickupRequest(1, 1))
val newRequests = List(
PickupRequest(2, 1),
PickupRequest(3, -1),
)
val building = Building(initialFloors, List(), existingRequests)

val updatedBuilding = building.addPickupRequests(newRequests)

assert(updatedBuilding.floors(1) == 1)
assert(updatedBuilding.floors(2) == 3)
assert(updatedBuilding.floors(3) == 1)
assert(updatedBuilding.outsideRequests == existingRequests ++ newRequests)
}

test("Add pickup request and check elevators unchanged") {
val initialFloors = HashMap(1 -> 0, 2 -> 0, 3 -> 0)
val initialCabs = List(ElevatorCab(1, 1, SortedSet(DropRequest(2))))
val pickupRequests = List(PickupRequest(2, 1))
val building = Building(initialFloors, initialCabs, List())

val updatedBuilding = building.addPickupRequests(pickupRequests)

assert(updatedBuilding.floors(1) == 0)
assert(updatedBuilding.floors(2) == 1)
assert(updatedBuilding.floors(3) == 0)
assert(updatedBuilding.elevatorCabs == initialCabs)
}
}
109 changes: 109 additions & 0 deletions api/src/test/scala/system/ElevatorCabSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package system

import org.scalatest.funsuite.AnyFunSuite
import server.Schemas.DropRequest
import server.Schemas.PickupRequest
import system.Building
import system.ElevatorCab

import scala.collection.immutable.HashMap
import scala.collection.immutable.SortedSet

class ElevatorCabSuite extends AnyFunSuite {
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor)

test("Get target floor when moving up") {
val dropRequests = SortedSet(DropRequest(5), DropRequest(10))(dropRequestOrdering)
val elevator = ElevatorCab(1, 3, dropRequests, Direction.MovingUp)
assert(elevator.targetFloor.contains(5))
}

test("Get target floor when moving down") {
val dropRequests =
SortedSet(DropRequest(1), DropRequest(2), DropRequest(5))(dropRequestOrdering)
val elevator = ElevatorCab(1, 4, dropRequests, Direction.MovingDown)
assert(elevator.targetFloor.contains(2))
}

test("Get target floor when idle") {
val dropRequests = SortedSet(DropRequest(1), DropRequest(2))(dropRequestOrdering)
val elevator = ElevatorCab(1, 4, dropRequests, Direction.Idle)
assert(elevator.targetFloor.isEmpty)
}

test("Step when moving up") {
val dropRequests = SortedSet(DropRequest(5))(dropRequestOrdering)
val elevator = ElevatorCab(1, 3, dropRequests, Direction.MovingUp)
val updatedElevator = elevator.step
assert(updatedElevator.currentFloor == 4)
}

test("Step when moving down") {
val dropRequests = SortedSet(DropRequest(1))(dropRequestOrdering)
val elevator = ElevatorCab(1, 3, dropRequests, Direction.MovingDown)
val updatedElevator = elevator.step
assert(updatedElevator.currentFloor == 2)
}

test("Step when idle and on target floor") {
val dropRequests = SortedSet(DropRequest(3))(dropRequestOrdering)
val elevator = ElevatorCab(1, 3, dropRequests, Direction.Idle)
val updatedElevator = elevator.step
assert(updatedElevator.dropRequests.isEmpty)
}

test("Add new request when idle") {
val dropRequests = SortedSet(DropRequest(5))(dropRequestOrdering)
val elevator = ElevatorCab(1, 3, SortedSet.empty, Direction.Idle)
val updatedElevator = elevator.addNewRequest(DropRequest(5))
assert(updatedElevator.dropRequests.contains(DropRequest(5)))
assert(updatedElevator.direction == Direction.MovingUp)
}

test("Add new request when moving up") {
val dropRequests = SortedSet(DropRequest(7))(dropRequestOrdering)
val elevator = ElevatorCab(1, 5, dropRequests, Direction.MovingUp)
val updatedElevator = elevator.addNewRequest(DropRequest(9))
assert(updatedElevator.dropRequests.contains(DropRequest(9)))
assert(updatedElevator.direction == Direction.MovingUp)
}

test("Add new request when moving down") {
val dropRequests = SortedSet(DropRequest(3))(dropRequestOrdering)
val elevator = ElevatorCab(1, 5, dropRequests, Direction.MovingDown)
val updatedElevator = elevator.addNewRequest(DropRequest(1))
assert(updatedElevator.dropRequests.contains(DropRequest(1)))
assert(updatedElevator.direction == Direction.MovingDown)
}

test("Add multiple requests when idle") {
val dropRequests = Seq(DropRequest(5), DropRequest(2))
val expectedDropRequests = SortedSet(DropRequest(2), DropRequest(5))(dropRequestOrdering)
val elevator = ElevatorCab(1, 3, SortedSet.empty, Direction.Idle)
val updatedElevator = elevator.addMultipleRequests(dropRequests)
assert(updatedElevator.dropRequests == expectedDropRequests)
assert(updatedElevator.direction == Direction.MovingDown)
}

test("Add multiple requests when moving up") {
val initialRequests = SortedSet(DropRequest(7))(dropRequestOrdering)
val newRequests = Seq(DropRequest(9), DropRequest(10))
val elevator = ElevatorCab(1, 5, initialRequests, Direction.MovingUp)
val updatedElevator = elevator.addMultipleRequests(newRequests)
assert(
updatedElevator.dropRequests == SortedSet(DropRequest(7), DropRequest(9), DropRequest(10))
)
assert(updatedElevator.direction == Direction.MovingUp)
}

test("Add multiple requests when moving down") {
val initialRequests = SortedSet(DropRequest(3))(dropRequestOrdering)
val newRequests = Seq(DropRequest(1), DropRequest(2))
val elevator = ElevatorCab(1, 5, initialRequests, Direction.MovingDown)
val updatedElevator = elevator.addMultipleRequests(newRequests)
assert(
updatedElevator.dropRequests == SortedSet(DropRequest(1), DropRequest(2), DropRequest(3))
)
assert(updatedElevator.direction == Direction.MovingDown)
}
}
44 changes: 44 additions & 0 deletions api/src/test/scala/system/SimulationSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package system

import org.scalatest.funsuite.AnyFunSuite
import server.Schemas.{DropRequest, PickupRequest}

import scala.collection.immutable.HashMap
import scala.util.Random

class SimulationSuite extends AnyFunSuite {
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor)
private final val RNG_SEED = 42
private final val RANDOM = new Random(RNG_SEED)
private final val CAB_QUANTITY = 16
private final val FLOORS = 10
private final val MAX_PICKUP_REQUESTS_PER_STEP = 10

class SimulationTest extends AnyFunSuite {

test("Generate Building") {
val building = Simulation.generateBuilding()
assert(building.floors.size == FLOORS)
assert(building.floors.forall(_._2 == 0))
assert(building.elevatorCabs.size == CAB_QUANTITY)
assert(building.outsideRequests.isEmpty)
}

test("Run Simulation Step") {
val initialBuilding = Simulation.generateBuilding()
val updatedBuilding = Simulation.run(initialBuilding)

assert(updatedBuilding.floors.size == FLOORS)
assert(updatedBuilding.elevatorCabs.size == CAB_QUANTITY)
}

test("Simulation handles new requests correctly") {
val initialBuilding = Simulation.generateBuilding()
val newRequests = List(PickupRequest(1, 1), PickupRequest(2, -1))
val buildingWithNewRequests = initialBuilding.addPickupRequests(newRequests)
assert(buildingWithNewRequests.outsideRequests == newRequests)
assert(newRequests.forall(req => buildingWithNewRequests.floors(req.fromFloor) > 0))
}
}

}
37 changes: 37 additions & 0 deletions api/src/test/scala/system/schedulers/FIFOSchedulerSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package system.schedulers

import org.scalatest.funsuite.AnyFunSuite
import server.Schemas.DropRequest
import server.Schemas.PickupRequest
import system.ElevatorCab
import system.schedulers.FIFOScheduler.findBestCab

import scala.collection.immutable.SortedSet

class FIFOSchedulerSuite extends AnyFunSuite {
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor)

test("Single Elevator") {
val elevator = ElevatorCab(1, 1, SortedSet(DropRequest(3)))
val request = PickupRequest(5, 1)
val result = findBestCab(List(elevator), request, 10)
assert(result == elevator)
}

test("Second elevator is closer") {
val elevator1 = ElevatorCab(1, 1, SortedSet(DropRequest(3)))
val elevator2 = ElevatorCab(2, 4, SortedSet(DropRequest(4)))
val request = PickupRequest(5, 1)
val result = findBestCab(List(elevator1), request, 10)
assert(result == elevator1)
}

test("Second elevator is already on the pickup floor") {
val elevator1 = ElevatorCab(1, 1, SortedSet(DropRequest(3)))
val elevator2 = ElevatorCab(2, 4, SortedSet(DropRequest(2)))
val request = PickupRequest(4, 1)
val result = findBestCab(List(elevator1, elevator2), request, 10)
assert(result == elevator1)
}

}
Loading

0 comments on commit e8e329c

Please sign in to comment.