diff --git a/src/audio/recording_curves.cpp b/src/audio/recording_curves.cpp index 6a80f37b..021e9230 100644 --- a/src/audio/recording_curves.cpp +++ b/src/audio/recording_curves.cpp @@ -60,6 +60,11 @@ void RecordingCurves::pauseRecording() qInfo() << "pauseRecording finished"; } +bool RecordingCurves::isRecordingActive() const +{ + return m_timer && m_timer->isActive(); +} + void RecordingCurves::updateCurves() { // qInfo() << "updateCurves called"; diff --git a/src/audio/recording_curves.h b/src/audio/recording_curves.h index 34a3e056..804b5571 100644 --- a/src/audio/recording_curves.h +++ b/src/audio/recording_curves.h @@ -17,6 +17,9 @@ class RecordingCurves : public QQuickPaintedItem Q_INVOKABLE void startRecording(); Q_INVOKABLE void stopRecording(); Q_INVOKABLE void pauseRecording(); + + // 查询录音定时器是否处于激活状态(供测试与外部状态查询使用) + bool isRecordingActive() const; public: void paint(QPainter *painter); diff --git a/src/handler/voice_to_text_task_manager.cpp b/src/handler/voice_to_text_task_manager.cpp index a5f06171..75b130a2 100644 --- a/src/handler/voice_to_text_task_manager.cpp +++ b/src/handler/voice_to_text_task_manager.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024-2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -90,3 +90,8 @@ void VoiceToTextTaskManager::removeTask(const QString &voiceId) qDebug() << "Removed task for voiceId:" << voiceId; } } + +void VoiceToTextTaskManager::clearAllTasks() +{ + m_tasks.clear(); +} diff --git a/src/handler/voice_to_text_task_manager.h b/src/handler/voice_to_text_task_manager.h index 9a78c0d5..0648e2b2 100644 --- a/src/handler/voice_to_text_task_manager.h +++ b/src/handler/voice_to_text_task_manager.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024-2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -81,6 +81,11 @@ class VoiceToTextTaskManager : public QObject */ void removeTask(const QString &voiceId); + /** + * @brief 清除所有任务(仅供测试环境重置单例状态) + */ + void clearAllTasks(); + signals: /** * @brief 任务状态变化信号 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 652753b6..310a5a68 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -112,7 +112,6 @@ list(REMOVE_ITEM VNOTE_SRC_TEST1 "${CMAKE_CURRENT_LIST_DIR}/src/common/ut_utils.cpp" "${CMAKE_CURRENT_LIST_DIR}/src/common/ut_vlcplayer.cpp" "${CMAKE_CURRENT_LIST_DIR}/src/common/ut_vntaskworker.cpp" - "${CMAKE_CURRENT_LIST_DIR}/src/task/ut_vnmainwnddelayinittask.cpp" ) list(REMOVE_ITEM VNOTE_SRC_TEST "${CMAKE_CURRENT_LIST_DIR}/../src/main.cpp") diff --git a/tests/src/audio/ut_recording_curves.cpp b/tests/src/audio/ut_recording_curves.cpp new file mode 100644 index 00000000..d17ead57 --- /dev/null +++ b/tests/src/audio/ut_recording_curves.cpp @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_recording_curves.h" +#include "recording_curves.h" + +#include + +UT_RecordingCurves::UT_RecordingCurves() +{ +} + +TEST_F(UT_RecordingCurves, Constructor_CreatesValidInstance) +{ + RecordingCurves curves; + EXPECT_FALSE(curves.isRecordingActive()); +} + +TEST_F(UT_RecordingCurves, UpdateVolume_DoesNotCrash) +{ + RecordingCurves curves; + curves.updateVolume(0.5); + curves.updateVolume(0.0); + curves.updateVolume(1.0); + SUCCEED(); +} + +TEST_F(UT_RecordingCurves, StartRecording_TimerBecomesActive) +{ + RecordingCurves curves; + EXPECT_FALSE(curves.isRecordingActive()); + + curves.startRecording(); + EXPECT_TRUE(curves.isRecordingActive()); +} + +TEST_F(UT_RecordingCurves, StopRecording_AfterStart_TimerStops) +{ + RecordingCurves curves; + curves.startRecording(); + ASSERT_TRUE(curves.isRecordingActive()); + + curves.stopRecording(); + EXPECT_FALSE(curves.isRecordingActive()); +} + +TEST_F(UT_RecordingCurves, StopRecording_WithoutStart_DoesNotCrash) +{ + RecordingCurves curves; + EXPECT_FALSE(curves.isRecordingActive()); + + curves.stopRecording(); + EXPECT_FALSE(curves.isRecordingActive()); +} + +TEST_F(UT_RecordingCurves, PauseRecording_TogglesTimer) +{ + RecordingCurves curves; + curves.startRecording(); + ASSERT_TRUE(curves.isRecordingActive()); + + // pauseRecording should stop the timer + curves.pauseRecording(); + EXPECT_FALSE(curves.isRecordingActive()); + + // Second call should restart the timer + curves.pauseRecording(); + EXPECT_TRUE(curves.isRecordingActive()); +} + +// 注:pauseRecording 在未 startRecording 时调用会启动定时器, +// 这是 RecordingCurves 源码的已知行为(pauseRecording 内部用 +// m_timer->isActive() 做切换),此处不作为预期断言,避免将 +// 源码行为固化为"正确"。 + +TEST_F(UT_RecordingCurves, Paint_WithValidSize_DoesNotCrash) +{ + RecordingCurves curves; + curves.setSize(QSizeF(100, 50)); + curves.updateVolume(0.5); + + QImage image(100, 50, QImage::Format_ARGB32); + image.fill(Qt::white); + QPainter painter(&image); + curves.paint(&painter); + SUCCEED(); +} + +TEST_F(UT_RecordingCurves, Paint_WithZeroGain_DoesNotCrash) +{ + RecordingCurves curves; + curves.setSize(QSizeF(100, 50)); + + QImage image(100, 50, QImage::Format_ARGB32); + image.fill(Qt::white); + QPainter painter(&image); + curves.paint(&painter); + SUCCEED(); +} diff --git a/tests/src/audio/ut_recording_curves.h b/tests/src/audio/ut_recording_curves.h new file mode 100644 index 00000000..de50669d --- /dev/null +++ b/tests/src/audio/ut_recording_curves.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_RECORDING_CURVES_H +#define UT_RECORDING_CURVES_H + +#include "gtest/gtest.h" +#include +#include + +class UT_RecordingCurves : public QObject + , public ::testing::Test +{ + Q_OBJECT +public: + UT_RecordingCurves(); +}; + +#endif // UT_RECORDING_CURVES_H diff --git a/tests/src/handler/ut_voice_to_text_task_manager.cpp b/tests/src/handler/ut_voice_to_text_task_manager.cpp new file mode 100644 index 00000000..7c94f37e --- /dev/null +++ b/tests/src/handler/ut_voice_to_text_task_manager.cpp @@ -0,0 +1,169 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_voice_to_text_task_manager.h" +#include "voice_to_text_task_manager.h" + +#include + +UT_VoiceToTextTaskManager::UT_VoiceToTextTaskManager() +{ +} + +void UT_VoiceToTextTaskManager::SetUp() +{ +} + +void UT_VoiceToTextTaskManager::TearDown() +{ + // 使用 clearAllTasks 统一重置单例状态,确保用例间完全隔离 + VoiceToTextTaskManager::instance()->clearAllTasks(); +} + +// --------------------------------------------------------------------------- +// addTask / getTask +// --------------------------------------------------------------------------- + +TEST_F(UT_VoiceToTextTaskManager, AddTask_ValidVoiceId_AddsTask) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + QSignalSpy spy(mgr, &VoiceToTextTaskManager::taskStatusChanged); + + mgr->addTask(1, QStringLiteral("voice-add-001")); + VoiceToTextTask *task = mgr->getTask(QStringLiteral("voice-add-001")); + + ASSERT_NE(nullptr, task); + EXPECT_EQ(1, task->noteId); + EXPECT_EQ(VoiceToTextTask::Converting, task->status); + EXPECT_EQ(QStringLiteral("voice-add-001"), task->voiceId); + + EXPECT_EQ(1, spy.count()); +} + +TEST_F(UT_VoiceToTextTaskManager, AddTask_EmptyVoiceId_DoesNotAdd) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + QSignalSpy spy(mgr, &VoiceToTextTaskManager::taskStatusChanged); + + mgr->addTask(2, QString()); + EXPECT_EQ(nullptr, mgr->getTask(QString())); + EXPECT_EQ(0, spy.count()); +} + +TEST_F(UT_VoiceToTextTaskManager, GetTask_NotExist_ReturnsNull) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + EXPECT_EQ(nullptr, mgr->getTask(QStringLiteral("nonexistent-uuid-999"))); +} + +// --------------------------------------------------------------------------- +// setTaskResult +// --------------------------------------------------------------------------- + +TEST_F(UT_VoiceToTextTaskManager, SetTaskResult_Success_UpdatesStatus) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + mgr->addTask(3, QStringLiteral("voice-result-001")); + + QSignalSpy statusSpy(mgr, &VoiceToTextTaskManager::taskStatusChanged); + QSignalSpy completedSpy(mgr, &VoiceToTextTaskManager::taskCompleted); + + mgr->setTaskResult(QStringLiteral("voice-result-001"), QStringLiteral("转写结果"), true); + + VoiceToTextTask *task = mgr->getTask(QStringLiteral("voice-result-001")); + ASSERT_NE(nullptr, task); + EXPECT_EQ(VoiceToTextTask::Completed, task->status); + EXPECT_EQ(QStringLiteral("转写结果"), task->resultText); + + EXPECT_EQ(1, statusSpy.count()); + EXPECT_EQ(1, completedSpy.count()); + + QList args = completedSpy.takeFirst(); + EXPECT_EQ(3, args.at(0).toInt()); + EXPECT_EQ(QStringLiteral("voice-result-001"), args.at(1).toString()); + EXPECT_EQ(QStringLiteral("转写结果"), args.at(2).toString()); + EXPECT_TRUE(args.at(3).toBool()); +} + +TEST_F(UT_VoiceToTextTaskManager, SetTaskResult_Failure_UpdatesStatus) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + mgr->addTask(4, QStringLiteral("voice-result-002")); + + QSignalSpy statusSpy(mgr, &VoiceToTextTaskManager::taskStatusChanged); + QSignalSpy completedSpy(mgr, &VoiceToTextTaskManager::taskCompleted); + + mgr->setTaskResult(QStringLiteral("voice-result-002"), QString(), false); + + VoiceToTextTask *task = mgr->getTask(QStringLiteral("voice-result-002")); + ASSERT_NE(nullptr, task); + EXPECT_EQ(VoiceToTextTask::Failed, task->status); + EXPECT_EQ(1, statusSpy.count()); + EXPECT_EQ(1, completedSpy.count()); +} + +TEST_F(UT_VoiceToTextTaskManager, SetTaskResult_NotExist_NoSignal) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + QSignalSpy statusSpy(mgr, &VoiceToTextTaskManager::taskStatusChanged); + QSignalSpy completedSpy(mgr, &VoiceToTextTaskManager::taskCompleted); + + mgr->setTaskResult(QStringLiteral("nonexistent-uuid-998"), QString(), false); + + EXPECT_EQ(0, statusSpy.count()); + EXPECT_EQ(0, completedSpy.count()); +} + +// --------------------------------------------------------------------------- +// getTasksForNote / hasActiveTask +// --------------------------------------------------------------------------- + +TEST_F(UT_VoiceToTextTaskManager, GetTasksForNote_ReturnsMatchingTasks) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + mgr->addTask(10, QStringLiteral("voice-note-a")); + mgr->addTask(10, QStringLiteral("voice-note-b")); + mgr->addTask(20, QStringLiteral("voice-note-c")); + + QList tasks = mgr->getTasksForNote(10); + EXPECT_EQ(2, tasks.size()); +} + +TEST_F(UT_VoiceToTextTaskManager, HasActiveTask_WithConvertingTask_ReturnsTrue) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + mgr->addTask(11, QStringLiteral("voice-active-001")); + EXPECT_TRUE(mgr->hasActiveTask()); +} + +TEST_F(UT_VoiceToTextTaskManager, HasActiveTask_WithNoConvertingTask_ReturnsFalse) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + mgr->addTask(12, QStringLiteral("voice-active-002")); + ASSERT_TRUE(mgr->hasActiveTask()); + + mgr->setTaskResult(QStringLiteral("voice-active-002"), QStringLiteral("done"), true); + EXPECT_FALSE(mgr->hasActiveTask()); +} + +// --------------------------------------------------------------------------- +// removeTask +// --------------------------------------------------------------------------- + +TEST_F(UT_VoiceToTextTaskManager, RemoveTask_Existing_RemovesIt) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + mgr->addTask(13, QStringLiteral("voice-remove-001")); + ASSERT_NE(nullptr, mgr->getTask(QStringLiteral("voice-remove-001"))); + + mgr->removeTask(QStringLiteral("voice-remove-001")); + EXPECT_EQ(nullptr, mgr->getTask(QStringLiteral("voice-remove-001"))); +} + +TEST_F(UT_VoiceToTextTaskManager, RemoveTask_NonExistent_NoCrash) +{ + VoiceToTextTaskManager *mgr = VoiceToTextTaskManager::instance(); + mgr->removeTask(QStringLiteral("nonexistent-uuid-997")); + SUCCEED(); +} diff --git a/tests/src/handler/ut_voice_to_text_task_manager.h b/tests/src/handler/ut_voice_to_text_task_manager.h new file mode 100644 index 00000000..bb0f8345 --- /dev/null +++ b/tests/src/handler/ut_voice_to_text_task_manager.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_VOICETOTEXTTASKMANAGER_H +#define UT_VOICETOTEXTTASKMANAGER_H + +#include "gtest/gtest.h" +#include +#include + +class UT_VoiceToTextTaskManager : public QObject + , public ::testing::Test +{ + Q_OBJECT +public: + UT_VoiceToTextTaskManager(); + +protected: + virtual void SetUp() override; + virtual void TearDown() override; +}; + +#endif // UT_VOICETOTEXTTASKMANAGER_H diff --git a/tests/src/task/ut_vnmainwnddelayinittask.cpp b/tests/src/task/ut_vnmainwnddelayinittask.cpp index b93ea559..aa2f18a6 100644 --- a/tests/src/task/ut_vnmainwnddelayinittask.cpp +++ b/tests/src/task/ut_vnmainwnddelayinittask.cpp @@ -1,20 +1,23 @@ -// Copyright (C) 2019 ~ 2019 UnionTech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023-2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later #include "ut_vnmainwnddelayinittask.h" #include "vnmainwnddelayinittask.h" -#include "views/vnotemainwindow.h" UT_VNMainWndDelayInitTask::UT_VNMainWndDelayInitTask() { } -TEST_F(UT_VNMainWndDelayInitTask, UT_VNMainWndDelayInitTask_run_001) +TEST_F(UT_VNMainWndDelayInitTask, Run_WithNullMainWnd_DoesNotCrash) { - VNMainWndDelayInitTask *work = new VNMainWndDelayInitTask(nullptr); - work->run(); + VNMainWndDelayInitTask task(nullptr); + task.run(); + SUCCEED(); +} - delete work; +TEST_F(UT_VNMainWndDelayInitTask, Constructor_DoesNotCrash) +{ + VNMainWndDelayInitTask task(nullptr); + SUCCEED(); } diff --git a/tests/src/task/ut_vnmainwnddelayinittask.h b/tests/src/task/ut_vnmainwnddelayinittask.h index d299f62f..18afbf7a 100644 --- a/tests/src/task/ut_vnmainwnddelayinittask.h +++ b/tests/src/task/ut_vnmainwnddelayinittask.h @@ -1,5 +1,4 @@ -// Copyright (C) 2019 ~ 2019 UnionTech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023-2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -8,6 +7,7 @@ #include #include "gtest/gtest.h" + class UT_VNMainWndDelayInitTask : public ::testing::Test { public: