Files
oak-editor/tests/gtest/timeline_marker_test.cpp
Mike-Solar bb40b4923e style: unify identifier naming per updated conventions
Automated with clang-tidy readability-identifier-naming (config added to
.clang-tidy) plus scripted passes, per the updated rules now documented
in CONTRIBUTING.md:

- types (class/struct/enum/alias/template params): PascalCase
- functions, variables, members: snake_case (incl. rational -> Rational)
- private/protected members: trailing underscore; static member
  variables likewise (instance_, available_themes_)
- constants and enum values: snake_case (kLinear -> k_linear,
  F32P -> f32p); ALL_CAPS reserved for macros
- macros: OAK_ prefix (OLIVE_ADD_TEST/OLIVE_ASSERT/OLIVE_CONFIG ->
  OAK_ADD_TEST/OAK_ASSERT/OAK_CONFIG, GL_PREAMBLE -> OAK_GL_PREAMBLE,
  include guards -> OAK_*)
- file names: all lowercase (Current/Plugin/OliveHost/OliveClip/
  OlivePluginInstance -> current/plugin/olivehost/oliveclip/
  oliveplugininstance)
- getters share the member name sans underscore, setters set_foo()
- Qt and third-party (OpenFX) virtual overrides and framework callbacks
  keep their original names (exempt in .clang-tidy)

Manual follow-ups required where automation could not reach:
- string-based QMetaObject/SIGNAL/SLOT references updated to renamed
  methods (AddTask, CreatedFile, DeleteSpecificFile, moveSelectionUp, ...)
- macro bodies referencing renamed methods (OLIVE_CONFIG,
  NODE_DEFAULT_DESTRUCTOR, MANAGEDDISPLAYWIDGET_*)
- self-shadowing locals renamed where signals/methods became same-named
  (size_changed, worker_count, selected_items, import param, filters)
- third_party OFX member/namespace usages restored (OFX::Host::*,
  _created, _clipPrefsDirty, createInstance, clearPersistentMessage)
- STL protocol aliases restored (const_iterator) with .clang-tidy
  ignore rules; qHash overloads restored

Full build and test suite pass: ctest 4/4, ~1960 gtest cases green.
2026-07-19 16:10:54 +08:00

183 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.get_marker_at_time(olive::core::Rational(10, 1)), &marker_a);
EXPECT_EQ(list.get_closest_marker_to_time(olive::core::Rational(7, 1)),
&marker_b);
EXPECT_EQ(list.get_closest_marker_to_time(olive::core::Rational(9, 1)),
&marker_a);
}
TEST(TimelineMarkerList, GetMarkerAtTimeReturnsNullWhenEmpty)
{
olive::TimelineMarkerList list;
EXPECT_EQ(list.get_marker_at_time(olive::core::Rational(10, 1)), nullptr);
EXPECT_EQ(list.get_closest_marker_to_time(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());
}