添加测试

This commit is contained in:
2026-01-05 02:55:21 +08:00
parent 9d0790370f
commit 1f679551f2
20 changed files with 784 additions and 0 deletions
+12
View File
@@ -69,6 +69,18 @@ function(olive_add_test GROUP NAME SOURCE)
endif()
endfunction()
include(FetchContent)
find_package(GTest QUIET)
if (NOT GTest_FOUND)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/v1.15.2.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
endif()
add_subdirectory(compositing)
add_subdirectory(general)
add_subdirectory(timeline)
add_subdirectory(gtest)
+53
View File
@@ -0,0 +1,53 @@
add_executable(olive-gtest
main.cpp
common_current_test.cpp
common_xmlutils_test.cpp
config_test.cpp
node_value_test.cpp
node_keyframe_test.cpp
node_serialization_test.cpp
render_videoparams_test.cpp
render_audioparams_test.cpp
project_serializer_test.cpp
timeline_marker_test.cpp
undo_stack_test.cpp
plugin_support_test.cpp
codec_frame_test.cpp
task_taskmanager_test.cpp
module_smoke_test.cpp
)
target_sources(olive-gtest PRIVATE $<TARGET_OBJECTS:libolive-editor>)
target_include_directories(
olive-gtest
PRIVATE
${CMAKE_SOURCE_DIR}/app
${CMAKE_SOURCE_DIR}/tests
${OLIVE_INCLUDE_DIRS}
)
target_link_libraries(
olive-gtest
PRIVATE
${OLIVE_LIBRARIES}
GTest::gtest
)
target_compile_definitions(
olive-gtest
PRIVATE
${OLIVE_DEFINITIONS}
)
target_compile_options(
olive-gtest
PRIVATE
${OLIVE_COMPILE_OPTIONS}
)
if (MSVC)
add_test("Olive.gtest" olive-gtest)
else()
add_test(olive-gtest olive-gtest)
endif()
+11
View File
@@ -0,0 +1,11 @@
#include <gtest/gtest.h>
#include "codec/frame.h"
TEST(CodecFrame, DefaultState)
{
olive::Frame frame;
EXPECT_EQ(frame.width(), 0);
EXPECT_EQ(frame.height(), 0);
EXPECT_EQ(frame.pixel_format(), olive::core::PixelFormat::Format::kFormatNone);
}
+27
View File
@@ -0,0 +1,27 @@
#include <gtest/gtest.h>
#include "common/Current.h"
#include "render/videoparams.h"
#include "render/audioparams.h"
TEST(CommonCurrent, SetAndGetVideoParams)
{
olive::VideoParams params;
params.set_width(1920);
params.set_height(1080);
Current::getInstance().setCurrentVideoParams(params);
const olive::VideoParams &stored = Current::getInstance().currentVideoParams();
EXPECT_EQ(stored.width(), 1920);
EXPECT_EQ(stored.height(), 1080);
}
TEST(CommonCurrent, SetAndGetAudioParams)
{
olive::AudioParams params;
params.set_sample_rate(48000);
Current::getInstance().setCurrentAudioParams(params);
const olive::AudioParams &stored = Current::getInstance().currentAudioParams();
EXPECT_EQ(stored.sample_rate(), 48000);
}
+20
View File
@@ -0,0 +1,20 @@
#include <gtest/gtest.h>
#include <QBuffer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "common/xmlutils.h"
TEST(CommonXmlUtils, ReadNextStartElement)
{
QByteArray xml = "<root><child>value</child></root>";
QBuffer buffer(&xml);
buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&buffer);
EXPECT_TRUE(XMLReadNextStartElement(&reader));
EXPECT_EQ(reader.name().toString(), QStringLiteral("root"));
EXPECT_TRUE(XMLReadNextStartElement(&reader));
EXPECT_EQ(reader.name().toString(), QStringLiteral("child"));
}
+20
View File
@@ -0,0 +1,20 @@
#include <gtest/gtest.h>
#include "config/config.h"
TEST(Config, DefaultsPresent)
{
olive::Config &cfg = olive::Config::Current();
cfg.SetDefaults();
EXPECT_TRUE(cfg[QStringLiteral("Style")].isValid());
EXPECT_TRUE(cfg[QStringLiteral("TimecodeDisplay")].isValid());
EXPECT_TRUE(cfg[QStringLiteral("DefaultStillLength")].isValid());
}
TEST(Config, SetAndGetValues)
{
olive::Config &cfg = olive::Config::Current();
cfg[QStringLiteral("UnitTestValue")] = 42;
EXPECT_EQ(cfg[QStringLiteral("UnitTestValue")].toInt(), 42);
}
+9
View File
@@ -0,0 +1,9 @@
#include <QCoreApplication>
#include <gtest/gtest.h>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+15
View File
@@ -0,0 +1,15 @@
#include <gtest/gtest.h>
#include "audio/audiomanager.h"
#include "cli/cliexport/cliexportmanager.h"
#include "dialog/progress/progress.h"
#include "panel/panelmanager.h"
#include "tool/tool.h"
#include "ui/humanstrings.h"
#include "widget/nodeview/nodeview.h"
#include "window/mainwindow/mainwindow.h"
TEST(ModuleSmoke, HeadersBuild)
{
SUCCEED();
}
+47
View File
@@ -0,0 +1,47 @@
#include <gtest/gtest.h>
#include <QBuffer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "node/keyframe.h"
#include "node/value.h"
TEST(NodeKeyframe, SaveLoadRoundTrip)
{
olive::NodeKeyframe key;
key.set_input(QStringLiteral("Value"));
key.set_time(olive::core::rational(1, 24));
key.set_type(olive::NodeKeyframe::kLinear);
key.set_value(42.0);
key.set_bezier_control_in(QPointF(0.1, 0.2));
key.set_bezier_control_out(QPointF(0.3, 0.4));
QByteArray xml;
QBuffer buffer(&xml);
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
writer.writeStartElement(QStringLiteral("key"));
key.save(&writer, olive::NodeValue::kFloat);
writer.writeEndElement();
writer.writeEndDocument();
buffer.close();
QBuffer read_buffer(&xml);
read_buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&read_buffer);
EXPECT_TRUE(reader.readNextStartElement());
EXPECT_EQ(reader.name().toString(), QStringLiteral("key"));
olive::NodeKeyframe loaded;
EXPECT_TRUE(loaded.load(&reader, olive::NodeValue::kFloat));
EXPECT_EQ(loaded.input(), QStringLiteral("Value"));
EXPECT_EQ(loaded.time(), olive::core::rational(1, 24));
EXPECT_EQ(loaded.type(), olive::NodeKeyframe::kLinear);
EXPECT_DOUBLE_EQ(loaded.value().toDouble(), 42.0);
EXPECT_DOUBLE_EQ(loaded.bezier_control_in().x(), 0.1);
EXPECT_DOUBLE_EQ(loaded.bezier_control_in().y(), 0.2);
EXPECT_DOUBLE_EQ(loaded.bezier_control_out().x(), 0.3);
EXPECT_DOUBLE_EQ(loaded.bezier_control_out().y(), 0.4);
}
+81
View File
@@ -0,0 +1,81 @@
#include <gtest/gtest.h>
#include <QBuffer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "node/node.h"
#include "node/serializeddata.h"
#include "node/value.h"
namespace {
class TestNode final : public olive::Node {
public:
TestNode()
{
AddInput(QStringLiteral("Value"), olive::NodeValue::kFloat);
SetSplitStandardValue(QStringLiteral("Value"), 3.5, -1);
}
TestNode *copy() const override
{
return new TestNode();
}
QString Name() const override
{
return QStringLiteral("TestNode");
}
QString id() const override
{
return QStringLiteral("org.olivevideoeditor.TestNode");
}
QVector<CategoryID> Category() const override
{
return { kCategoryUnknown };
}
QString Description() const override
{
return QStringLiteral("Test node for serialization");
}
void Value(const NodeValueRow &, const NodeGlobals &, NodeValueTable *) const override
{
}
};
}
TEST(NodeSerialization, SaveAndLoadInput)
{
TestNode node;
node.SetLabel(QStringLiteral("MyNode"));
node.SetOverrideColor(2);
QByteArray xml;
QBuffer buffer(&xml);
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
writer.writeStartElement(QStringLiteral("node"));
node.Save(&writer);
writer.writeEndElement();
writer.writeEndDocument();
buffer.close();
TestNode loaded;
olive::SerializedData data;
QBuffer read_buffer(&xml);
read_buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&read_buffer);
EXPECT_TRUE(reader.readNextStartElement());
EXPECT_EQ(reader.name().toString(), QStringLiteral("node"));
EXPECT_TRUE(loaded.Load(&reader, &data));
EXPECT_EQ(loaded.GetLabel(), QStringLiteral("MyNode"));
EXPECT_EQ(loaded.GetOverrideColor(), 2);
EXPECT_DOUBLE_EQ(loaded.GetSplitStandardValue(QStringLiteral("Value"), -1)
.first().toDouble(), 3.5);
}
+50
View File
@@ -0,0 +1,50 @@
#include <gtest/gtest.h>
#include <QVector2D>
#include <QVector3D>
#include <QVector4D>
#include "node/value.h"
TEST(NodeValue, VectorRoundTrip)
{
QVector2D v2(1.5f, -2.0f);
QString encoded = olive::NodeValue::ValueToString(
olive::NodeValue::kVec2, QVariant::fromValue(v2), false);
QVariant decoded = olive::NodeValue::StringToValue(
olive::NodeValue::kVec2, encoded, false);
QVector2D v2_out = decoded.value<QVector2D>();
EXPECT_FLOAT_EQ(v2_out.x(), v2.x());
EXPECT_FLOAT_EQ(v2_out.y(), v2.y());
QVector3D v3(1.0f, 2.0f, 3.0f);
encoded = olive::NodeValue::ValueToString(
olive::NodeValue::kVec3, QVariant::fromValue(v3), false);
decoded = olive::NodeValue::StringToValue(
olive::NodeValue::kVec3, encoded, false);
QVector3D v3_out = decoded.value<QVector3D>();
EXPECT_FLOAT_EQ(v3_out.x(), v3.x());
EXPECT_FLOAT_EQ(v3_out.y(), v3.y());
EXPECT_FLOAT_EQ(v3_out.z(), v3.z());
QVector4D v4(1.0f, 2.0f, 3.0f, 4.0f);
encoded = olive::NodeValue::ValueToString(
olive::NodeValue::kVec4, QVariant::fromValue(v4), false);
decoded = olive::NodeValue::StringToValue(
olive::NodeValue::kVec4, encoded, false);
QVector4D v4_out = decoded.value<QVector4D>();
EXPECT_FLOAT_EQ(v4_out.x(), v4.x());
EXPECT_FLOAT_EQ(v4_out.y(), v4.y());
EXPECT_FLOAT_EQ(v4_out.z(), v4.z());
EXPECT_FLOAT_EQ(v4_out.w(), v4.w());
}
TEST(NodeValue, BinaryRoundTrip)
{
QByteArray data("OliveTest");
QString encoded = olive::NodeValue::ValueToString(
olive::NodeValue::kBinary, data, false);
QVariant decoded = olive::NodeValue::StringToValue(
olive::NodeValue::kBinary, encoded, false);
EXPECT_EQ(decoded.toByteArray(), data);
}
+10
View File
@@ -0,0 +1,10 @@
#include <gtest/gtest.h>
#include "pluginSupport/OliveHost.h"
TEST(PluginSupport, LoadPluginsEmptyPath)
{
EXPECT_NO_THROW({
olive::plugin::loadPlugins(QString());
});
}
+43
View File
@@ -0,0 +1,43 @@
#include <gtest/gtest.h>
#include <QBuffer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "node/factory.h"
#include "node/project.h"
#include "node/input/time/timeinput.h"
#include "node/project/serializer/serializer.h"
TEST(ProjectSerializer, SaveLoadProjectRoundTrip)
{
olive::NodeFactory::Initialize();
olive::Project project;
project.Initialize();
auto *node = new olive::TimeInput();
node->SetLabel(QStringLiteral("TimeInput"));
node->setParent(&project);
olive::ProjectSerializer::SaveData save_data(
olive::ProjectSerializer::kProject, &project, QString());
QByteArray xml;
QBuffer buffer(&xml);
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&buffer);
EXPECT_EQ(olive::ProjectSerializer::Save(&writer, save_data),
olive::ProjectSerializer::kSuccess);
buffer.close();
olive::Project loaded_project;
QBuffer read_buffer(&xml);
read_buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&read_buffer);
olive::ProjectSerializer::Result result =
olive::ProjectSerializer::Load(&loaded_project, &reader,
olive::ProjectSerializer::kProject);
EXPECT_EQ(result.code(), olive::ProjectSerializer::kSuccess);
EXPECT_FALSE(loaded_project.nodes().isEmpty());
}
+38
View File
@@ -0,0 +1,38 @@
#include <gtest/gtest.h>
#include <QBuffer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "node/project/serializer/typeserializer.h"
#include "render/audioparams.h"
TEST(RenderAudioParams, SaveLoadRoundTrip)
{
olive::AudioParams params;
params.set_sample_rate(48000);
params.set_enabled(true);
params.set_time_base(olive::core::rational(1, 48000));
QByteArray xml;
QBuffer buffer(&xml);
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
writer.writeStartElement(QStringLiteral("audioparams"));
olive::TypeSerializer::SaveAudioParams(&writer, params);
writer.writeEndElement();
writer.writeEndDocument();
buffer.close();
QBuffer read_buffer(&xml);
read_buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&read_buffer);
EXPECT_TRUE(reader.readNextStartElement());
EXPECT_EQ(reader.name().toString(), QStringLiteral("audioparams"));
olive::AudioParams loaded = olive::TypeSerializer::LoadAudioParams(&reader);
EXPECT_EQ(loaded.sample_rate(), 48000);
EXPECT_TRUE(loaded.enabled());
EXPECT_EQ(loaded.time_base(), olive::core::rational(1, 48000));
}
+42
View File
@@ -0,0 +1,42 @@
#include <gtest/gtest.h>
#include <QBuffer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "render/videoparams.h"
TEST(RenderVideoParams, SaveLoadRoundTrip)
{
olive::VideoParams params;
params.set_width(1280);
params.set_height(720);
params.set_frame_rate(olive::core::rational(24, 1));
params.set_pixel_aspect_ratio(olive::core::rational(1, 1));
params.set_colorspace(QStringLiteral("test"));
QByteArray xml;
QBuffer buffer(&xml);
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
writer.writeStartElement(QStringLiteral("videoparams"));
params.Save(&writer);
writer.writeEndElement();
writer.writeEndDocument();
buffer.close();
olive::VideoParams loaded;
QBuffer read_buffer(&xml);
read_buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&read_buffer);
EXPECT_TRUE(reader.readNextStartElement());
EXPECT_EQ(reader.name().toString(), QStringLiteral("videoparams"));
loaded.Load(&reader);
EXPECT_EQ(loaded.width(), 1280);
EXPECT_EQ(loaded.height(), 720);
EXPECT_EQ(loaded.frame_rate(), olive::core::rational(24, 1));
EXPECT_EQ(loaded.pixel_aspect_ratio(), olive::core::rational(1, 1));
EXPECT_EQ(loaded.colorspace(), QStringLiteral("test"));
}
+52
View File
@@ -0,0 +1,52 @@
#include <gtest/gtest.h>
#include <QEventLoop>
#include <QTimer>
#include "task/taskmanager.h"
namespace {
class DummyTask final : public olive::Task {
public:
explicit DummyTask(bool *ran)
: ran_(ran)
{
SetTitle(QStringLiteral("DummyTask"));
}
protected:
bool Run() override
{
if (ran_) {
*ran_ = true;
}
return true;
}
private:
bool *ran_ = nullptr;
};
}
TEST(TaskManager, AddAndRunTask)
{
olive::TaskManager::CreateInstance();
olive::TaskManager *mgr = olive::TaskManager::instance();
ASSERT_NE(mgr, nullptr);
bool ran = false;
DummyTask *task = new DummyTask(&ran);
QEventLoop loop;
QObject::connect(task, &olive::Task::Finished, &loop, [&loop](olive::Task *, bool) {
loop.quit();
});
mgr->AddTask(task);
QTimer::singleShot(5000, &loop, &QEventLoop::quit);
loop.exec();
EXPECT_TRUE(ran);
olive::TaskManager::DestroyInstance();
}
+38
View File
@@ -0,0 +1,38 @@
#include <gtest/gtest.h>
#include <QBuffer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "timeline/timelinemarker.h"
TEST(TimelineMarker, SaveLoadRoundTrip)
{
olive::TimelineMarker marker;
marker.set_time(olive::core::rational(10, 1));
marker.set_name(QStringLiteral("Marker"));
marker.set_color(5);
QByteArray xml;
QBuffer buffer(&xml);
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
writer.writeStartElement(QStringLiteral("marker"));
marker.save(&writer);
writer.writeEndElement();
writer.writeEndDocument();
buffer.close();
olive::TimelineMarker loaded;
QBuffer read_buffer(&xml);
read_buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&read_buffer);
EXPECT_TRUE(reader.readNextStartElement());
EXPECT_EQ(reader.name().toString(), QStringLiteral("marker"));
loaded.load(&reader);
EXPECT_EQ(loaded.time(), olive::core::rational(10, 1));
EXPECT_EQ(loaded.name(), QStringLiteral("Marker"));
EXPECT_EQ(loaded.color(), 5);
}
+44
View File
@@ -0,0 +1,44 @@
#include <gtest/gtest.h>
#include "undo/undostack.h"
#include "undo/undocommand.h"
namespace {
class TestCommand final : public olive::UndoCommand {
public:
explicit TestCommand(int *value)
: value_(value)
{
}
protected:
void redo() override
{
if (value_) {
(*value_)++;
}
}
void undo() override
{
if (value_) {
(*value_)--;
}
}
private:
int *value_ = nullptr;
};
}
TEST(UndoStack, PushUndoRedo)
{
int counter = 0;
olive::UndoStack stack;
stack.push(new TestCommand(&counter), QStringLiteral("Test"));
EXPECT_EQ(counter, 1);
stack.undo();
EXPECT_EQ(counter, 0);
stack.redo();
EXPECT_EQ(counter, 1);
}