145 lines
5.4 KiB
C++
145 lines
5.4 KiB
C++
#include <gtest/gtest.h>
|
|
#include <gmock/gmock.h>
|
|
#include <fstream>
|
|
#include <nlohmann/json.hpp>
|
|
#include "detector/TrafficLightDetector.h"
|
|
#include "config/IntersectionConfig.h"
|
|
#include "vehicle/ControllableVehicles.h"
|
|
#include "utils/Logger.h"
|
|
#include "types/VehicleCommand.h"
|
|
#include "types/TrafficLightTypes.h"
|
|
|
|
class MockControllableVehicles : public ControllableVehicles {
|
|
public:
|
|
explicit MockControllableVehicles() : ControllableVehicles("config/vehicle_speed_limits.json") {}
|
|
MOCK_METHOD(bool, isControllable, (const std::string& vehicleNo), (const, override));
|
|
MOCK_METHOD(void, sendCommand, (const std::string& vehicleNo, const VehicleCommand& command), (override));
|
|
};
|
|
|
|
class TrafficLightDetectorTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
// 创建测试用的交叉口配置
|
|
Intersection intersection;
|
|
intersection.id = "INT001";
|
|
intersection.name = "Test Intersection";
|
|
intersection.position.latitude = 36.36;
|
|
intersection.position.longitude = 120.08;
|
|
intersection.radius = 50.0;
|
|
intersection.trafficLightId = "TL001";
|
|
|
|
// 创建临时配置文件
|
|
std::ofstream config_file("test_intersections.json");
|
|
nlohmann::json j;
|
|
j["intersections"] = nlohmann::json::array();
|
|
j["intersections"].push_back({
|
|
{"id", intersection.id},
|
|
{"name", intersection.name},
|
|
{"position", {
|
|
{"latitude", intersection.position.latitude},
|
|
{"longitude", intersection.position.longitude}
|
|
}},
|
|
{"radius", intersection.radius},
|
|
{"trafficLightId", intersection.trafficLightId}
|
|
});
|
|
config_file << j.dump(4);
|
|
config_file.close();
|
|
|
|
intersectionConfig = IntersectionConfig::load("test_intersections.json");
|
|
|
|
mockControllableVehicles = std::make_shared<::testing::NiceMock<MockControllableVehicles>>();
|
|
detector = std::make_unique<TrafficLightDetector>(intersectionConfig, *mockControllableVehicles);
|
|
}
|
|
|
|
void TearDown() override {
|
|
detector.reset();
|
|
std::remove("test_intersections.json");
|
|
}
|
|
|
|
// 创建测试用的红绿灯信号
|
|
TrafficLightSignal createTestSignal(const std::string& id, SignalStatus status) {
|
|
TrafficLightSignal signal;
|
|
signal.trafficLightId = id;
|
|
signal.status = status;
|
|
signal.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
|
|
return signal;
|
|
}
|
|
|
|
// 创建测试用的车辆数据
|
|
Vehicle createTestVehicle(const std::string& id, double lat, double lon) {
|
|
Vehicle v;
|
|
v.id = id;
|
|
v.vehicleNo = id;
|
|
v.geo.latitude = lat;
|
|
v.geo.longitude = lon;
|
|
v.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
|
|
return v;
|
|
}
|
|
|
|
std::unique_ptr<TrafficLightDetector> detector;
|
|
IntersectionConfig intersectionConfig;
|
|
std::shared_ptr<MockControllableVehicles> mockControllableVehicles;
|
|
};
|
|
|
|
// 测试红绿灯信号处理
|
|
TEST_F(TrafficLightDetectorTest, SignalProcessing) {
|
|
// 创建一个在交叉口范围内的车辆
|
|
Vehicle vehicle = createTestVehicle("V001", 36.36, 120.08);
|
|
std::vector<Vehicle> vehicles = {vehicle};
|
|
|
|
// 测试红灯
|
|
TrafficLightSignal redSignal = createTestSignal("TL001", SignalStatus::RED);
|
|
EXPECT_CALL(*mockControllableVehicles, isControllable("V001"))
|
|
.WillOnce(::testing::Return(true));
|
|
EXPECT_CALL(*mockControllableVehicles, sendCommand("V001", ::testing::_))
|
|
.Times(1);
|
|
|
|
detector->processSignal(redSignal, vehicles);
|
|
|
|
// 测试绿灯
|
|
TrafficLightSignal greenSignal = createTestSignal("TL001", SignalStatus::GREEN);
|
|
EXPECT_CALL(*mockControllableVehicles, isControllable("V001"))
|
|
.WillOnce(::testing::Return(true));
|
|
EXPECT_CALL(*mockControllableVehicles, sendCommand("V001", ::testing::_))
|
|
.Times(1);
|
|
|
|
detector->processSignal(greenSignal, vehicles);
|
|
}
|
|
|
|
// 测试无效的红绿灯信号
|
|
TEST_F(TrafficLightDetectorTest, InvalidSignal) {
|
|
Vehicle vehicle = createTestVehicle("V001", 36.36, 120.08);
|
|
std::vector<Vehicle> vehicles = {vehicle};
|
|
|
|
// 测试无效的红绿灯ID
|
|
TrafficLightSignal invalidSignal = createTestSignal("TL999", SignalStatus::RED);
|
|
EXPECT_CALL(*mockControllableVehicles, isControllable(::testing::_))
|
|
.Times(0);
|
|
EXPECT_CALL(*mockControllableVehicles, sendCommand(::testing::_, ::testing::_))
|
|
.Times(0);
|
|
|
|
detector->processSignal(invalidSignal, vehicles);
|
|
}
|
|
|
|
// 测试边界情况
|
|
TEST_F(TrafficLightDetectorTest, EdgeCases) {
|
|
// 测试空车辆列表
|
|
std::vector<Vehicle> emptyVehicles;
|
|
TrafficLightSignal signal = createTestSignal("TL001", SignalStatus::RED);
|
|
EXPECT_CALL(*mockControllableVehicles, isControllable(::testing::_))
|
|
.Times(0);
|
|
EXPECT_CALL(*mockControllableVehicles, sendCommand(::testing::_, ::testing::_))
|
|
.Times(0);
|
|
|
|
detector->processSignal(signal, emptyVehicles);
|
|
|
|
// 测试交叉口范围外的车辆
|
|
Vehicle farVehicle = createTestVehicle("V002", 36.40, 120.12);
|
|
std::vector<Vehicle> vehicles = {farVehicle};
|
|
EXPECT_CALL(*mockControllableVehicles, isControllable(::testing::_))
|
|
.Times(0);
|
|
EXPECT_CALL(*mockControllableVehicles, sendCommand(::testing::_, ::testing::_))
|
|
.Times(0);
|
|
|
|
detector->processSignal(signal, vehicles);
|
|
}
|