diff --git a/libs/flake/tests/TestPointMergeCommand.cpp b/libs/flake/tests/TestPointMergeCommand.cpp index cd73dffafa..077e307b06 100644 --- a/libs/flake/tests/TestPointMergeCommand.cpp +++ b/libs/flake/tests/TestPointMergeCommand.cpp @@ -1,564 +1,578 @@ /* This file is part of the KDE project * Copyright (C) 2009 Jan Hambrecht * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "TestPointMergeCommand.h" #include "KoPathPointMergeCommand.h" #include "KoPathShape.h" #include "KoPathPoint.h" #include "KoPathPointData.h" #include #include #include void TestPointMergeCommand::closeSingleLinePath() { KoPathShape path1; path1.moveTo(QPointF(40, 0)); path1.lineTo(QPointF(60, 0)); path1.lineTo(QPointF(60, 30)); path1.lineTo(QPointF(0, 30)); path1.lineTo(QPointF(0, 0)); path1.lineTo(QPointF(20, 0)); KoPathPointIndex index1(0,0); KoPathPointIndex index2(0,5); KoPathPointData pd1(&path1, index1); KoPathPointData pd2(&path1, index2); KoPathPoint * p1 = path1.pointByIndex(index1); KoPathPoint * p2 = path1.pointByIndex(index2); QVERIFY(!path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 6); QCOMPARE(p1->point(), QPointF(40,0)); QCOMPARE(p2->point(), QPointF(20,0)); KoPathPointMergeCommand cmd1(pd1,pd2); cmd1.redo(); QVERIFY(path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 5); QCOMPARE(p2->point(), QPointF(20,0)); cmd1.undo(); QVERIFY(!path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 6); QCOMPARE(p1->point(), QPointF(40,0)); QCOMPARE(p2->point(), QPointF(20,0)); KoPathPointMergeCommand cmd2(pd2,pd1); cmd2.redo(); QVERIFY(path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 5); QCOMPARE(p2->point(), QPointF(20,0)); cmd2.undo(); QVERIFY(!path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 6); QCOMPARE(p1->point(), QPointF(40,0)); QCOMPARE(p2->point(), QPointF(20,0)); } void TestPointMergeCommand::closeSingleCurvePath() { KoPathShape path1; path1.moveTo(QPointF(40, 0)); path1.curveTo(QPointF(60, 0), QPointF(60,0), QPointF(60,60)); path1.lineTo(QPointF(0, 60)); path1.curveTo(QPointF(0, 0), QPointF(0,0), QPointF(20,0)); KoPathPointIndex index1(0,0); KoPathPointIndex index2(0,3); KoPathPointData pd1(&path1, index1); KoPathPointData pd2(&path1, index2); KoPathPoint * p1 = path1.pointByIndex(index1); KoPathPoint * p2 = path1.pointByIndex(index2); QVERIFY(!path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 4); QCOMPARE(p1->point(), QPointF(40,0)); QVERIFY(!p1->activeControlPoint1()); QCOMPARE(p2->point(), QPointF(20,0)); QVERIFY(!p2->activeControlPoint2()); KoPathPointMergeCommand cmd1(pd1,pd2); cmd1.redo(); QVERIFY(path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 3); QCOMPARE(p2->point(), QPointF(20,0)); QVERIFY(p2->activeControlPoint1()); QVERIFY(!p2->activeControlPoint2()); cmd1.undo(); QVERIFY(!path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 4); QCOMPARE(p1->point(), QPointF(40,0)); QVERIFY(!p1->activeControlPoint1()); QCOMPARE(p2->point(), QPointF(20,0)); QVERIFY(!p2->activeControlPoint2()); KoPathPointMergeCommand cmd2(pd2,pd1); cmd2.redo(); QVERIFY(path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 3); QCOMPARE(p2->point(), QPointF(20,0)); QVERIFY(p2->activeControlPoint1()); QVERIFY(!p2->activeControlPoint2()); cmd2.undo(); QVERIFY(!path1.isClosedSubpath(0)); QCOMPARE(path1.subpathPointCount(0), 4); QCOMPARE(p1->point(), QPointF(40,0)); QVERIFY(!p1->activeControlPoint1()); QCOMPARE(p2->point(), QPointF(20,0)); QVERIFY(!p2->activeControlPoint2()); } void TestPointMergeCommand::connectLineSubpaths() { KoPathShape path1; path1.moveTo(QPointF(0,0)); path1.lineTo(QPointF(10,0)); path1.moveTo(QPointF(20,0)); path1.lineTo(QPointF(30,0)); KoPathPointIndex index1(0,1); KoPathPointIndex index2(1,0); KoPathPointData pd1(&path1, index1); KoPathPointData pd2(&path1, index2); QCOMPARE(path1.subpathCount(), 2); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(10,0)); QCOMPARE(path1.pointByIndex(index2)->point(), QPointF(20,0)); KoPathPointMergeCommand cmd1(pd1, pd2); cmd1.redo(); QCOMPARE(path1.subpathCount(), 1); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(15,0)); cmd1.undo(); QCOMPARE(path1.subpathCount(), 2); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(10,0)); QCOMPARE(path1.pointByIndex(index2)->point(), QPointF(20,0)); KoPathPointMergeCommand cmd2(pd2, pd1); cmd2.redo(); QCOMPARE(path1.subpathCount(), 1); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(15,0)); cmd2.undo(); QCOMPARE(path1.subpathCount(), 2); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(10,0)); QCOMPARE(path1.pointByIndex(index2)->point(), QPointF(20,0)); } void TestPointMergeCommand::connectCurveSubpaths() { KoPathShape path1; path1.moveTo(QPointF(0,0)); path1.curveTo(QPointF(20,0),QPointF(0,20),QPointF(20,20)); path1.moveTo(QPointF(50,0)); path1.curveTo(QPointF(30,0), QPointF(50,20), QPointF(30,20)); KoPathPointIndex index1(0,1); KoPathPointIndex index2(1,1); KoPathPointData pd1(&path1, index1); KoPathPointData pd2(&path1, index2); QCOMPARE(path1.subpathCount(), 2); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(20,20)); QCOMPARE(path1.pointByIndex(index1)->controlPoint1(), QPointF(0,20)); QCOMPARE(path1.pointByIndex(index2)->point(), QPointF(30,20)); QCOMPARE(path1.pointByIndex(index2)->controlPoint1(), QPointF(50,20)); QVERIFY(path1.pointByIndex(index1)->activeControlPoint1()); QVERIFY(!path1.pointByIndex(index1)->activeControlPoint2()); KoPathPointMergeCommand cmd1(pd1, pd2); cmd1.redo(); QCOMPARE(path1.subpathCount(), 1); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(25,20)); QCOMPARE(path1.pointByIndex(index1)->controlPoint1(), QPointF(5,20)); QCOMPARE(path1.pointByIndex(index1)->controlPoint2(), QPointF(45,20)); QVERIFY(path1.pointByIndex(index1)->activeControlPoint1()); QVERIFY(path1.pointByIndex(index1)->activeControlPoint2()); cmd1.undo(); QCOMPARE(path1.subpathCount(), 2); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(20,20)); QCOMPARE(path1.pointByIndex(index1)->controlPoint1(), QPointF(0,20)); QCOMPARE(path1.pointByIndex(index2)->point(), QPointF(30,20)); QCOMPARE(path1.pointByIndex(index2)->controlPoint1(), QPointF(50,20)); QVERIFY(path1.pointByIndex(index1)->activeControlPoint1()); QVERIFY(!path1.pointByIndex(index1)->activeControlPoint2()); KoPathPointMergeCommand cmd2(pd2, pd1); cmd2.redo(); QCOMPARE(path1.subpathCount(), 1); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(25,20)); QCOMPARE(path1.pointByIndex(index1)->controlPoint1(), QPointF(5,20)); QCOMPARE(path1.pointByIndex(index1)->controlPoint2(), QPointF(45,20)); QVERIFY(path1.pointByIndex(index1)->activeControlPoint1()); QVERIFY(path1.pointByIndex(index1)->activeControlPoint2()); cmd2.undo(); QCOMPARE(path1.subpathCount(), 2); QCOMPARE(path1.pointByIndex(index1)->point(), QPointF(20,20)); QCOMPARE(path1.pointByIndex(index1)->controlPoint1(), QPointF(0,20)); QCOMPARE(path1.pointByIndex(index2)->point(), QPointF(30,20)); QCOMPARE(path1.pointByIndex(index2)->controlPoint1(), QPointF(50,20)); QVERIFY(path1.pointByIndex(index1)->activeControlPoint1()); QVERIFY(!path1.pointByIndex(index1)->activeControlPoint2()); } #include #include #include "kis_debug.h" #include void TestPointMergeCommand::testCombineShapes() { MockShapeController mockController; MockCanvas canvas(&mockController); - QList shapes; + QList shapesToCombine; for (int i = 0; i < 3; i++) { const QPointF step(15,15); const QRectF rect = QRectF(5,5,10,10).translated(step * i); QPainterPath p; p.addRect(rect); KoPathShape *shape = KoPathShape::createShapeFromPainterPath(p); QCOMPARE(shape->absoluteOutlineRect(), rect); - shapes << shape; + shapesToCombine << shape; mockController.addShape(shape); } - KoPathCombineCommand cmd(&mockController, shapes); + KoPathCombineCommand cmd(&mockController, shapesToCombine); cmd.redo(); QCOMPARE(canvas.shapeManager()->shapes().size(), 1); KoPathShape *combinedShape = dynamic_cast(canvas.shapeManager()->shapes().first()); QCOMPARE(combinedShape, cmd.combinedPath()); QCOMPARE(combinedShape->subpathCount(), 3); QCOMPARE(combinedShape->absoluteOutlineRect(), QRectF(5,5,40,40)); QList tstPoints; QList expPoints; - tstPoints << KoPathPointData(shapes[0], KoPathPointIndex(0,1)); + tstPoints << KoPathPointData(shapesToCombine[0], KoPathPointIndex(0,1)); expPoints << KoPathPointData(combinedShape, KoPathPointIndex(0,1)); - tstPoints << KoPathPointData(shapes[1], KoPathPointIndex(0,2)); + tstPoints << KoPathPointData(shapesToCombine[1], KoPathPointIndex(0,2)); expPoints << KoPathPointData(combinedShape, KoPathPointIndex(1,2)); - tstPoints << KoPathPointData(shapes[2], KoPathPointIndex(0,3)); + tstPoints << KoPathPointData(shapesToCombine[2], KoPathPointIndex(0,3)); expPoints << KoPathPointData(combinedShape, KoPathPointIndex(2,3)); for (int i = 0; i < tstPoints.size(); i++) { KoPathPointData convertedPoint = cmd.originalToCombined(tstPoints[i]); QCOMPARE(convertedPoint, expPoints[i]); } - qDeleteAll(canvas.shapeManager()->shapes()); + Q_FOREACH (KoShape *shape, canvas.shapeManager()->shapes()) { + mockController.removeShape(shape); + shape->setParent(0); + delete shape; + } + + // 'shapesToCombine' will be deleted by KoPathCombineCommand } #include #include #include #include "kis_algebra_2d.h" inline QPointF fetchPoint(KoPathShape *shape, int subpath, int pointIndex) { return shape->absoluteTransformation(0).map( shape->pointByIndex(KoPathPointIndex(subpath, pointIndex))->point()); } void dumpShape(KoPathShape *shape, const QString &fileName) { QImage tmp(50,50, QImage::Format_ARGB32); tmp.fill(0); QPainter p(&tmp); p.drawPath(shape->absoluteTransformation(0).map(shape->outline())); tmp.save(fileName); } template void testMultipathMergeShapesImpl(const int srcPointIndex1, const int srcPointIndex2, const QList &expectedResultPoints, bool singleShape = false) { MockShapeController mockController; MockCanvas canvas(&mockController); QList shapes; for (int i = 0; i < 3; i++) { const QPointF step(15,15); const QRectF rect = QRectF(5,5,10,10).translated(step * i); QPainterPath p; p.moveTo(rect.topLeft()); p.lineTo(rect.bottomRight()); p.lineTo(rect.topRight()); KoPathShape *shape = KoPathShape::createShapeFromPainterPath(p); QCOMPARE(shape->absoluteOutlineRect(), rect); shapes << shape; mockController.addShape(shape); } { KoPathPointData pd1(shapes[0], KoPathPointIndex(0,srcPointIndex1)); KoPathPointData pd2(shapes[singleShape ? 0 : 1], KoPathPointIndex(0,srcPointIndex2)); MergeCommand cmd(pd1, pd2, &mockController, canvas.shapeManager()->selection()); cmd.redo(); const int expectedShapesCount = singleShape ? 3 : 2; QCOMPARE(canvas.shapeManager()->shapes().size(), expectedShapesCount); KoPathShape *combinedShape = 0; if (!singleShape) { combinedShape = dynamic_cast(canvas.shapeManager()->shapes()[1]); QCOMPARE(combinedShape, cmd.testingCombinedPath()); } else { combinedShape = dynamic_cast(canvas.shapeManager()->shapes()[0]); QCOMPARE(combinedShape, shapes[0]); } QCOMPARE(combinedShape->subpathCount(), 1); QRectF expectedOutlineRect; KisAlgebra2D::accumulateBounds(expectedResultPoints, &expectedOutlineRect); QVERIFY(KisAlgebra2D::fuzzyCompareRects(combinedShape->absoluteOutlineRect(), expectedOutlineRect, 0.01)); if (singleShape) { QCOMPARE(combinedShape->isClosedSubpath(0), true); } QCOMPARE(combinedShape->subpathPointCount(0), expectedResultPoints.size()); for (int i = 0; i < expectedResultPoints.size(); i++) { if (fetchPoint(combinedShape, 0, i) != expectedResultPoints[i]) { qDebug() << ppVar(i); qDebug() << ppVar(fetchPoint(combinedShape, 0, i)); qDebug() << ppVar(expectedResultPoints[i]); QFAIL("Resulting shape points are different!"); } } QList shapes = canvas.shapeManager()->selection()->selectedEditableShapes(); QCOMPARE(shapes.size(), 1); QCOMPARE(shapes.first(), combinedShape); //dumpShape(combinedShape, "tmp_0_seq.png"); cmd.undo(); QCOMPARE(canvas.shapeManager()->shapes().size(), 3); } + + Q_FOREACH (KoShape *shape, canvas.shapeManager()->shapes()) { + mockController.removeShape(shape); + shape->setParent(0); + delete shape; + } + + // combined shapes will be deleted by the corresponding commands } void TestPointMergeCommand::testMultipathMergeShapesBothSequential() { // both sequential testMultipathMergeShapesImpl(2, 0, { QPointF(5,5), QPointF(15,15), QPointF(17.5,12.5), // merged by melding the points! QPointF(30,30), QPointF(30,20) }); } void TestPointMergeCommand::testMultipathMergeShapesFirstReversed() { // first reversed testMultipathMergeShapesImpl(0, 0, { QPointF(15,5), QPointF(15,15), QPointF(12.5,12.5), // merged by melding the points! QPointF(30,30), QPointF(30,20) }); } void TestPointMergeCommand::testMultipathMergeShapesSecondReversed() { // second reversed testMultipathMergeShapesImpl(2, 2, { QPointF(5,5), QPointF(15,15), QPointF(22.5,12.5), // merged by melding the points! QPointF(30,30), QPointF(20,20) }); } void TestPointMergeCommand::testMultipathMergeShapesBothReversed() { // both reversed testMultipathMergeShapesImpl(0, 2, { QPointF(15,5), QPointF(15,15), QPointF(17.5,12.5), // merged by melding the points! QPointF(30,30), QPointF(20,20) }); } void TestPointMergeCommand::testMultipathMergeShapesSingleShapeEndToStart() { // close end->start testMultipathMergeShapesImpl(2, 0, { - QPointF(15,15), - QPointF(10,5) + QPointF(10,5), + QPointF(15,15) }, true); } void TestPointMergeCommand::testMultipathMergeShapesSingleShapeStartToEnd() { // close start->end testMultipathMergeShapesImpl(0, 2, { - QPointF(15,15), - QPointF(10,5) + QPointF(10,5), + QPointF(15,15) }, true); } void TestPointMergeCommand::testMultipathJoinShapesBothSequential() { // both sequential testMultipathMergeShapesImpl (2, 0, { QPointF(5,5), QPointF(15,15), QPointF(15,5), QPointF(20,20), QPointF(30,30), QPointF(30,20) }); } void TestPointMergeCommand::testMultipathJoinShapesFirstReversed() { // first reversed testMultipathMergeShapesImpl (0, 0, { QPointF(15,5), QPointF(15,15), QPointF(5,5), QPointF(20,20), QPointF(30,30), QPointF(30,20) }); } void TestPointMergeCommand::testMultipathJoinShapesSecondReversed() { // second reversed testMultipathMergeShapesImpl (2, 2, { QPointF(5,5), QPointF(15,15), QPointF(15,5), QPointF(30,20), QPointF(30,30), QPointF(20,20) }); } void TestPointMergeCommand::testMultipathJoinShapesBothReversed() { // both reversed testMultipathMergeShapesImpl (0, 2, { QPointF(15,5), QPointF(15,15), QPointF(5,5), QPointF(30,20), QPointF(30,30), QPointF(20,20) }); } void TestPointMergeCommand::testMultipathJoinShapesSingleShapeEndToStart() { // close end->start testMultipathMergeShapesImpl (2, 0, { QPointF(5,5), QPointF(15,15), QPointF(15,5) }, true); } void TestPointMergeCommand::testMultipathJoinShapesSingleShapeStartToEnd() { // close start->end testMultipathMergeShapesImpl (0, 2, { QPointF(5,5), QPointF(15,15), QPointF(15,5) }, true); } KISTEST_MAIN(TestPointMergeCommand) diff --git a/libs/image/tests/kis_meta_data_test.cpp b/libs/image/tests/kis_meta_data_test.cpp index 9295c6404b..f079c9caf4 100644 --- a/libs/image/tests/kis_meta_data_test.cpp +++ b/libs/image/tests/kis_meta_data_test.cpp @@ -1,592 +1,582 @@ /* * Copyright (c) 2008-2009 Cyrille Berger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_meta_data_test.h" #include #include "kis_meta_data_entry.h" #include "kis_meta_data_filter_registry.h" #include "kis_meta_data_value.h" #include "kis_meta_data_schema.h" #include "kis_meta_data_schema_registry.h" #include "kis_meta_data_store.h" #include "kis_meta_data_type_info.h" #include "kis_meta_data_type_info_p.h" #include "kis_meta_data_parser.h" #include "kis_meta_data_validator.h" #include "sdk/tests/kistest.h" using namespace KisMetaData; KisMetaData::Value KisMetaDataTest::createRationalValue() { return KisMetaData::Value(Rational(12, -42)); } KisMetaData::Value KisMetaDataTest::createIntegerValue(int v) { return KisMetaData::Value(v); } KisMetaData::Value KisMetaDataTest::createStringValue() { return KisMetaData::Value("Hello World !"); } KisMetaData::Value KisMetaDataTest::createListValue() { QList list; list << createRationalValue() << createIntegerValue() << createStringValue(); return list; } #define TEST_SCHEMA(uriStr) \ { \ const Schema* schema = SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::uriStr); \ QVERIFY(schema); \ QCOMPARE(schema->uri(), KisMetaData::Schema::uriStr); \ QCOMPARE(schema, SchemaRegistry::instance()->schemaFromPrefix(schema->prefix()) ); \ QVERIFY( !SchemaRegistry::instance()->create("http://tartampion.com", schema->prefix())); \ QCOMPARE(schema, SchemaRegistry::instance()->create(KisMetaData::Schema::uriStr, "tartampion")); \ QCOMPARE(QString(schema->prefix() + ":hello"), schema->generateQualifiedName("hello")); \ } void KisMetaDataTest::testSchemaBasic() { TEST_SCHEMA(TIFFSchemaUri); TEST_SCHEMA(EXIFSchemaUri); TEST_SCHEMA(DublinCoreSchemaUri); TEST_SCHEMA(XMPSchemaUri); TEST_SCHEMA(XMPRightsSchemaUri); TEST_SCHEMA(MakerNoteSchemaUri); TEST_SCHEMA(IPTCSchemaUri); TEST_SCHEMA(PhotoshopSchemaUri); } void KisMetaDataTest::testRationals() { { KisMetaData::Rational sr(-10, -14); QCOMPARE(sr.numerator, -10); QCOMPARE(sr.denominator, -14); KisMetaData::Rational sr2(14, 10); QVERIFY(sr == sr); QVERIFY(!(sr == sr2)); QVERIFY(sr != sr2); } { KisMetaData::Rational sr(10, 14); QCOMPARE(sr.numerator, 10); QCOMPARE(sr.denominator, 14); KisMetaData::Rational sr2(14, 10); QVERIFY(sr == sr); QVERIFY(!(sr == sr2)); QVERIFY(sr != sr2); } } void KisMetaDataTest::testValueCreation() { { Value v; QCOMPARE(v.type(), Value::Invalid); } { Value v(10); QCOMPARE(v.type(), Value::Variant); QCOMPARE(v.asVariant().toInt(), 10); QCOMPARE(v.asInteger(), 10); QCOMPARE(createIntegerValue().type(), Value::Variant); } { Value v("Hello World !"); QCOMPARE(v.type(), Value::Variant); QCOMPARE(v.asVariant().toString(), QString("Hello World !")); QCOMPARE(createStringValue().type(), Value::Variant); } { KisMetaData::Rational sr(42, -12); Value v(sr); QCOMPARE(v.type(), Value::Rational); QCOMPARE(v.asRational(), sr); QCOMPARE(createRationalValue().type(), Value::Rational); QCOMPARE(v.asInteger(), -42 / 12); QCOMPARE(v.asDouble(), -42.0 / 12.0); } { KisMetaData::Rational sr(42, 12); Value v(sr); QCOMPARE(v.type(), Value::Rational); QCOMPARE(v.asRational(), sr); QCOMPARE(createRationalValue().type(), Value::Rational); QCOMPARE(v.asInteger(), 42 / 12); QCOMPARE(v.asDouble(), 42.0 / 12.0); } { QList list; list << createRationalValue() << createIntegerValue() << createStringValue(); Value v(list); QCOMPARE(v.type(), Value::OrderedArray); QVERIFY(v.isArray()); QCOMPARE(v.asArray(), list); QCOMPARE(createListValue().type(), Value::OrderedArray); } { Value v(QList(), Value::OrderedArray); QCOMPARE(v.type(), Value::OrderedArray); QVERIFY(v.isArray()); } { Value v(QList(), Value::UnorderedArray); QCOMPARE(v.type(), Value::UnorderedArray); QVERIFY(v.isArray()); } { Value v(QList(), Value::AlternativeArray); QCOMPARE(v.type(), Value::AlternativeArray); QVERIFY(v.isArray()); } } void KisMetaDataTest::testValueEquality() { QVERIFY(createRationalValue() == createRationalValue()); QVERIFY(createIntegerValue() == createIntegerValue()); QVERIFY(createStringValue() == createStringValue()); QVERIFY(createListValue() == createListValue()); } #define TEST_VALUE_COPY(func) \ { \ Value v1 = func(); \ Value v2(v1); \ Value v3 = v1; \ QCOMPARE(v1, v2); \ QCOMPARE(v1, v3); \ } void KisMetaDataTest::testValueCopy() { TEST_VALUE_COPY(createRationalValue); TEST_VALUE_COPY(createIntegerValue); TEST_VALUE_COPY(createStringValue); TEST_VALUE_COPY(createListValue); } void KisMetaDataTest::testEntry() { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri); Value v1 = createIntegerValue(42); Value v2 = createIntegerValue(12); Entry e(schema, "test", v1); QVERIFY(schema); QCOMPARE(e.name(), QString("test")); QCOMPARE(e.schema(), schema); QCOMPARE(e.qualifiedName(), schema->generateQualifiedName("test")); QCOMPARE(e.value(), v1); e.value() = v2; QCOMPARE(e.value(), v2); } void KisMetaDataTest::testStore() { const Schema* schema = SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::TIFFSchemaUri); QVERIFY(schema); Store s; Entry e(schema, "test", createIntegerValue()); QVERIFY(!s.containsEntry(schema, "test")); s.addEntry(e); QVERIFY(s.containsEntry(schema, "test")); QVERIFY(s.containsEntry(e.qualifiedName())); QVERIFY(s.containsEntry(KisMetaData::Schema::TIFFSchemaUri, "test")); s.removeEntry(schema, "test"); QVERIFY(!s.containsEntry(schema, "test")); Entry& e2 = s.getEntry(schema, "hello"); QVERIFY(s.containsEntry(schema, "hello")); QVERIFY(e2.name() == "hello"); QVERIFY(e2.schema() == schema); } void KisMetaDataTest::testFilters() { // Test anonymizer { Store s; const KisMetaData::Filter* filter = FilterRegistry::instance()->get("Anonymizer"); QVERIFY(filter); const KisMetaData::Schema* dcSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::DublinCoreSchemaUri); QVERIFY(dcSchema); s.addEntry(Entry(dcSchema, "contributor", Value("somevalue"))); s.addEntry(Entry(dcSchema, "creator", Value("somevalue"))); s.addEntry(Entry(dcSchema, "publisher", Value("somevalue"))); s.addEntry(Entry(dcSchema, "rights", Value("somevalue"))); const KisMetaData::Schema* psSchema = KisMetaData::SchemaRegistry::instance()->schemaFromUri(KisMetaData::Schema::PhotoshopSchemaUri); s.addEntry(Entry(psSchema, "AuthorsPosition", Value("somevalue"))); s.addEntry(Entry(psSchema, "CaptionWriter", Value("somevalue"))); s.addEntry(Entry(psSchema, "Credit", Value("somevalue"))); s.addEntry(Entry(psSchema, "City", Value("somevalue"))); s.addEntry(Entry(psSchema, "Country", Value("somevalue"))); QList filters; filters << filter; s.applyFilters(filters); QVERIFY(!s.containsEntry(dcSchema, "contributor")); QVERIFY(!s.containsEntry(dcSchema, "creator")); QVERIFY(!s.containsEntry(dcSchema, "publisher")); QVERIFY(!s.containsEntry(dcSchema, "rights")); QVERIFY(!s.containsEntry(psSchema, "AuthorsPosition")); QVERIFY(!s.containsEntry(psSchema, "CaptionWriter")); QVERIFY(!s.containsEntry(psSchema, "Credit")); QVERIFY(!s.containsEntry(psSchema, "City")); QVERIFY(!s.containsEntry(psSchema, "Country")); } } void KisMetaDataTest::testTypeInfo() { QVERIFY(TypeInfo::Private::Boolean->propertyType() == TypeInfo::BooleanType); QVERIFY(TypeInfo::Private::Boolean->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Boolean->choices().size() == 0); QVERIFY(TypeInfo::Private::Boolean->hasCorrectType(Value(true))); QVERIFY(!TypeInfo::Private::Boolean->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Boolean->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Boolean->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Integer->propertyType() == TypeInfo::IntegerType); QVERIFY(TypeInfo::Private::Integer->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Integer->choices().size() == 0); QVERIFY(!TypeInfo::Private::Integer->hasCorrectType(Value(true))); QVERIFY(TypeInfo::Private::Integer->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Integer->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Integer->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Text->propertyType() == TypeInfo::TextType); QVERIFY(TypeInfo::Private::Text->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Text->choices().size() == 0); QVERIFY(!TypeInfo::Private::Text->hasCorrectType(Value(true))); QVERIFY(!TypeInfo::Private::Text->hasCorrectType(createIntegerValue())); QVERIFY(TypeInfo::Private::Text->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Text->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Date->propertyType() == TypeInfo::DateType); QVERIFY(TypeInfo::Private::Date->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Date->choices().size() == 0); QVERIFY(TypeInfo::Private::Date->hasCorrectType(Value(QDateTime()))); QVERIFY(!TypeInfo::Private::Date->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Date->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Date->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::Rational->propertyType() == TypeInfo::RationalType); QVERIFY(TypeInfo::Private::Rational->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::Rational->choices().size() == 0); QVERIFY(TypeInfo::Private::Rational->hasCorrectType(createRationalValue())); QVERIFY(!TypeInfo::Private::Rational->hasCorrectType(createIntegerValue())); QVERIFY(!TypeInfo::Private::Rational->hasCorrectType(createStringValue())); QVERIFY(!TypeInfo::Private::Rational->hasCorrectType(createListValue())); QVERIFY(TypeInfo::Private::GPSCoordinate->propertyType() == TypeInfo::GPSCoordinateType); QVERIFY(TypeInfo::Private::GPSCoordinate->embeddedPropertyType() == 0); QVERIFY(TypeInfo::Private::GPSCoordinate->choices().size() == 0); QVERIFY(TypeInfo::Private::LangArray->propertyType() == TypeInfo::LangArrayType); QVERIFY(TypeInfo::Private::LangArray->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(TypeInfo::Private::LangArray->choices().size() == 0); // Create List of integer Value QList< Value > goodIntegerList; goodIntegerList.push_back(createIntegerValue()); goodIntegerList.push_back(createIntegerValue(12)); QList< Value > badIntegerList; badIntegerList.push_back(createIntegerValue()); badIntegerList.push_back(createStringValue()); badIntegerList.push_back(createIntegerValue(12)); // Test OrderedArray const TypeInfo* arrOA1 = TypeInfo::Private::orderedArray(TypeInfo::Private::Integer); QVERIFY(arrOA1->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(arrOA1->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(arrOA1->choices().size() == 0); QVERIFY(arrOA1 == TypeInfo::Private::orderedArray(TypeInfo::Private::Integer)); const TypeInfo* arrOA2 = TypeInfo::Private::orderedArray(TypeInfo::Private::Text); QVERIFY(arrOA1 != arrOA2); QVERIFY(arrOA2->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(!arrOA1->hasCorrectType(Value(true))); QVERIFY(!arrOA1->hasCorrectType(createIntegerValue())); QVERIFY(!arrOA1->hasCorrectType(createStringValue())); QVERIFY(!arrOA1->hasCorrectType(createListValue())); QVERIFY(arrOA1->hasCorrectType(Value(goodIntegerList, Value::OrderedArray))); QVERIFY(!arrOA1->hasCorrectType(Value(badIntegerList, Value::OrderedArray))); // Test UnarderedArray const TypeInfo* arrUOA1 = TypeInfo::Private::unorderedArray(TypeInfo::Private::Integer); QVERIFY(arrUOA1->propertyType() == TypeInfo::UnorderedArrayType); QVERIFY(arrUOA1->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(arrUOA1->choices().size() == 0); QVERIFY(arrUOA1 == TypeInfo::Private::unorderedArray(TypeInfo::Private::Integer)); const TypeInfo* arrUOA2 = TypeInfo::Private::unorderedArray(TypeInfo::Private::Text); QVERIFY(arrUOA1 != arrUOA2); QVERIFY(arrUOA2->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(arrUOA1 != arrOA1); QVERIFY(arrUOA2 != arrOA2); QVERIFY(!arrUOA1->hasCorrectType(Value(true))); QVERIFY(!arrUOA1->hasCorrectType(createIntegerValue())); QVERIFY(!arrUOA1->hasCorrectType(createStringValue())); QVERIFY(!arrUOA1->hasCorrectType(createListValue())); QVERIFY(arrUOA1->hasCorrectType(Value(goodIntegerList, Value::UnorderedArray))); QVERIFY(!arrUOA1->hasCorrectType(Value(badIntegerList, Value::UnorderedArray))); // Test AlternativeArray const TypeInfo* arrAA1 = TypeInfo::Private::alternativeArray(TypeInfo::Private::Integer); QVERIFY(arrAA1->propertyType() == TypeInfo::AlternativeArrayType); QVERIFY(arrAA1->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(arrAA1->choices().size() == 0); QVERIFY(arrAA1 == TypeInfo::Private::alternativeArray(TypeInfo::Private::Integer)); const TypeInfo* arrAA2 = TypeInfo::Private::alternativeArray(TypeInfo::Private::Text); QVERIFY(arrAA1 != arrAA2); QVERIFY(arrAA2->embeddedPropertyType() == TypeInfo::Private::Text); QVERIFY(arrAA1 != arrOA1); QVERIFY(arrAA1 != arrUOA1); QVERIFY(arrAA2 != arrOA2); QVERIFY(arrAA2 != arrUOA2); QVERIFY(!arrAA1->hasCorrectType(Value(true))); QVERIFY(!arrAA1->hasCorrectType(createIntegerValue())); QVERIFY(!arrAA1->hasCorrectType(createStringValue())); QVERIFY(!arrAA1->hasCorrectType(createListValue())); QVERIFY(arrAA1->hasCorrectType(Value(goodIntegerList, Value::AlternativeArray))); QVERIFY(!arrAA1->hasCorrectType(Value(badIntegerList, Value::AlternativeArray))); // Test Choice QList< TypeInfo::Choice > choices; choices.push_back(TypeInfo::Choice(Value(12), "Hello")); choices.push_back(TypeInfo::Choice(Value(42), "World")); const TypeInfo* oChoice = TypeInfo::Private::createChoice(TypeInfo::OpenedChoice, TypeInfo::Private::Integer, choices); QVERIFY(oChoice->propertyType() == TypeInfo::OpenedChoice); QVERIFY(oChoice->embeddedPropertyType() == TypeInfo::Private::Integer); QVERIFY(oChoice->choices().size() == 2); QVERIFY(oChoice->choices()[0].value() == Value(12)); QVERIFY(oChoice->choices()[0].hint() == "Hello"); QVERIFY(oChoice->choices()[1].value() == Value(42)); QVERIFY(oChoice->choices()[1].hint() == "World"); QVERIFY(!oChoice->hasCorrectType(Value(true))); QVERIFY(oChoice->hasCorrectType(createIntegerValue(12))); QVERIFY(oChoice->hasCorrectType(createIntegerValue(-12))); QVERIFY(oChoice->hasCorrectType(createIntegerValue(42))); QVERIFY(!oChoice->hasCorrectType(createStringValue())); QVERIFY(!oChoice->hasCorrectType(createListValue())); QVERIFY(!oChoice->hasCorrectType(Value(goodIntegerList, Value::AlternativeArray))); QVERIFY(!oChoice->hasCorrectType(Value(badIntegerList, Value::AlternativeArray))); const TypeInfo* cChoice = TypeInfo::Private::createChoice(TypeInfo::ClosedChoice, TypeInfo::Private::Integer, choices); QVERIFY(cChoice->propertyType() == TypeInfo::ClosedChoice); QVERIFY(!cChoice->hasCorrectType(Value(true))); QVERIFY(cChoice->hasCorrectType(createIntegerValue(12))); QVERIFY(cChoice->hasCorrectType(createIntegerValue(-12))); QVERIFY(cChoice->hasCorrectType(createIntegerValue(42))); QVERIFY(!cChoice->hasCorrectType(createStringValue())); QVERIFY(!cChoice->hasCorrectType(createListValue())); QVERIFY(!cChoice->hasCorrectType(Value(goodIntegerList, Value::AlternativeArray))); QVERIFY(!cChoice->hasCorrectType(Value(badIntegerList, Value::AlternativeArray))); QVERIFY(cChoice->hasCorrectValue(createIntegerValue(12))); QVERIFY(!cChoice->hasCorrectValue(createIntegerValue(-12))); QVERIFY(cChoice->hasCorrectValue(createIntegerValue(42))); // Test structure } void KisMetaDataTest::testSchemaParse() { const Schema* exifSchema = SchemaRegistry::instance()->schemaFromUri(Schema::EXIFSchemaUri); QVERIFY(exifSchema); const TypeInfo* colorSpaceType = exifSchema->propertyType("ColorSpace"); QVERIFY(colorSpaceType); QVERIFY(colorSpaceType->propertyType() == TypeInfo::ClosedChoice); QVERIFY(colorSpaceType->choices().size() == 2); QVERIFY(colorSpaceType->choices()[0].value() == Value(1)); QVERIFY(colorSpaceType->choices()[0].hint() == "sRGB"); QVERIFY(colorSpaceType->choices()[1].value() == Value(65635)); QVERIFY(colorSpaceType->choices()[1].hint() == "uncalibrated"); QVERIFY(exifSchema->propertyType("CompressedBitsPerPixel")); QVERIFY(exifSchema->propertyType("CompressedBitsPerPixel")->propertyType() == TypeInfo::RationalType); QVERIFY(exifSchema->propertyType("PixelXDimension")); QVERIFY(exifSchema->propertyType("PixelXDimension")->propertyType() == TypeInfo::IntegerType); QVERIFY(exifSchema->propertyType("UserComment")); QVERIFY(exifSchema->propertyType("UserComment")->propertyType() == TypeInfo::LangArrayType); QVERIFY(exifSchema->propertyType("RelatedSoundFile")); QVERIFY(exifSchema->propertyType("RelatedSoundFile")->propertyType() == TypeInfo::TextType); QVERIFY(exifSchema->propertyType("DateTimeOriginal")); QVERIFY(exifSchema->propertyType("DateTimeOriginal")->propertyType() == TypeInfo::DateType); QVERIFY(exifSchema->propertyType("ISOSpeedRatings")); QVERIFY(exifSchema->propertyType("ISOSpeedRatings")->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(exifSchema->propertyType("ISOSpeedRatings")->embeddedPropertyType() == TypeInfo::Private::Integer); const TypeInfo* oecfType = exifSchema->propertyType("OECF"); QVERIFY(oecfType); QVERIFY(oecfType->propertyType() == TypeInfo::StructureType); QVERIFY(oecfType == exifSchema->structure("OECFSFR")); QVERIFY(oecfType->structureName() == "OECFSFR"); QVERIFY(oecfType->structureSchema()); QVERIFY(oecfType->structureSchema()->propertyType("Columns")->propertyType() == TypeInfo::IntegerType); QVERIFY(oecfType->structureSchema()->propertyType("Rows")->propertyType() == TypeInfo::IntegerType); QVERIFY(oecfType->structureSchema()->propertyType("Names")->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(oecfType->structureSchema()->propertyType("Names")->embeddedPropertyType()->propertyType() == TypeInfo::TextType); QVERIFY(oecfType->structureSchema()->propertyType("Values")->propertyType() == TypeInfo::OrderedArrayType); QVERIFY(oecfType->structureSchema()->propertyType("Values")->embeddedPropertyType()->propertyType() == TypeInfo::RationalType); } void KisMetaDataTest::testParser() { Value intV = TypeInfo::Private::Integer->parser()->parse("1242"); QVERIFY(intV.type() == Value::Variant); QVERIFY(intV.asVariant() == 1242); QVERIFY(intV.asVariant().type() == QVariant::Int); Value textV = TypeInfo::Private::Text->parser()->parse("Bouh"); QVERIFY(textV.type() == Value::Variant); QVERIFY(textV.asVariant() == "Bouh"); QVERIFY(textV.asVariant().type() == QVariant::String); Value dateV1 = TypeInfo::Private::Date->parser()->parse("2005-10-31"); QVERIFY(dateV1.type() == Value::Variant); QDateTime d1 = dateV1.asVariant().toDateTime(); QVERIFY(d1.date().year() == 2005); QVERIFY(d1.date().month() == 10); QVERIFY(d1.date().day() == 31); Value dateV2 = TypeInfo::Private::Date->parser()->parse("2005"); QVERIFY(dateV2.type() == Value::Variant); QDateTime d2 = dateV2.asVariant().toDateTime(); QVERIFY(d2.date().year() == 2005); Value dateV3 = TypeInfo::Private::Date->parser()->parse("2005-12"); QVERIFY(dateV3.type() == Value::Variant); QDateTime d3 = dateV3.asVariant().toDateTime(); QVERIFY(d3.date().year() == 2005); QVERIFY(d3.date().month() == 12); Value dateV4 = TypeInfo::Private::Date->parser()->parse("2005-10-31T12:20"); QVERIFY(dateV4.type() == Value::Variant); QDateTime d4 = dateV4.asVariant().toDateTime(); QVERIFY(d4.date().year() == 2005); QVERIFY(d4.date().month() == 10); QVERIFY(d4.date().day() == 31); QVERIFY(d4.time().hour() == 12); QVERIFY(d4.time().minute() == 20); Value dateV5 = TypeInfo::Private::Date->parser()->parse("2005-10-31T12:20:32"); QVERIFY(dateV5.type() == Value::Variant); QDateTime d5 = dateV5.asVariant().toDateTime(); QVERIFY(d5.date().year() == 2005); QVERIFY(d5.date().month() == 10); QVERIFY(d5.date().day() == 31); QVERIFY(d5.time().hour() == 12); QVERIFY(d5.time().minute() == 20); QVERIFY(d5.time().second() == 32); - Value dateV6 = TypeInfo::Private::Date->parser()->parse("2005-10-31T12:20:32-06:00"); - QVERIFY(dateV6.type() == Value::Variant); - QDateTime d6 = dateV6.asVariant().toDateTime(); - QVERIFY(d6.date().year() == 2005); - QVERIFY(d6.date().month() == 10); - QVERIFY(d6.date().day() == 31); - QVERIFY(d6.time().hour() == 18); - QVERIFY(d6.time().minute() == 20); - QVERIFY(d6.time().second() == 32); - Value rational1 = TypeInfo::Private::Rational->parser()->parse("-10/20"); QVERIFY(rational1.type() == Value::Rational); QVERIFY(rational1.asRational().numerator == -10); QVERIFY(rational1.asRational().denominator == 20); Value rational2 = TypeInfo::Private::Rational->parser()->parse("10/20"); QVERIFY(rational2.type() == Value::Rational); QVERIFY(rational2.asRational().numerator == 10); QVERIFY(rational2.asRational().denominator == 20); } void KisMetaDataTest::testValidator() { Store store; const Schema* exif = SchemaRegistry::instance()->schemaFromUri(Schema::EXIFSchemaUri); QVERIFY(exif); store.addEntry(Entry(exif, "PixelXDimension", createIntegerValue())); store.addEntry(Entry(exif, "PixelYDimension", createIntegerValue())); store.addEntry(Entry(exif, "RelatedSoundFile", createStringValue())); store.addEntry(Entry(exif, "ColorSpace", createIntegerValue(1))); store.addEntry(Entry(exif, "ExposureTime", createRationalValue())); Validator validator(&store); QCOMPARE(validator.countInvalidEntries(), 0); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries().size(), 0); // Unknown entry store.addEntry(Entry(exif, "azerty", createIntegerValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("azerty")].type(), Validator::Reason::UNKNOWN_ENTRY); store.removeEntry(exif, "azerty"); // Invalid type for rational store.addEntry(Entry(exif, "FNumber", createIntegerValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("FNumber")].type(), Validator::Reason::INVALID_TYPE); store.removeEntry(exif, "FNumber"); // Invalid type for integer store.addEntry(Entry(exif, "SubjectLocation", createStringValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("SubjectLocation")].type(), Validator::Reason::INVALID_TYPE); store.removeEntry(exif, "SubjectLocation"); // Invalid type for choice store.addEntry(Entry(exif, "SensingMethod", createStringValue())); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("SensingMethod")].type(), Validator::Reason::INVALID_TYPE); store.removeEntry(exif, "SensingMethod"); // Invalid value for choice store.addEntry(Entry(exif, "SensingMethod", createIntegerValue(1242))); validator.revalidate(); QCOMPARE(validator.countInvalidEntries(), 1); QCOMPARE(validator.countValidEntries(), 5); QCOMPARE(validator.invalidEntries()[ exif->generateQualifiedName("SensingMethod")].type(), Validator::Reason::INVALID_VALUE); store.removeEntry(exif, "SensingMethod"); } KISTEST_MAIN(KisMetaDataTest)