[education/labplot] tests/backend/Column: [column] added more tests for mode conversion and for value labels in Column

Alexander Semke <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit c72fe651410ce03741fa5936d21437e2b5ce35e4 by Alexander Semke.
Committed on 10/08/2026 at 18:43.
Pushed by asemke into branch 'master'.

[column] added more tests for mode conversion and for value labels in Column

M  +407  -0    tests/backend/Column/ColumnTest.cpp
M  +33   -0    tests/backend/Column/ColumnTest.h

https://invent.kde.org/education/labplot/-/commit/c72fe651410ce03741fa5936d21437e2b5ce35e4

diff --git a/tests/backend/Column/ColumnTest.cpp b/tests/backend/Column/ColumnTest.cpp
index 9b02fcc9c9..a709e28a2a 100644
--- a/tests/backend/Column/ColumnTest.cpp
+++ b/tests/backend/Column/ColumnTest.cpp
@@ -2515,4 +2515,411 @@ void ColumnTest::testFormulaDateTimeEmptyCells() {
 	QCOMPARE(dayIntCol.isValid(3), false); // Empty → invalid
 }
 
+// ############################################################################
+// setColumnMode conversion tests
+// ############################################################################
+
+void ColumnTest::columnModeDoubleToBigInt() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.setValues({1.5, 2.7, NAN});
+
+	c.setColumnMode(Column::ColumnMode::BigInt);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::BigInt);
+	QCOMPARE(c.bigIntAt(0), (qint64)2); // round(1.5)
+	QCOMPARE(c.bigIntAt(1), (qint64)3); // round(2.7)
+	QCOMPARE(c.bigIntAt(2), (qint64)0); // NaN → 0
+	QCOMPARE(c.isValid(2), false); // NaN
+}
+
+void ColumnTest::columnModeDoubleToDateTime() {
+	// Double2DateTimeFilter interprets doubles as fractional days since 1900-01-01
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.setValues({0.0, 1.0}); // day 0 and day 1 relative to 1900-01-01
+
+	c.setColumnMode(Column::ColumnMode::DateTime);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::DateTime);
+	QCOMPARE(c.dateTimeAt(0), QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0)));
+	QCOMPARE(c.dateTimeAt(1), QDateTime(QDate(1900, 1, 2), QTime(0, 0, 0)));
+}
+
+void ColumnTest::columnModeDoubleToMonth() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.setValues({1.0});
+
+	c.setColumnMode(Column::ColumnMode::Month);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Month);
+	QVERIFY(c.dateTimeAt(0).isValid());
+}
+
+void ColumnTest::columnModeDoubleToDay() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.setValues({1.0});
+
+	c.setColumnMode(Column::ColumnMode::Day);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Day);
+	QVERIFY(c.dateTimeAt(0).isValid());
+}
+
+void ColumnTest::columnModeIntegerToBigInt() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Integer);
+	c.setIntegers({42, -7, 0});
+
+	c.setColumnMode(Column::ColumnMode::BigInt);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::BigInt);
+	QCOMPARE(c.bigIntAt(0), (qint64)42);
+	QCOMPARE(c.bigIntAt(1), (qint64)-7);
+	QCOMPARE(c.bigIntAt(2), (qint64)0);
+}
+
+void ColumnTest::columnModeIntegerToDateTime() {
+	// Integer2DateTimeFilter: epoch.addMSecs(value)
+	Column c(QStringLiteral("col"), Column::ColumnMode::Integer);
+	c.setIntegers({0, 1000});
+
+	c.setColumnMode(Column::ColumnMode::DateTime);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::DateTime);
+	const QDateTime epoch = QDateTime::fromSecsSinceEpoch(0, QTimeZone::UTC);
+	QCOMPARE(c.dateTimeAt(0), epoch);
+	QCOMPARE(c.dateTimeAt(1), epoch.addMSecs(1000));
+}
+
+void ColumnTest::columnModeBigIntToDouble() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::BigInt);
+	c.setBigInts({42LL, -7LL, 0LL});
+
+	c.setColumnMode(Column::ColumnMode::Double);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Double);
+	QCOMPARE(c.valueAt(0), 42.0);
+	QCOMPARE(c.valueAt(1), -7.0);
+	QCOMPARE(c.valueAt(2), 0.0);
+}
+
+void ColumnTest::columnModeBigIntToInteger() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::BigInt);
+	c.setBigInts({42LL, -7LL, 0LL});
+
+	c.setColumnMode(Column::ColumnMode::Integer);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Integer);
+	QCOMPARE(c.integerAt(0), 42);
+	QCOMPARE(c.integerAt(1), -7);
+	QCOMPARE(c.integerAt(2), 0);
+}
+
+void ColumnTest::columnModeBigIntToText() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::BigInt);
+	c.setBigInts({42LL});
+
+	c.setColumnMode(Column::ColumnMode::Text);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Text);
+	QCOMPARE(c.textAt(0), QLocale().toString((qint64)42));
+}
+
+void ColumnTest::columnModeBigIntToDateTime() {
+	// BigInt2DateTimeFilter: epoch.addMSecs(value)
+	Column c(QStringLiteral("col"), Column::ColumnMode::BigInt);
+	const qint64 ms = 1'000'000LL;
+	c.setBigInts({0LL, ms});
+
+	c.setColumnMode(Column::ColumnMode::DateTime);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::DateTime);
+	const QDateTime epoch = QDateTime::fromSecsSinceEpoch(0, QTimeZone::UTC);
+	QCOMPARE(c.dateTimeAt(0), epoch);
+	QCOMPARE(c.dateTimeAt(1), epoch.addMSecs(ms));
+}
+
+void ColumnTest::columnModeDateTimeToDouble() {
+	// DateTime2DoubleFilter: fractional days since 1900-01-01
+	Column c(QStringLiteral("col"), Column::ColumnMode::DateTime);
+	c.setDateTimes({QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0)), QDateTime(QDate(1900, 1, 2), QTime(0, 0, 0))});
+
+	c.setColumnMode(Column::ColumnMode::Double);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Double);
+	QCOMPARE(c.valueAt(0), 0.0);
+	QCOMPARE(c.valueAt(1), 1.0);
+}
+
+void ColumnTest::columnModeDateTimeToInteger() {
+	// DateTime2IntegerFilter: toMSecsSinceEpoch() cast to int
+	Column c(QStringLiteral("col"), Column::ColumnMode::DateTime);
+	const QDateTime epoch = QDateTime::fromSecsSinceEpoch(0, QTimeZone::UTC);
+	c.setDateTimes({epoch, epoch.addMSecs(500)});
+
+	c.setColumnMode(Column::ColumnMode::Integer);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Integer);
+	QCOMPARE(c.integerAt(0), 0);
+	QCOMPARE(c.integerAt(1), 500);
+}
+
+void ColumnTest::columnModeDateTimeToBigInt() {
+	// DateTime2BigIntFilter: toMSecsSinceEpoch()
+	Column c(QStringLiteral("col"), Column::ColumnMode::DateTime);
+	const QDateTime epoch = QDateTime::fromSecsSinceEpoch(0, QTimeZone::UTC);
+	const qint64 ms = 1'000'000LL;
+	c.setDateTimes({epoch, epoch.addMSecs(ms)});
+
+	c.setColumnMode(Column::ColumnMode::BigInt);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::BigInt);
+	QCOMPARE(c.bigIntAt(0), (qint64)0);
+	QCOMPARE(c.bigIntAt(1), ms);
+}
+
+void ColumnTest::columnModeDateTimeToText() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::DateTime);
+	c.setDateTimes({QDateTime(QDate(2024, 3, 15), QTime(0, 0, 0))});
+
+	c.setColumnMode(Column::ColumnMode::Text);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Text);
+	QVERIFY(!c.textAt(0).isEmpty());
+}
+
+void ColumnTest::columnModeTextToDateTime() {
+	// String2DateTimeFilter default format: "yyyy-MM-dd hh:mm:ss.zzz"
+	Column c(QStringLiteral("col"), Column::ColumnMode::Text);
+	c.setText({QStringLiteral("2024-03-15 00:00:00.000"), QStringLiteral("not-a-date")});
+
+	c.setColumnMode(Column::ColumnMode::DateTime);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::DateTime);
+	QCOMPARE(c.dateTimeAt(0), QDateTime(QDate(2024, 3, 15), QTime(0, 0, 0)));
+	QVERIFY(!c.dateTimeAt(1).isValid()); // unparseable string → invalid
+}
+
+// ############################################################################
+// value label tests
+// ############################################################################
+
+void ColumnTest::valueLabelsIntegerColumnBasic() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Integer);
+	c.addValueLabel(1, QStringLiteral("one"));
+	c.addValueLabel(2, QStringLiteral("two"));
+	c.addValueLabel(3, QStringLiteral("three"));
+
+	QCOMPARE(c.valueLabelsCount(), 3);
+	QVERIFY(c.valueLabelsInitialized());
+
+	const auto* labels = c.intValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 3);
+	QCOMPARE(labels->at(0).value, 1);
+	QCOMPARE(labels->at(0).label, QStringLiteral("one"));
+	QCOMPARE(labels->at(2).value, 3);
+	QCOMPARE(labels->at(2).label, QStringLiteral("three"));
+}
+
+void ColumnTest::valueLabelsBigIntColumn() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::BigInt);
+	c.addValueLabel((qint64)100, QStringLiteral("hundred"));
+	c.addValueLabel((qint64)200, QStringLiteral("two hundred"));
+
+	QCOMPARE(c.valueLabelsCount(), 2);
+
+	const auto* labels = c.bigIntValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 2);
+	QCOMPARE(labels->at(0).value, (qint64)100);
+	QCOMPARE(labels->at(0).label, QStringLiteral("hundred"));
+	QCOMPARE(labels->at(1).value, (qint64)200);
+
+	// wrong-type accessor returns null
+	QCOMPARE(c.intValueLabels(), nullptr);
+	QCOMPARE(c.valueLabels(), nullptr);
+}
+
+void ColumnTest::valueLabelsTextColumn() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Text);
+	c.addValueLabel(QStringLiteral("low"), QStringLiteral("Low state"));
+	c.addValueLabel(QStringLiteral("high"), QStringLiteral("High state"));
+
+	QCOMPARE(c.valueLabelsCount(), 2);
+
+	const auto* labels = c.textValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 2);
+	QCOMPARE(labels->at(0).value, QStringLiteral("low"));
+	QCOMPARE(labels->at(0).label, QStringLiteral("Low state"));
+
+	// wrong-type accessors return null
+	QCOMPARE(c.intValueLabels(), nullptr);
+	QCOMPARE(c.valueLabels(), nullptr);
+}
+
+void ColumnTest::valueLabelsMigrateDoubleToInteger() {
+	// Double labels are truncated (cast) when migrating to Integer
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.addValueLabel(1.9, QStringLiteral("almost two"));
+	c.addValueLabel(5.0, QStringLiteral("five"));
+
+	c.setColumnMode(Column::ColumnMode::Integer);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Integer);
+	QCOMPARE(c.valueLabelsCount(), 2);
+
+	const auto* labels = c.intValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->at(0).value, 1); // (int)1.9 = 1 (truncation)
+	QCOMPARE(labels->at(0).label, QStringLiteral("almost two"));
+	QCOMPARE(labels->at(1).value, 5);
+	QCOMPARE(labels->at(1).label, QStringLiteral("five"));
+}
+
+void ColumnTest::valueLabelsMigrateDoubleToBigInt() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.addValueLabel(42.0, QStringLiteral("forty-two"));
+	c.addValueLabel(-7.0, QStringLiteral("minus seven"));
+
+	c.setColumnMode(Column::ColumnMode::BigInt);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::BigInt);
+	const auto* labels = c.bigIntValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 2);
+	QCOMPARE(labels->at(0).value, (qint64)42);
+	QCOMPARE(labels->at(1).value, (qint64)-7);
+}
+
+void ColumnTest::valueLabelsMigrateDoubleToText() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.addValueLabel(1.0, QStringLiteral("one"));
+	c.addValueLabel(2.0, QStringLiteral("two"));
+
+	c.setColumnMode(Column::ColumnMode::Text);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Text);
+	const auto* labels = c.textValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 2);
+	QCOMPARE(labels->at(0).label, QStringLiteral("one"));
+	QCOMPARE(labels->at(1).label, QStringLiteral("two"));
+}
+
+void ColumnTest::valueLabelsMigrateIntegerToDouble() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Integer);
+	c.addValueLabel(10, QStringLiteral("ten"));
+	c.addValueLabel(20, QStringLiteral("twenty"));
+
+	c.setColumnMode(Column::ColumnMode::Double);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Double);
+	const auto* labels = c.valueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 2);
+	QCOMPARE(labels->at(0).value, 10.0);
+	QCOMPARE(labels->at(0).label, QStringLiteral("ten"));
+	QCOMPARE(labels->at(1).value, 20.0);
+}
+
+void ColumnTest::valueLabelsMigrateIntegerToBigInt() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Integer);
+	c.addValueLabel(7, QStringLiteral("seven"));
+
+	c.setColumnMode(Column::ColumnMode::BigInt);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::BigInt);
+	const auto* labels = c.bigIntValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 1);
+	QCOMPARE(labels->at(0).value, (qint64)7);
+	QCOMPARE(labels->at(0).label, QStringLiteral("seven"));
+}
+
+void ColumnTest::valueLabelsMigrateBigIntToDouble() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::BigInt);
+	c.addValueLabel((qint64)1000, QStringLiteral("thousand"));
+
+	c.setColumnMode(Column::ColumnMode::Double);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Double);
+	const auto* labels = c.valueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 1);
+	QCOMPARE(labels->at(0).value, 1000.0);
+	QCOMPARE(labels->at(0).label, QStringLiteral("thousand"));
+}
+
+void ColumnTest::valueLabelsMigrateBigIntToInteger() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::BigInt);
+	c.addValueLabel((qint64)99, QStringLiteral("ninety-nine"));
+
+	c.setColumnMode(Column::ColumnMode::Integer);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Integer);
+	const auto* labels = c.intValueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 1);
+	QCOMPARE(labels->at(0).value, 99);
+	QCOMPARE(labels->at(0).label, QStringLiteral("ninety-nine"));
+}
+
+void ColumnTest::valueLabelsMigrateTextToDouble() {
+	// Parseable strings become double values; unparseable ones are dropped
+	Column c(QStringLiteral("col"), Column::ColumnMode::Text);
+	c.addValueLabel(QStringLiteral("3.14"), QStringLiteral("pi-ish"));
+	c.addValueLabel(QStringLiteral("not-a-number"), QStringLiteral("invalid"));
+
+	c.setColumnMode(Column::ColumnMode::Double);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Double);
+	const auto* labels = c.valueLabels();
+	QVERIFY(labels != nullptr);
+	QCOMPARE(labels->size(), 1); // "not-a-number" is dropped
+	QCOMPARE(labels->at(0).label, QStringLiteral("pi-ish"));
+}
+
+void ColumnTest::valueLabelsMigrateDateTimeToDouble() {
+	// DateTime → Double migration is not supported; all labels are dropped
+	Column c(QStringLiteral("col"), Column::ColumnMode::DateTime);
+	c.addValueLabel(QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0)), QStringLiteral("new year"));
+	QCOMPARE(c.valueLabelsCount(), 1);
+
+	c.setColumnMode(Column::ColumnMode::Double);
+
+	QCOMPARE(c.columnMode(), Column::ColumnMode::Double);
+	// labels are re-initialized empty after migration
+	QCOMPARE(c.valueLabelsCount(), 0);
+}
+
+void ColumnTest::valueLabelsRemoveAll() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Double);
+	c.addValueLabel(1.0, QStringLiteral("one"));
+	c.addValueLabel(2.0, QStringLiteral("two"));
+	c.addValueLabel(3.0, QStringLiteral("three"));
+	QCOMPARE(c.valueLabelsCount(), 3);
+
+	c.valueLabelsRemoveAll();
+
+	QCOMPARE(c.valueLabelsCount(), 0);
+	QVERIFY(c.valueLabelsInitialized()); // still initialized, just empty
+}
+
+void ColumnTest::valueLabelsRemoveSingle() {
+	Column c(QStringLiteral("col"), Column::ColumnMode::Integer);
+	c.addValueLabel(1, QStringLiteral("one"));
+	c.addValueLabel(2, QStringLiteral("two"));
+	c.addValueLabel(3, QStringLiteral("three"));
+	QCOMPARE(c.valueLabelsCount(), 3);
+
+	c.removeValueLabel(QLocale().toString(2)); // key is locale-formatted value
+
+	QCOMPARE(c.valueLabelsCount(), 2);
+	const auto* labels = c.intValueLabels();
+	QVERIFY(labels != nullptr);
+	// value 2 is gone, 1 and 3 remain
+	QCOMPARE(labels->at(0).value, 1);
+	QCOMPARE(labels->at(1).value, 3);
+}
+
 QTEST_MAIN(ColumnTest)
