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.
190 lines
5.3 KiB
C++
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());
|
|
}
|