-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfacade_test.dart
119 lines (92 loc) · 3.15 KB
/
facade_test.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import 'package:test/test.dart';
class RoomRepository {
final List<Room> _rooms = [];
void add(Room room) {
_rooms.add(room);
}
Iterable<Room> get rooms => List.unmodifiable(_rooms);
}
class Room {
final String number;
const Room(this.number);
@override
String toString() => "Room $number";
}
class ReservationRepository {
final List<Reservation> _reservations = [];
Iterable<Reservation> get reservations => List.unmodifiable(_reservations);
void add(Reservation reservation) => _reservations.add(reservation);
}
class Reservation {
final DateTime from;
final DateTime to;
final String roomNumber;
Reservation({required this.from, required this.to, required this.roomNumber})
: assert(from.isBefore(to));
}
class HotelFacade {
final RoomRepository _roomRepository;
final ReservationRepository _reservationRepository;
const HotelFacade(this._roomRepository, this._reservationRepository);
Iterable<Room> findVacantRooms(DateTime from, DateTime to) {
assert(from.isBefore(to));
return _roomRepository.rooms.where((room) => _isVacant(room, from, to));
}
bool _isVacant(Room room, DateTime from, DateTime to) {
return _reservationRepository.reservations.every((reservation) =>
reservation.roomNumber != room.number ||
_intersects(reservation.from, reservation.to, from, to));
}
bool _intersects(
DateTime firstFrom,
DateTime firstTo,
DateTime secondFrom,
DateTime secondTo,
) =>
firstFrom.isAfter(secondTo) || firstTo.isBefore(secondFrom);
void addReservation(Reservation reservation) {
_reservationRepository.add(reservation);
}
Iterable<Reservation> findReservations(DateTime from, DateTime to) {
return _reservationRepository.reservations.where((reservation) =>
(reservation.from.isAfter(from) ||
reservation.from.isAtSameMomentAs(from)) &&
(reservation.to.isBefore(to) || reservation.to.isAtSameMomentAs(to)));
}
}
void main() {
group("hotel facade", () {
late HotelFacade facade;
Room room = Room("404");
DateTime from = DateTime(2018, 12, 24);
DateTime to = DateTime(2018, 12, 30);
void initializeFacade() {
final roomRepository = RoomRepository()..add(room);
final reservationRepository = ReservationRepository();
facade = HotelFacade(roomRepository, reservationRepository);
}
group("when adding reservation", () {
initializeFacade();
final reservation = Reservation(
from: from,
to: to,
roomNumber: room.number,
);
facade.addReservation(reservation);
test("should have a reservation for a date range", () {
final foundReservations = facade.findReservations(from, to);
expect(foundReservations.length, equals(1));
expect(foundReservations.elementAt(0), equals(reservation));
});
test("should have no free rooms left", () {
final rooms = facade.findVacantRooms(from, to);
expect(rooms, isEmpty);
});
});
test("should find empty room", () {
initializeFacade();
final rooms = facade.findVacantRooms(from, to);
expect(rooms.length, equals(1));
});
});
}