diff --git a/tests/backend/Column/ColumnTest.h b/tests/backend/Column/ColumnTest.h
index b298859b37..12e144c12a 100644
--- a/tests/backend/Column/ColumnTest.h
+++ b/tests/backend/Column/ColumnTest.h
@@ -155,6 +155,39 @@ private Q_SLOTS:
 	void testFormulaDateTimeToDateTime();
 	void testFormulaDateTimeDatedif();
 	void testFormulaDateTimeEmptyCells();
+
+	// setColumnMode conversion tests
+	void columnModeDoubleToBigInt();
+	void columnModeDoubleToDateTime();
+	void columnModeDoubleToMonth();
+	void columnModeDoubleToDay();
+	void columnModeIntegerToBigInt();
+	void columnModeIntegerToDateTime();
+	void columnModeBigIntToDouble();
+	void columnModeBigIntToInteger();
+	void columnModeBigIntToText();
+	void columnModeBigIntToDateTime();
+	void columnModeDateTimeToDouble();
+	void columnModeDateTimeToInteger();
+	void columnModeDateTimeToBigInt();
+	void columnModeDateTimeToText();
+	void columnModeTextToDateTime();
+
+	// value label tests
+	void valueLabelsIntegerColumnBasic();
+	void valueLabelsBigIntColumn();
+	void valueLabelsTextColumn();
+	void valueLabelsMigrateDoubleToInteger();
+	void valueLabelsMigrateDoubleToBigInt();
+	void valueLabelsMigrateDoubleToText();
+	void valueLabelsMigrateIntegerToDouble();
+	void valueLabelsMigrateIntegerToBigInt();
+	void valueLabelsMigrateBigIntToDouble();
+	void valueLabelsMigrateBigIntToInteger();
+	void valueLabelsMigrateTextToDouble();
+	void valueLabelsMigrateDateTimeToDouble();
+	void valueLabelsRemoveAll();
+	void valueLabelsRemoveSingle();
 };
 
 #endif // COLUMNTEST_H
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.