001/tests/basic_test.cpp

215 lines
8.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "../include/employee.hpp"
#include "../include/schedule.hpp"
#include "../include/checkin.hpp"
#include "../include/attendance.hpp"
#include "../include/alert.hpp"
#include <cassert>
#include <iostream>
using namespace AttendanceSystem;
void test_employee() {
std::cout << "测试 Employee 类..." << std::endl;
// 测试默认构造函数
Employee emp1;
assert(!emp1.isValid()); // 默认构造的对象应该无效
// 测试带参构造函数
Employee emp2("EMP001", "张三", "DEPT001", "软件工程师", "13800138001", "zhangsan@example.com");
assert(emp2.isValid());
assert(emp2.getId() == "EMP001");
assert(emp2.getName() == "张三");
assert(emp2.getDepartmentId() == "DEPT001");
assert(emp2.getPosition() == "软件工程师");
assert(emp2.getMobile() == "13800138001");
assert(emp2.getEmail() == "zhangsan@example.com");
// 测试无效数据
Employee emp3("", "李四", "DEPT001", "", "", "");
assert(!emp3.isValid());
std::cout << "Employee 测试通过!" << std::endl;
}
void test_schedule_rule() {
std::cout << "测试 ScheduleRule 类..." << std::endl;
// 测试白班规则
ScheduleRule rule1("RULE001", "白班", 9, 0, 18, 0, 60, 30);
assert(rule1.isValid());
assert(rule1.getRuleId() == "RULE001");
assert(rule1.getShiftName() == "白班");
assert(rule1.getStartHour() == 9);
assert(rule1.getStartMinute() == 0);
assert(rule1.getEndHour() == 18);
assert(rule1.getEndMinute() == 0);
assert(rule1.getBreakDuration() == 60);
assert(rule1.getOvertimeThreshold() == 30);
// 测试工作时间计算
int workDuration = rule1.calculateWorkDuration();
assert(workDuration == 8 * 60); // 9:00-18:00减去60分钟休息应该是8小时
// 测试加班判断
assert(!rule1.isOvertime(17, 30)); // 17:30下班不算加班
assert(rule1.isOvertime(18, 45)); // 18:45下班超过阈值30分钟算加班
// 测试版本控制
ScheduleRule rule2 = rule1.createNewVersion();
assert(rule2.getVersion() == 2); // 新版本号应该是2
// 测试无效规则
ScheduleRule rule3("", "", 25, 70, -1, 70, -10, -20); // 无效时间
assert(!rule3.isValid());
std::cout << "ScheduleRule 测试通过!" << std::endl;
}
void test_checkin_record() {
std::cout << "测试 CheckInRecord 类..." << std::endl;
// 创建时间戳
std::time_t now = std::time(nullptr);
std::tm* tm_now = std::localtime(&now);
tm_now->tm_hour = 9;
tm_now->tm_min = 15;
tm_now->tm_sec = 0;
std::time_t checkInTime = std::mktime(tm_now);
// 测试GPS打卡
Location location(39.9042, 116.4074);
CheckInRecord record1("REC001", "EMP001", CheckInMethod::GPS_LOCATION, checkInTime, location);
assert(record1.isValid());
assert(record1.getRecordId() == "REC001");
assert(record1.getEmployeeId() == "EMP001");
assert(record1.getMethod() == CheckInMethod::GPS_LOCATION);
assert(record1.getTimestamp() == checkInTime);
assert(record1.getLocation().latitude == 39.9042);
assert(record1.getLocation().longitude == 116.4074);
// 测试人脸识别打卡
CheckInRecord record2("REC002", "EMP002", CheckInMethod::FACE_RECOGNITION, checkInTime, Location());
assert(record2.isValid());
assert(record2.getMethodString() == "人脸识别");
// 测试是否迟到/早退
assert(!record1.isLate(9, 0)); // 9:15打卡期望9:00不算迟到
assert(!record1.isLate(8, 30)); // 9:15打卡期望8:30不算迟到
// 创建一个早一点的打卡记录
tm_now->tm_hour = 8;
tm_now->tm_min = 30;
std::time_t earlyTime = std::mktime(tm_now);
CheckInRecord record3("REC003", "EMP003", CheckInMethod::CARD_SWIPE, earlyTime, Location());
assert(!record3.isEarlyLeave(17, 30)); // 8:30打卡期望17:30下班不算早退
std::cout << "CheckInRecord 测试通过!" << std::endl;
}
void test_attendance_result() {
std::cout << "测试 AttendanceResult 类..." << std::endl;
// 创建时间戳
std::time_t now = std::time(nullptr);
// 测试正常考勤
AttendanceResult result1("RES001", "EMP001", now, AttendanceStatus::NORMAL, 480, "正常上班");
assert(result1.isValid());
assert(result1.getResultId() == "RES001");
assert(result1.getEmployeeId() == "EMP001");
assert(result1.getStatus() == AttendanceStatus::NORMAL);
assert(result1.getDuration() == 480); // 8小时
assert(result1.getRemarks() == "正常上班");
assert(!result1.shouldDeductSalary()); // 正常不应该扣款
assert(!result1.shouldPayOvertime()); // 正常不是加班
// 测试迟到考勤
AttendanceResult result2("RES002", "EMP002", now, AttendanceStatus::LATE, 15, "迟到15分钟");
assert(result2.getStatusString() == "迟到");
assert(result2.shouldDeductSalary()); // 迟到应该扣款
// 测试加班考勤
AttendanceResult result3("RES003", "EMP003", now, AttendanceStatus::OVERTIME, 60, "加班1小时");
assert(result3.shouldPayOvertime()); // 加班应该支付加班费
// 测试无效数据
AttendanceResult result4("", "", 0, AttendanceStatus::NORMAL, -10, "");
assert(!result4.isValid());
std::cout << "AttendanceResult 测试通过!" << std::endl;
}
void test_alert_event() {
std::cout << "测试 AlertEvent 类..." << std::endl;
std::time_t now = std::time(nullptr);
// 测试未打卡异常
AlertEvent alert1("ALERT001", "EMP001", AlertType::NO_CHECK_IN, now, "员工今日未打卡");
assert(alert1.isValid());
assert(alert1.getEventId() == "ALERT001");
assert(alert1.getEmployeeId() == "EMP001");
assert(alert1.getAlertType() == AlertType::NO_CHECK_IN);
assert(alert1.getReason() == "员工今日未打卡");
assert(!alert1.isHandled());
// 测试通知渠道
alert1.addNotificationChannel(NotificationChannel::IN_APP_MESSAGE);
alert1.addNotificationChannel(NotificationChannel::SMS);
assert(alert1.isNotifiedByChannel(NotificationChannel::IN_APP_MESSAGE));
assert(alert1.isNotifiedByChannel(NotificationChannel::SMS));
assert(!alert1.isNotifiedByChannel(NotificationChannel::EMAIL));
// 测试移除通知渠道
alert1.removeNotificationChannel(NotificationChannel::SMS);
assert(!alert1.isNotifiedByChannel(NotificationChannel::SMS));
// 测试异常处理
alert1.handle("ADMIN001", "已电话联系确认");
assert(alert1.isHandled());
assert(alert1.getHandlerId() == "ADMIN001");
assert(alert1.getHandleRemarks() == "已电话联系确认");
// 测试严重性判断
AlertEvent alert2("ALERT002", "EMP002", AlertType::CONTINUOUS_ABSENCE, now, "连续缺勤3天");
assert(alert2.isCritical()); // 连续缺勤是严重异常
AlertEvent alert3("ALERT003", "EMP003", AlertType::CHECK_IN_TIME_DEVIATION, now, "打卡时间偏离");
assert(alert3.needsImmediateAttention()); // 需要立即处理
std::cout << "AlertEvent 测试通过!" << std::endl;
}
int main() {
std::cout << "开始运行智能考勤管理系统测试..." << std::endl;
std::cout << "========================================\n" << std::endl;
try {
test_employee();
std::cout << std::endl;
test_schedule_rule();
std::cout << std::endl;
test_checkin_record();
std::cout << std::endl;
test_attendance_result();
std::cout << std::endl;
test_alert_event();
std::cout << std::endl;
std::cout << "========================================\n" << std::endl;
std::cout << "所有测试通过!" << std::endl;
return 0;
} catch (const std::exception& e) {
std::cerr << "测试异常:" << e.what() << std::endl;
return 1;
} catch (...) {
std::cerr << "未知测试异常!" << std::endl;
return 1;
}
}