diff --git a/trafficmon/lib/hamcrest-all-1.3.jar b/trafficmon/lib/hamcrest-all-1.3.jar new file mode 100644 index 0000000..6f62ba0 Binary files /dev/null and b/trafficmon/lib/hamcrest-all-1.3.jar differ diff --git a/trafficmon/lib/jmock-2.8.1.jar b/trafficmon/lib/jmock-2.8.1.jar new file mode 100644 index 0000000..850c7eb Binary files /dev/null and b/trafficmon/lib/jmock-2.8.1.jar differ diff --git a/trafficmon/lib/jmock-junit4-2.8.1.jar b/trafficmon/lib/jmock-junit4-2.8.1.jar new file mode 100644 index 0000000..d2a063d Binary files /dev/null and b/trafficmon/lib/jmock-junit4-2.8.1.jar differ diff --git a/trafficmon/lib/junit-4.12.jar b/trafficmon/lib/junit-4.12.jar new file mode 100644 index 0000000..3a7fc26 Binary files /dev/null and b/trafficmon/lib/junit-4.12.jar differ diff --git a/trafficmon/lib/trafficmon-externals.jar b/trafficmon/lib/trafficmon-externals.jar new file mode 100644 index 0000000..f0eb13a Binary files /dev/null and b/trafficmon/lib/trafficmon-externals.jar differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/CongestionChargeSystem.class b/trafficmon/out/production/trafficmon/com/trafficmon/CongestionChargeSystem.class new file mode 100644 index 0000000..e9abd1e Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/CongestionChargeSystem.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/CustomerAccountsService.class b/trafficmon/out/production/trafficmon/com/trafficmon/CustomerAccountsService.class new file mode 100644 index 0000000..c025f92 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/CustomerAccountsService.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/CustomerAccountsServiceInterface.class b/trafficmon/out/production/trafficmon/com/trafficmon/CustomerAccountsServiceInterface.class new file mode 100644 index 0000000..ac298fd Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/CustomerAccountsServiceInterface.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/EntryEvent.class b/trafficmon/out/production/trafficmon/com/trafficmon/EntryEvent.class new file mode 100644 index 0000000..6922702 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/EntryEvent.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/ExitEvent.class b/trafficmon/out/production/trafficmon/com/trafficmon/ExitEvent.class new file mode 100644 index 0000000..8629474 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/ExitEvent.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/Main.class b/trafficmon/out/production/trafficmon/com/trafficmon/Main.class new file mode 100644 index 0000000..f4eff6a Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/Main.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/OperationsService.class b/trafficmon/out/production/trafficmon/com/trafficmon/OperationsService.class new file mode 100644 index 0000000..9f8c007 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/OperationsService.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/OperationsServiceInterface.class b/trafficmon/out/production/trafficmon/com/trafficmon/OperationsServiceInterface.class new file mode 100644 index 0000000..fe0fa30 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/OperationsServiceInterface.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/Vehicle.class b/trafficmon/out/production/trafficmon/com/trafficmon/Vehicle.class new file mode 100644 index 0000000..98fae88 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/Vehicle.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/VehicleInterface.class b/trafficmon/out/production/trafficmon/com/trafficmon/VehicleInterface.class new file mode 100644 index 0000000..204c68b Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/VehicleInterface.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/ZoneBoundaryCrossing.class b/trafficmon/out/production/trafficmon/com/trafficmon/ZoneBoundaryCrossing.class new file mode 100644 index 0000000..558f857 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/ZoneBoundaryCrossing.class differ diff --git a/trafficmon/out/production/trafficmon/com/trafficmon/ZoneBoundaryCrossingInterface.class b/trafficmon/out/production/trafficmon/com/trafficmon/ZoneBoundaryCrossingInterface.class new file mode 100644 index 0000000..4a651f1 Binary files /dev/null and b/trafficmon/out/production/trafficmon/com/trafficmon/ZoneBoundaryCrossingInterface.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$1.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$1.class new file mode 100644 index 0000000..f0de1fc Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$1.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$10.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$10.class new file mode 100644 index 0000000..a868a9b Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$10.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$11.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$11.class new file mode 100644 index 0000000..4026c08 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$11.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$12.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$12.class new file mode 100644 index 0000000..20ef2f4 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$12.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$13.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$13.class new file mode 100644 index 0000000..4273aa5 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$13.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$14.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$14.class new file mode 100644 index 0000000..ab03645 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$14.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$15.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$15.class new file mode 100644 index 0000000..d767b63 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$15.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$16.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$16.class new file mode 100644 index 0000000..f8481f6 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$16.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$17.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$17.class new file mode 100644 index 0000000..733f92d Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$17.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$18.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$18.class new file mode 100644 index 0000000..f8a523a Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$18.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$19.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$19.class new file mode 100644 index 0000000..72b1f08 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$19.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$2.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$2.class new file mode 100644 index 0000000..ebee1ae Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$2.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$20.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$20.class new file mode 100644 index 0000000..b25dad0 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$20.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$21.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$21.class new file mode 100644 index 0000000..15ef09f Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$21.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$22.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$22.class new file mode 100644 index 0000000..5c3026e Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$22.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$3.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$3.class new file mode 100644 index 0000000..acc9e23 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$3.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$4.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$4.class new file mode 100644 index 0000000..4776af2 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$4.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$5.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$5.class new file mode 100644 index 0000000..b4b1448 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$5.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$6.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$6.class new file mode 100644 index 0000000..bd0394b Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$6.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$7.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$7.class new file mode 100644 index 0000000..b68d9f6 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$7.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$8.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$8.class new file mode 100644 index 0000000..dd21c33 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$8.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$9.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$9.class new file mode 100644 index 0000000..4d4dbc1 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest$9.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest.class b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest.class new file mode 100644 index 0000000..83b980c Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/CongestionChargeSystemTest.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/VehicleTest.class b/trafficmon/out/test/trafficmon/com/trafficmon/VehicleTest.class new file mode 100644 index 0000000..af02906 Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/VehicleTest.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/testEntryEvent.class b/trafficmon/out/test/trafficmon/com/trafficmon/testEntryEvent.class new file mode 100644 index 0000000..3ef6bea Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/testEntryEvent.class differ diff --git a/trafficmon/out/test/trafficmon/com/trafficmon/testExitEvent.class b/trafficmon/out/test/trafficmon/com/trafficmon/testExitEvent.class new file mode 100644 index 0000000..70705fe Binary files /dev/null and b/trafficmon/out/test/trafficmon/com/trafficmon/testExitEvent.class differ diff --git a/trafficmon/src/com/trafficmon/CongestionChargeSystem.java b/trafficmon/src/com/trafficmon/CongestionChargeSystem.java new file mode 100644 index 0000000..072ad83 --- /dev/null +++ b/trafficmon/src/com/trafficmon/CongestionChargeSystem.java @@ -0,0 +1,147 @@ +package com.trafficmon; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.*; + +public class CongestionChargeSystem { + //Variables + public static final long HOURS_TO_MILLI_SECONDS = 60*60*1000L; + private Map> crossingsByVehicle; + private CustomerAccountsServiceInterface customerAccountService; + private OperationsServiceInterface operationsService; + //Variables* + + //Package Private Constructor for testing + CongestionChargeSystem(Map> crossingsByVehicle,CustomerAccountsServiceInterface customerAccountService,OperationsServiceInterface opsi){ + this.crossingsByVehicle = crossingsByVehicle; + this.customerAccountService = customerAccountService; + this.operationsService = opsi; + } + + public CongestionChargeSystem(){ + this.operationsService = new OperationsService(); + this.customerAccountService = new CustomerAccountsService(); + this.crossingsByVehicle = new HashMap>(); + } + + public void vehicleEnteringZone(VehicleInterface vehicle) { + if (!crossingsByVehicle.containsKey(vehicle)) { + crossingsByVehicle.put(vehicle, new ArrayList()); + } + crossingsByVehicle.get(vehicle).add(new EntryEvent(vehicle)); + } + + public void vehicleLeavingZone(VehicleInterface vehicle) { + //Make sure vehicle is registered + if ((!crossingsByVehicle.containsKey(vehicle))||(crossingsByVehicle.get(vehicle).size()<=0)) { + return; + } + crossingsByVehicle.get(vehicle).add(new ExitEvent(vehicle)); + } + + public void calculateCharges() { + //crossingsByVehicle.clear();//reset hashmap + //For each vehicle make sure the crossing are not illegal and then calculate the charges and deduct from account + for (Map.Entry> vehicleCrossings : crossingsByVehicle.entrySet()) { + VehicleInterface vehicle = vehicleCrossings.getKey(); + List crossings = vehicleCrossings.getValue(); + if (!checkOrderingOf(crossings)) { + operationsService.triggerInvestigationInto(vehicle); + } else { + + BigDecimal charge = calculateChargeForTimeInZone(crossings); + try { + customerAccountService.deductChargeFrom(vehicle,charge); + } catch (InsufficientCreditException | AccountNotRegisteredException ex) { + operationsService.issuePenaltyNotice(vehicle, charge); + } + } + } + + } + + private double timeFromEpochToHourOfDay(long millis){ + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + Date resultantDate = new Date(millis); + String[] timeOfDay = sdf.format(resultantDate).split(":"); + return (Double.parseDouble(timeOfDay[0])+(Double.parseDouble(timeOfDay[1])/60.0)); + + } + + private BigDecimal calculateChargeForTimeInZone(List crossings){ + BigDecimal charge; + ZoneBoundaryCrossing previousEvent = crossings.get(0);//stores the previous crossing + ZoneBoundaryCrossing previousEntryEventCharged = crossings.get(0);//stores the last entry event in which you were charged + long totalTimeInZone = 0; + + if (timeFromEpochToHourOfDay(previousEntryEventCharged.timestamp()) < 14.0){ + charge= new BigDecimal(6.0);//before 2 pm + }else{ + charge= new BigDecimal(4.0);//2pm onwards will be 4 gbp + } + + for (ZoneBoundaryCrossing crossing : crossings.subList(1, crossings.size())) { + if (crossing instanceof ExitEvent) { + totalTimeInZone += crossing.timestamp()-previousEvent.timestamp(); + //For the case where you weren't charged when you entered but stayed past the 4 hour mark from the previous charge + if ( (crossing.timestamp()-previousEntryEventCharged.timestamp()) > (4*HOURS_TO_MILLI_SECONDS) ){ + long tmp_crossing_time = previousEntryEventCharged.timestamp()+(4*HOURS_TO_MILLI_SECONDS); + if (timeFromEpochToHourOfDay(tmp_crossing_time) < 14.0){ + charge = charge.add(new BigDecimal(6.0)); + }else{ + charge = charge.add(new BigDecimal(4.0)); + } + previousEntryEventCharged = new EntryEvent(crossing.getVehicle(),tmp_crossing_time);//create a phantom crossing(entry event) to make the system work + } + + }else{ + //Add Charges if previous charge was more than 4 hours ago + if ( (crossing.timestamp()-previousEntryEventCharged.timestamp()) > (4*HOURS_TO_MILLI_SECONDS) ){ + if (timeFromEpochToHourOfDay(crossing.timestamp()) < 14.0) { + charge = charge.add(new BigDecimal(6.0)); + } else{ + charge = charge.add(new BigDecimal(4.0)); + } + previousEntryEventCharged = crossing; + } + } + previousEvent = crossing; + } + + //if total time spent in the zone greater than 4 hours return 12 gbp + if (totalTimeInZone > (4* HOURS_TO_MILLI_SECONDS)){ + return new BigDecimal(12); + } + + return charge; + } + + private boolean checkOrderingOf(List crossings) { + + ZoneBoundaryCrossing previousEvent = crossings.get(0); + //Even though the vehicleLeavingZone function does not allow for exit events to be registered as the first event, it is always a good idea to perform checks in multiple places + if (previousEvent instanceof ExitEvent){ + return false; + } + //Make sure a vehicle always leaves after entering (the list size is even and every Entry is followed by and Exit) + if ((crossings.size() % 2) != 0){ + return false; + } + for (ZoneBoundaryCrossing crossing : crossings.subList(1, crossings.size())) { + if (crossing.timestamp() < previousEvent.timestamp()) { + return false; + } + if (crossing instanceof EntryEvent && previousEvent instanceof EntryEvent) { + return false; + } + if (crossing instanceof ExitEvent && previousEvent instanceof ExitEvent) { + return false; + } + previousEvent = crossing; + } + + return true; + } + +} diff --git a/trafficmon/src/com/trafficmon/CustomerAccountsService.java b/trafficmon/src/com/trafficmon/CustomerAccountsService.java new file mode 100644 index 0000000..f8715ff --- /dev/null +++ b/trafficmon/src/com/trafficmon/CustomerAccountsService.java @@ -0,0 +1,16 @@ +package com.trafficmon; + +import java.math.BigDecimal; + +/** + * Created by Shoaib on 11/19/18. + */ + +public class CustomerAccountsService implements CustomerAccountsServiceInterface { + private AccountsService registeredCustomerAccountsService = RegisteredCustomerAccountsService.getInstance(); + + @Override + public void deductChargeFrom(VehicleInterface vehicle, BigDecimal charge) throws InsufficientCreditException,AccountNotRegisteredException { + registeredCustomerAccountsService.accountFor((Vehicle) vehicle).deduct(charge); + } +} diff --git a/trafficmon/src/com/trafficmon/CustomerAccountsServiceInterface.java b/trafficmon/src/com/trafficmon/CustomerAccountsServiceInterface.java new file mode 100644 index 0000000..3048ac2 --- /dev/null +++ b/trafficmon/src/com/trafficmon/CustomerAccountsServiceInterface.java @@ -0,0 +1,12 @@ +package com.trafficmon; + +import java.math.BigDecimal; + +/** + * Created by Shoaib on 11/19/18. + */ + +public interface CustomerAccountsServiceInterface { + + void deductChargeFrom(VehicleInterface vehicle, BigDecimal charge) throws InsufficientCreditException,AccountNotRegisteredException ; +} diff --git a/trafficmon/src/com/trafficmon/EntryEvent.java b/trafficmon/src/com/trafficmon/EntryEvent.java new file mode 100644 index 0000000..f61c59a --- /dev/null +++ b/trafficmon/src/com/trafficmon/EntryEvent.java @@ -0,0 +1,9 @@ +package com.trafficmon; + +public class EntryEvent extends ZoneBoundaryCrossing{ + public EntryEvent(VehicleInterface vehicleRegistration) { + super(vehicleRegistration); + } + // Package-Private Method For Testing + EntryEvent(VehicleInterface vehicleRegistration,long time) {super(vehicleRegistration, time);} +} diff --git a/trafficmon/src/com/trafficmon/ExitEvent.java b/trafficmon/src/com/trafficmon/ExitEvent.java new file mode 100644 index 0000000..40ca455 --- /dev/null +++ b/trafficmon/src/com/trafficmon/ExitEvent.java @@ -0,0 +1,11 @@ +package com.trafficmon; + +public class ExitEvent extends ZoneBoundaryCrossing { + public ExitEvent(VehicleInterface vehicle) { + super(vehicle); + } + // Package-Private Method For Testing + ExitEvent(VehicleInterface vehicle, long time) { + super(vehicle,time); + } +} diff --git a/trafficmon/src/com/trafficmon/Main.java b/trafficmon/src/com/trafficmon/Main.java new file mode 100644 index 0000000..bec3c66 --- /dev/null +++ b/trafficmon/src/com/trafficmon/Main.java @@ -0,0 +1,26 @@ +package com.trafficmon; + +/** + * Created by Shoaib on 11/17/18. + */ + +public class Main { + public static void main(String[] args) throws Exception { + + CongestionChargeSystem congestionChargeSystem = new CongestionChargeSystem(); + congestionChargeSystem.vehicleEnteringZone(Vehicle.withRegistration("A123 XYZ")); + //delaySeconds(15); + congestionChargeSystem.vehicleEnteringZone(Vehicle.withRegistration("J091 4PY")); + //delayMinutes(30); + //congestionChargeSystem.vehicleLeavingZone(Vehicle.withRegistration("A123 XYZ")); + //delayMinutes(10); + congestionChargeSystem.vehicleLeavingZone(Vehicle.withRegistration("J091 4PY")); + congestionChargeSystem.calculateCharges(); + } + private static void delayMinutes(int mins) throws InterruptedException { + delaySeconds(mins * 60); + } + private static void delaySeconds(int secs) throws InterruptedException { + Thread.sleep(secs * 1000); + } +} diff --git a/trafficmon/src/com/trafficmon/OperationsService.java b/trafficmon/src/com/trafficmon/OperationsService.java new file mode 100644 index 0000000..7bb501a --- /dev/null +++ b/trafficmon/src/com/trafficmon/OperationsService.java @@ -0,0 +1,19 @@ +package com.trafficmon; + +import java.math.BigDecimal; + +public class OperationsService implements OperationsServiceInterface { + private PenaltiesService OpTeam = OperationsTeam.getInstance(); + + @Override + public void issuePenaltyNotice(VehicleInterface vehicle, BigDecimal charge) { + OpTeam.issuePenaltyNotice((Vehicle) vehicle,charge); + } + + @Override + public void triggerInvestigationInto(VehicleInterface vehicle){ + OpTeam.triggerInvestigationInto((Vehicle) vehicle); + } + + +} diff --git a/trafficmon/src/com/trafficmon/OperationsServiceInterface.java b/trafficmon/src/com/trafficmon/OperationsServiceInterface.java new file mode 100644 index 0000000..9434286 --- /dev/null +++ b/trafficmon/src/com/trafficmon/OperationsServiceInterface.java @@ -0,0 +1,8 @@ +package com.trafficmon; + +import java.math.BigDecimal; + +public interface OperationsServiceInterface { + void issuePenaltyNotice(VehicleInterface vehicle, BigDecimal charge); + void triggerInvestigationInto(VehicleInterface vehicle); +} diff --git a/trafficmon/src/com/trafficmon/Vehicle.java b/trafficmon/src/com/trafficmon/Vehicle.java new file mode 100644 index 0000000..f25f118 --- /dev/null +++ b/trafficmon/src/com/trafficmon/Vehicle.java @@ -0,0 +1,39 @@ +package com.trafficmon; + +public class Vehicle implements VehicleInterface { + + private final String registration; + + private Vehicle(String registration) { + this.registration = registration; + } + + static Vehicle withRegistration(String registration) { + return new Vehicle(registration); + } + + @Override + public String toString() { + return "Vehicle [" + registration + "]"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Vehicle vehicle = (Vehicle) o; + + return (registration != null) ? registration.equals(vehicle.registration) : vehicle.registration == null; + + /*if (registration != null){ + return registration.equals(vehicle.registration); + } + return (vehicle.registration == null);*/ + } + + @Override + public int hashCode() { + return registration != null ? registration.hashCode() : 0; + } +} diff --git a/trafficmon/src/com/trafficmon/VehicleInterface.java b/trafficmon/src/com/trafficmon/VehicleInterface.java new file mode 100644 index 0000000..1017a43 --- /dev/null +++ b/trafficmon/src/com/trafficmon/VehicleInterface.java @@ -0,0 +1,17 @@ +package com.trafficmon; + +/** + * Created by Shoaib on 11/17/18. + */ + +interface VehicleInterface { + + @Override + String toString(); + + @Override + boolean equals(Object o); + + @Override + int hashCode(); +} diff --git a/trafficmon/src/com/trafficmon/ZoneBoundaryCrossing.java b/trafficmon/src/com/trafficmon/ZoneBoundaryCrossing.java new file mode 100644 index 0000000..eae5851 --- /dev/null +++ b/trafficmon/src/com/trafficmon/ZoneBoundaryCrossing.java @@ -0,0 +1,25 @@ +package com.trafficmon; + +public abstract class ZoneBoundaryCrossing { + + private final VehicleInterface vehicle; + private final long time; + + public ZoneBoundaryCrossing(VehicleInterface vehicle) { + this.vehicle = vehicle; + this.time = System.currentTimeMillis(); + } + //Package private constructor for testing purposes + ZoneBoundaryCrossing(VehicleInterface vehicle, long time) { + this.vehicle = vehicle; + this.time = time; + } + + public VehicleInterface getVehicle() { + return vehicle; + } + + public long timestamp() { + return time; + } +} diff --git a/trafficmon/test/com.trafficmon/CongestionChargeSystemTest.java b/trafficmon/test/com.trafficmon/CongestionChargeSystemTest.java new file mode 100644 index 0000000..15c0266 --- /dev/null +++ b/trafficmon/test/com.trafficmon/CongestionChargeSystemTest.java @@ -0,0 +1,374 @@ +package com.trafficmon; + +import org.hamcrest.Matchers; +import org.jmock.Expectations; +import org.jmock.integration.junit4.JUnitRuleMockery; +import org.junit.Rule; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static junit.framework.TestCase.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +public class CongestionChargeSystemTest { + + @Rule + public JUnitRuleMockery context = new JUnitRuleMockery(); + private OperationsServiceInterface mockOperationsService = context.mock(OperationsServiceInterface.class); + private CustomerAccountsServiceInterface mockAccountsService = context.mock(CustomerAccountsServiceInterface.class); + + private Vehicle testVehicle = Vehicle.withRegistration("A123 XYZ"); + private Vehicle testVehicle2 = Vehicle.withRegistration("B113 ZYZ"); + private Map> crossingsByVehicle = new HashMap>(); + private CongestionChargeSystem congestionChargeSystem = new CongestionChargeSystem(crossingsByVehicle, mockAccountsService,mockOperationsService); + private final static long START_OF_DAY = 1543536000001L;//start of a day in ms from epoch (for testing purposes) + + private void addCrossingEvent(double EntryHour, double ExitHour, VehicleInterface testVehiclee ){ + /*eventLog.add(new EntryEvent(testVehicle, (START_OF_DAY+(long)(EntryHour*CongestionChargeSystem.HOURS_TO_MILLI_SECONDS)))); + eventLog.add(new ExitEvent(testVehicle, (START_OF_DAY+(long)(ExitHour*CongestionChargeSystem.HOURS_TO_MILLI_SECONDS)) ));*/ + if (!crossingsByVehicle.containsKey(testVehiclee)) { + crossingsByVehicle.put(testVehiclee, new ArrayList()); + } + crossingsByVehicle.get(testVehiclee).add(new EntryEvent(testVehiclee, (START_OF_DAY+(long)(EntryHour*CongestionChargeSystem.HOURS_TO_MILLI_SECONDS)))); + crossingsByVehicle.get(testVehiclee).add(new ExitEvent(testVehiclee, (START_OF_DAY+(long)(ExitHour*CongestionChargeSystem.HOURS_TO_MILLI_SECONDS)) )); + } + + @Test + public void testVariables(){ + assertThat(crossingsByVehicle.size(), is(0)); + assertThat(CongestionChargeSystem.HOURS_TO_MILLI_SECONDS, is(60*60*1000L)); + } + + @Test + public void testVehicleEnteringZone(){ + assertThat(crossingsByVehicle.size(), is(0)); + congestionChargeSystem.vehicleEnteringZone(testVehicle); + assertThat(crossingsByVehicle.size(), is(1)); + assertTrue(crossingsByVehicle.get(testVehicle).get(0) instanceof EntryEvent); + assertThat(crossingsByVehicle.get(testVehicle).size(),is(1)); + + congestionChargeSystem.vehicleEnteringZone(testVehicle); + assertThat(crossingsByVehicle.get(testVehicle).size(), is(2)); + assertTrue(crossingsByVehicle.get(testVehicle).get(1) instanceof EntryEvent); + } + + @Test + public void testVehicleLeavingZone(){ + assertThat(crossingsByVehicle.size(), is(0)); + congestionChargeSystem.vehicleEnteringZone(testVehicle); + assertThat(crossingsByVehicle.size(), is(1)); + assertThat(crossingsByVehicle.get(testVehicle).size(), is(1)); + assertTrue(crossingsByVehicle.get(testVehicle).get(0) instanceof EntryEvent); + assertThat(crossingsByVehicle.get(testVehicle).get(0).getVehicle() , is(testVehicle)); + assertTrue( (crossingsByVehicle.get(testVehicle).get(0).timestamp() - System.currentTimeMillis()) < 10 );//the timestamp will close to current system time + + congestionChargeSystem.vehicleLeavingZone(testVehicle); + assertThat(crossingsByVehicle.size(), is(1)); + assertThat(crossingsByVehicle.get(testVehicle).size(), is(2)); + assertTrue(crossingsByVehicle.get(testVehicle).get(1) instanceof ExitEvent); + assertThat(crossingsByVehicle.get(testVehicle).get(1).getVehicle() , is(testVehicle)); + } + + @Test + public void testPreviouslyRegistered(){ + //Can not start with an exit event (testing previously registered) + assertThat(crossingsByVehicle.size(), is(0)); + congestionChargeSystem.vehicleLeavingZone(testVehicle); + assertThat(crossingsByVehicle.size(), is(0)); + + congestionChargeSystem.vehicleEnteringZone(testVehicle); + assertThat(crossingsByVehicle.size(), is(1)); + assertThat(crossingsByVehicle.get(testVehicle).size(), is(1)); + congestionChargeSystem.vehicleLeavingZone(testVehicle2); + assertThat(crossingsByVehicle.size(), is(1)); + assertThat(crossingsByVehicle.get(testVehicle).size(), is(1)); + //Can not start with an exit event (testing previously registered)* + } + + + + @Test + public void testCalculateChargesNoEntry(){ + context.checking(new Expectations() {{ + never(mockAccountsService); + }}); + assertThat(crossingsByVehicle.size(), is(0)); + congestionChargeSystem.calculateCharges(); + assertThat(crossingsByVehicle.size(), is(0)); + + } + + + //Testing checkOrderingOf + @Test + public void testOnlyEntry() throws Exception{ + context.checking(new Expectations() {{ + never(mockAccountsService); + exactly(1).of(mockOperationsService).triggerInvestigationInto(with(equal(testVehicle))); + + }}); + congestionChargeSystem.vehicleEnteringZone(testVehicle); + congestionChargeSystem.calculateCharges(); + + } + + @Test + public void testOnlyExit() throws Exception{ + context.checking(new Expectations() {{ + never(mockAccountsService); + exactly(1).of(mockOperationsService).triggerInvestigationInto(with(equal(testVehicle))); + + }}); + crossingsByVehicle.put(testVehicle, new ArrayList()); + crossingsByVehicle.get(testVehicle).add(new ExitEvent(testVehicle, START_OF_DAY)); + congestionChargeSystem.calculateCharges(); + } + + + @Test + public void testSecondCrossingBeforeFirstOne() throws Exception{ + context.checking(new Expectations() {{ + never(mockAccountsService); + exactly(1).of(mockOperationsService).triggerInvestigationInto(with(equal(testVehicle))); + + }}); + addCrossingEvent(0.5,0.5,testVehicle); + addCrossingEvent(0,0.6,testVehicle); + congestionChargeSystem.calculateCharges(); + } + //Testing checkOrderingOf* + + //Make sure charges are correct for all cases + @Test + public void testCalculateChargesOneCrossingBeforeTwoPM() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(6.00)) )); + + }}); + addCrossingEvent(0,0.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + + @Test + public void testCalculateChargesOneCrossingAtTwoPM() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(4.00)) )); + + }}); + addCrossingEvent(14,14.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesOneCrossingAfterTwoPM() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(4.00)) )); + + }}); + addCrossingEvent(14.1,14.5,testVehicle); + congestionChargeSystem.calculateCharges(); + + } + + //if staying for exactly 4 hours should not charge 12 gbp + @Test + public void testCalculateChargesOneCrossingBeforeTwoPMForFourHours() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(6.00)) )); + + }}); + addCrossingEvent(0,4,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + + @Test + public void testCalculateChargesOneCrossingAfterTwoPMForFourHours() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(4.00)) )); + + }}); + addCrossingEvent(15,19,testVehicle); + congestionChargeSystem.calculateCharges(); + } + //if staying for exactly 4 hours should not charge 12 gbp* + + //More than 4 hours regardless of entry time should be charge 12 gbp + @Test + public void testCalculateChargesOneCrossingBeforeTwoPMOverFourHours() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + + }}); + addCrossingEvent(0,8,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesOneCrossingAfterTwoPMOverFourHours() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + }}); + addCrossingEvent(14.1,19.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + //More than 4 hours regardless of entry time should be charge 12 gbp* + + //Make sure can enter and exit multiple times within four hours of entry where you were charged without extra charges + @Test + public void testCalculateChargesMultipleCrossingBeforeTwoWithinFourHours() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(6.00)) )); + + }}); + addCrossingEvent(0,0.5,testVehicle); + addCrossingEvent(1,1.1,testVehicle); + addCrossingEvent(1.5,1.9,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesMultipleCrossingAfterTwoWithinFourHours() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(4.00)) )); + + }}); + addCrossingEvent(14,14.5,testVehicle); + addCrossingEvent(15.5,15.6,testVehicle); + addCrossingEvent(16.5,17.9,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + + @Test + public void testCalculateChargesMultipleCrossingBeforeTwoAndAfterTwoWithinFourHours() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(6.00)) )); + + }}); + addCrossingEvent(13.5,14,testVehicle); + addCrossingEvent(15,16.1,testVehicle); + addCrossingEvent(17.4,17.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + //Make sure can enter and exit multiple times within four hours of entry where you were charged without extra charges* + + //Make sure you are charged appropriately if you enter after four hours from entry you were previously charged at + @Test + public void testCalculateChargesTwoCrossingBeforeTwoOverFourHourIntervals() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + + }}); + addCrossingEvent(0,1,testVehicle); + addCrossingEvent(4.1,4.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesMultipleCrossingBeforeTwoOverFourHourIntervals() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(18.00)) )); + + }}); + addCrossingEvent(0,1,testVehicle); + addCrossingEvent(4.1,4.5,testVehicle); + addCrossingEvent(8.1,8.5,testVehicle); + congestionChargeSystem.calculateCharges(); + //Discount if total time exceeds four hours + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + + }}); + addCrossingEvent(12.1,16.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesTwoCrossingAfterTwoOverFourHourIntervals() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(8.00)) )); + }}); + addCrossingEvent(14,14.5,testVehicle); + addCrossingEvent(18.1,18.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + //Make sure you are charged appropriately if you enter after four hours from entry you were previously charged at (if total time under 4 hours)* + + //Make sure you get charged if you enter within four hours of the previous entry for which you were charged but stayed past the 4 hour mark + @Test + public void testCalculateChargesInterFourHourIntervalCrossingsBefore2PM() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + }}); + addCrossingEvent(0,0.5,testVehicle); + addCrossingEvent(3.8,4.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesInterFourHourIntervalCrossingsAfter2PM() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(8.00)) )); + }}); + addCrossingEvent(14,14.5,testVehicle); + addCrossingEvent(17.8,18.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesInterFourHourIntervalCrossingsBefore2TillAfter2() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(10.00)) )); + }}); + addCrossingEvent(10,10.5,testVehicle); + addCrossingEvent(13.999,14.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + + @Test + public void testCalculateChargesMultipleCrossingsUnderFourHoursOverFourHourIntervals() throws Exception{ + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + }}); + addCrossingEvent(14,14.5,testVehicle); + addCrossingEvent(18.1,18.5,testVehicle); + addCrossingEvent(22.1,23.5,testVehicle); + congestionChargeSystem.calculateCharges(); + } + //Make sure you get charged if you enter within four hours of the previous entry for which you were charged but stayed past the 4 hour mark* + @Test + public void testCalculateChargesComplexCase() throws Exception{ + Vehicle testVehicle3 = Vehicle.withRegistration("C153 ZIZ"); + Vehicle testVehicle4 = Vehicle.withRegistration("B113 ZYZ"); + Vehicle testVehicle5 = Vehicle.withRegistration("B11R ZYZ"); + context.checking(new Expectations() {{ + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle3)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle)), with(Matchers.comparesEqualTo(new BigDecimal(12.00)) )); + exactly(1).of(mockAccountsService).deductChargeFrom(with(equal(testVehicle4)), with(Matchers.comparesEqualTo(new BigDecimal(20.00)) )); + exactly(1).of(mockOperationsService).triggerInvestigationInto(with(equal(testVehicle5))); + }}); + addCrossingEvent(14,14.5,testVehicle); + addCrossingEvent(18.1,18.5,testVehicle); + addCrossingEvent(22.1,23.5,testVehicle); + + addCrossingEvent(0,0.1,testVehicle4); + addCrossingEvent(3.8,4.5,testVehicle2); + addCrossingEvent(18.1,18.5,testVehicle2); + addCrossingEvent(22.1,23.5,testVehicle2); + + + addCrossingEvent(0,5,testVehicle3); + crossingsByVehicle.put(testVehicle5, new ArrayList()); + crossingsByVehicle.get(testVehicle5).add(new EntryEvent(testVehicle5, START_OF_DAY)); + congestionChargeSystem.calculateCharges(); + } + +} \ No newline at end of file diff --git a/trafficmon/test/com.trafficmon/VehicleTest.java b/trafficmon/test/com.trafficmon/VehicleTest.java new file mode 100644 index 0000000..d0c05ef --- /dev/null +++ b/trafficmon/test/com.trafficmon/VehicleTest.java @@ -0,0 +1,41 @@ +package com.trafficmon; + +import org.junit.Test; + +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +public class VehicleTest { + Vehicle testVehicle = Vehicle.withRegistration("testVehicle"); + + @Test + public void testInstanceVariable() + { + assertThat(testVehicle.toString() , containsString("testVehicle")); + } + + @Test + public void testEqualsMethod() + { + assertTrue(testVehicle.equals(testVehicle)); + assertFalse(testVehicle.equals(null)); + Vehicle testVehicle2 = Vehicle.withRegistration("testVehicle2"); + assertFalse(testVehicle.equals(testVehicle2)); + } + + @Test + public void testToStringMethod() + { + assertThat(testVehicle.toString() , is("Vehicle [testVehicle]")); + } + + @Test + public void testHashCode() + { + assertThat(testVehicle.hashCode() , is("testVehicle".hashCode())); + assertThat(Vehicle.withRegistration(null).hashCode() , is(0)); + } +} diff --git a/trafficmon/test/com.trafficmon/testEntryEvent.java b/trafficmon/test/com.trafficmon/testEntryEvent.java new file mode 100644 index 0000000..b29a931 --- /dev/null +++ b/trafficmon/test/com.trafficmon/testEntryEvent.java @@ -0,0 +1,33 @@ +package com.trafficmon; + +import org.junit.Test; + +import static junit.framework.TestCase.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.closeTo; +import static org.hamcrest.Matchers.is; + +public class testEntryEvent +{ + private Vehicle testVehicle = Vehicle.withRegistration("testVehicle"); + private EntryEvent testEntryEvent = new EntryEvent(testVehicle); + + @Test + public void testTimestamp() + { + assertThat((double) testEntryEvent.timestamp() , is(closeTo((double)System.currentTimeMillis(), 100))); + } + + @Test + public void testSetVehicle() + { + assertTrue(testEntryEvent instanceof EntryEvent); + } + + @Test + public void testGetVehicle() + { + assertThat(testEntryEvent.getVehicle() , is(testVehicle)); + + } +} diff --git a/trafficmon/test/com.trafficmon/testExitEvent.java b/trafficmon/test/com.trafficmon/testExitEvent.java new file mode 100644 index 0000000..12adfcd --- /dev/null +++ b/trafficmon/test/com.trafficmon/testExitEvent.java @@ -0,0 +1,33 @@ +package com.trafficmon; + +import org.junit.Test; + +import static junit.framework.TestCase.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.closeTo; +import static org.hamcrest.Matchers.is; + +public class testExitEvent +{ + Vehicle testVehicle = Vehicle.withRegistration("testVehicle"); + ExitEvent testExitEvent = new ExitEvent(testVehicle); + + @Test + public void testTimestamp() + { + assertThat((double) testExitEvent.timestamp() , is(closeTo((double)System.currentTimeMillis(), 100))); + } + + @Test + public void testSetVehicle() + { + assertTrue(testExitEvent instanceof ExitEvent); + } + + @Test + public void testGetVehicle() + { + assertThat(testExitEvent.getVehicle() , is(testVehicle)); + + } +}