GCC Code Coverage Report


Directory: ./
File: test/unit-tests/test_integration.cpp
Date: 2025-12-16 19:41:02
Exec Total Coverage
Lines: 51 51 100.0%
Functions: 3 3 100.0%
Branches: 29 58 50.0%

Line Branch Exec Source
1 /**
2 * @file test_integration.cpp
3 * @brief Integration tests: Entry and Exit controllers on same event bus
4 * Cross-check that entry actions don't affect exit, and vice versa.
5 */
6
7 #include "mocks/MockGpioInput.h"
8 #include "mocks/MockGate.h"
9 #include "mocks/MockEventBus.h"
10 #include "mocks/MockTicketService.h"
11 #include "EntryGateController.h"
12 #include "ExitGateController.h"
13 #include <cassert>
14 #include <cstdio>
15
16 1 void test_entry_does_not_affect_exit() {
17
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 printf("Test: Entry does not affect Exit\n");
18
19
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 MockEventBus eventBus;
20 1 MockGpioInput entryButton;
21 1 MockGate entryGate;
22 1 MockGate exitGate;
23 1 MockTicketService tickets(5);
24
25
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 EntryGateController entry(eventBus, entryButton, entryGate, tickets, 50);
26
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ExitGateController exitc(eventBus, exitGate, tickets, 50, 10);
27
28 // Trigger entry flow
29 // Publish entry button press on event bus
30
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 eventBus.publish(Event(EventType::EntryButtonPressed));
31
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 eventBus.processAllPending();
32
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(entry.getState() == EntryGateState::OpeningBarrier);
33
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(entryGate.isOpen() == true);
34
35 // Exit must remain idle and gate closed
36
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(exitc.getState() == ExitGateState::Idle);
37
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(exitGate.isOpen() == false);
38
39 // Advance entry to waiting for car
40
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 entry.TEST_forceBarrierTimeout();
41
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(entry.getState() == EntryGateState::WaitingForCar);
42
43 // Cross: still no change at exit
44
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(exitc.getState() == ExitGateState::Idle);
45
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(exitGate.isOpen() == false);
46
47
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 printf(" ✓ No cross-effects from entry to exit\n\n");
48 1 }
49
50 1 void test_exit_does_not_affect_entry() {
51
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 printf("Test: Exit does not affect Entry\n");
52
53
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 MockEventBus eventBus;
54 1 MockGpioInput entryButton;
55 1 MockGate entryGate;
56 1 MockGate exitGate;
57 1 MockTicketService tickets(5);
58
59 // Prepare a PAID ticket so exit validation can succeed
60
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 uint32_t ticketId = tickets.getNewTicket(); // ID=1
61
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 tickets.payTicket(ticketId);
62
63
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 EntryGateController entry(eventBus, entryButton, entryGate, tickets, 50);
64
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ExitGateController exitc(eventBus, exitGate, tickets, 50, 10);
65
66 // Trigger exit flow via manual validation
67
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 bool validated = exitc.validateTicketManually(ticketId);
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(validated);
69
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 eventBus.processAllPending();
70
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(exitc.getState() == ExitGateState::OpeningBarrier);
71
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(exitGate.isOpen() == true);
72
73 // Entry must remain idle and gate closed
74
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(entry.getState() == EntryGateState::Idle);
75
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 assert(entryGate.isOpen() == false);
76
77
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 printf(" ✓ No cross-effects from exit to entry\n\n");
78 1 }
79
80 1 int main() {
81 1 printf("=================================\n");
82 1 printf("Integration Tests (Entry <-> Exit)\n");
83 1 printf("=================================\n\n");
84
85 1 test_entry_does_not_affect_exit();
86 1 test_exit_does_not_affect_entry();
87
88 1 printf("=================================\n");
89 1 printf("All integration tests passed!\n");
90 1 printf("=================================\n");
91 1 return 0;
92 }
93