Files
oak-editor/tests/gtest/timeline_marker_test.cpp
T
Mike-Solar 748c53ac5c Expand Google Test coverage across core subsystems
Add and extend unit tests for:
- Task manager (failed tasks, progress signals, multiple tasks)
- Undo stack (multiple undo/redo, push-after-undo, clear, multi-command)
- Config defaults and graphics backend string conversion
- Node keyframe serialization and default state
- Node value string round-trips and table operations
- Node globals and project settings/serialization
- Timeline coordinate, workarea, and marker commands
- Color LUT processor and OCIO transform handling
- Common utilities (range, file functions, Qt helpers, XML utils)
- Render enums (loop mode, alpha association)
- Shader resource availability
- Module smoke tests for Tool and HumanStrings

All tests pass including RenderWorkerFootage GPU worker tests after
rebuilding the stale olive-render-worker binary.
2026-07-13 10:19:30 +08:00

190 lines
5.3 KiB
C++

#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().in(), olive::core::rational(10, 1));
EXPECT_EQ(loaded.name(), QStringLiteral("Marker"));
EXPECT_EQ(loaded.color(), 5);
}
TEST(TimelineMarker, DefaultConstruction)
{
olive::TimelineMarker marker;
EXPECT_TRUE(marker.name().isEmpty());
EXPECT_EQ(marker.time().in(), olive::core::rational(0, 1));
}
TEST(TimelineMarkerList, OrderAndLookup)
{
olive::TimelineMarkerList list;
olive::TimelineMarker marker_a(
1,
olive::core::TimeRange(olive::core::rational(10, 1),
olive::core::rational(10, 1)),
QStringLiteral("A"),
&list);
olive::TimelineMarker marker_b(
2,
olive::core::TimeRange(olive::core::rational(5, 1),
olive::core::rational(5, 1)),
QStringLiteral("B"),
&list);
olive::TimelineMarker marker_c(
3,
olive::core::TimeRange(olive::core::rational(20, 1),
olive::core::rational(20, 1)),
QStringLiteral("C"),
&list);
ASSERT_EQ(list.size(), 3);
auto it = list.cbegin();
EXPECT_EQ((*it)->time().in(), olive::core::rational(5, 1));
++it;
EXPECT_EQ((*it)->time().in(), olive::core::rational(10, 1));
++it;
EXPECT_EQ((*it)->time().in(), olive::core::rational(20, 1));
EXPECT_EQ(list.GetMarkerAtTime(olive::core::rational(10, 1)), &marker_a);
EXPECT_EQ(list.GetClosestMarkerToTime(olive::core::rational(7, 1)),
&marker_b);
EXPECT_EQ(list.GetClosestMarkerToTime(olive::core::rational(9, 1)),
&marker_a);
}
TEST(TimelineMarkerList, GetMarkerAtTimeReturnsNullWhenEmpty)
{
olive::TimelineMarkerList list;
EXPECT_EQ(list.GetMarkerAtTime(olive::core::rational(10, 1)), nullptr);
EXPECT_EQ(list.GetClosestMarkerToTime(olive::core::rational(10, 1)), nullptr);
}
TEST(TimelineMarkerList, SaveLoadWithUnknownElements)
{
olive::TimelineMarkerList list;
olive::TimelineMarker marker(
4,
olive::core::TimeRange(olive::core::rational(12, 1),
olive::core::rational(15, 1)),
QStringLiteral("Span"),
&list);
QByteArray xml;
QBuffer buffer(&xml);
buffer.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
writer.writeStartElement(QStringLiteral("markers"));
writer.writeStartElement(QStringLiteral("unknown"));
writer.writeEndElement();
list.save(&writer);
writer.writeEndElement();
writer.writeEndDocument();
buffer.close();
olive::TimelineMarkerList loaded;
QBuffer read_buffer(&xml);
read_buffer.open(QIODevice::ReadOnly);
QXmlStreamReader reader(&read_buffer);
EXPECT_TRUE(reader.readNextStartElement());
EXPECT_EQ(reader.name().toString(), QStringLiteral("markers"));
EXPECT_TRUE(loaded.load(&reader));
EXPECT_EQ(loaded.size(), 1);
EXPECT_EQ(loaded.front()->name(), QStringLiteral("Span"));
EXPECT_EQ(loaded.front()->time().in(), olive::core::rational(12, 1));
}
TEST(TimelineMarkerCommands, AddRemoveAndChange)
{
olive::TimelineMarkerList list;
olive::MarkerAddCommand add(
&list,
olive::core::TimeRange(olive::core::rational(1, 1),
olive::core::rational(2, 1)),
QStringLiteral("One"),
1);
add.redo_now();
ASSERT_EQ(list.size(), 1);
auto *marker = list.front();
EXPECT_EQ(marker->name(), QStringLiteral("One"));
olive::MarkerChangeNameCommand rename(marker, QStringLiteral("Renamed"));
rename.redo_now();
EXPECT_EQ(marker->name(), QStringLiteral("Renamed"));
rename.undo_now();
EXPECT_EQ(marker->name(), QStringLiteral("One"));
olive::MarkerChangeColorCommand recolor(marker, 9);
recolor.redo_now();
EXPECT_EQ(marker->color(), 9);
recolor.undo_now();
EXPECT_EQ(marker->color(), 1);
olive::MarkerRemoveCommand remove(marker);
remove.redo_now();
EXPECT_TRUE(list.empty());
remove.undo_now();
EXPECT_EQ(list.size(), 1);
olive::TimelineMarker other(
2,
olive::core::TimeRange(olive::core::rational(5, 1),
olive::core::rational(5, 1)),
QStringLiteral("Two"),
&list);
EXPECT_EQ(list.front()->time().in(), olive::core::rational(1, 1));
olive::MarkerChangeTimeCommand move(
marker,
olive::core::TimeRange(olive::core::rational(0, 1),
olive::core::rational(0, 1)));
move.redo_now();
EXPECT_EQ(list.front(), marker);
move.undo_now();
EXPECT_EQ(list.front()->time().in(), olive::core::rational(1, 1));
}
TEST(TimelineMarkerCommands, AddCommandUndo)
{
olive::TimelineMarkerList list;
olive::MarkerAddCommand add(
&list,
olive::core::TimeRange(olive::core::rational(5, 1),
olive::core::rational(5, 1)),
QStringLiteral("UndoMe"),
2);
add.redo_now();
EXPECT_EQ(list.size(), 1);
add.undo_now();
EXPECT_TRUE(list.empty());
}