File indexing completed on 2024-12-08 10:17:13

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 // First included header is the public header of the class we are testing;
0005 // this forces the header to be self-contained.
0006 #include "iohandlerfactory.h"
0007 
0008 #include "lcms2_plugin.h"
0009 #include <lcms2.h>
0010 #include <qbytearray.h>
0011 #include <qglobal.h>
0012 #include <qobject.h>
0013 #include <qscopedpointer.h>
0014 #include <qstring.h>
0015 #include <qstringliteral.h>
0016 #include <qtemporaryfile.h>
0017 #include <qtest.h>
0018 #include <qtestcase.h>
0019 
0020 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0021 #include <qtmetamacros.h>
0022 #else
0023 #include <qobjectdefs.h>
0024 #endif
0025 
0026 namespace PerceptualColor
0027 {
0028 class TestIOHandlerFactory : public QObject
0029 {
0030     Q_OBJECT
0031 
0032 public:
0033     explicit TestIOHandlerFactory(QObject *parent = nullptr)
0034         : QObject(parent)
0035     {
0036     }
0037 
0038 private:
0039     static void voidMessageHandler(QtMsgType, const QMessageLogContext &, const QString &)
0040     {
0041         // dummy message handler that does not print messages
0042     }
0043 
0044 private Q_SLOTS:
0045     void initTestCase()
0046     {
0047         // Called before the first test function is executed
0048     }
0049 
0050     void cleanupTestCase()
0051     {
0052         // Called after the last test function was executed
0053     }
0054 
0055     void init()
0056     {
0057         // Called before each test function is executed
0058     }
0059 
0060     void cleanup()
0061     {
0062         // Called after every test function
0063     }
0064 
0065     void testExistingFile()
0066     {
0067         QScopedPointer<QTemporaryFile> testFile(
0068             // Create a temporary actual file…
0069             QTemporaryFile::createNativeFile(
0070                 // …from the content of this resource:
0071                 QStringLiteral(":/testbed/ascii-abcd.txt")));
0072         if (testFile.isNull()) {
0073             throw 0;
0074         }
0075         cmsIOHANDLER *myHandler = IOHandlerFactory::createReadOnly( //
0076             nullptr,
0077             testFile->fileName());
0078 
0079         QVERIFY(myHandler != nullptr);
0080         QCOMPARE(myHandler->ContextID, nullptr);
0081         QCOMPARE(myHandler->ReportedSize, 4);
0082         QCOMPARE(myHandler->UsedSpace, 0);
0083         // We do not check neither “stream” (implicitly covered by other
0084         // tests) nor ”PhysicalFile” (an unused implementation detail).
0085 
0086         QByteArray myByteArray(5, ' '); // Array of 5 bytes, each with value 0x00
0087         cmsUInt32Number readResult;
0088         cmsBool seekResult;
0089         cmsBool closeResult;
0090         cmsBool writeResult;
0091 
0092         myByteArray.fill(' ');
0093         readResult = myHandler->Read(myHandler, myByteArray.data(), 1, 2);
0094         QCOMPARE(readResult, 2);
0095         QCOMPARE(myByteArray, QByteArrayLiteral("ab   "));
0096         QCOMPARE(myHandler->Tell(myHandler), 2);
0097 
0098         myByteArray.fill(' ');
0099         readResult = myHandler->Read(myHandler, myByteArray.data(), 1, 2);
0100         QCOMPARE(readResult, 2);
0101         QCOMPARE(myByteArray, QByteArrayLiteral("cd   "));
0102         QCOMPARE(myHandler->Tell(myHandler), 4);
0103 
0104         myByteArray.fill(' ');
0105         QCOMPARE(myHandler->Tell(myHandler), 4); // Assertion
0106         // We are at the end of the file. The following read should not work:
0107         qInstallMessageHandler(voidMessageHandler); // suppress warnings
0108         readResult = myHandler->Read(myHandler, myByteArray.data(), 1, 2);
0109         qInstallMessageHandler(nullptr); // do not suppress warning anymore
0110         QCOMPARE(readResult, 0);
0111         QCOMPARE(myByteArray, QByteArrayLiteral("     "));
0112         QCOMPARE(myHandler->Tell(myHandler), 4);
0113 
0114         myByteArray.fill(' ');
0115         seekResult = myHandler->Seek(myHandler, 1);
0116         QCOMPARE(seekResult, true);
0117         readResult = myHandler->Read(myHandler, myByteArray.data(), 1, 2);
0118         QCOMPARE(readResult, 2);
0119         QCOMPARE(myByteArray, QByteArrayLiteral("bc   "));
0120         QCOMPARE(myHandler->Tell(myHandler), 3);
0121 
0122         myByteArray.fill(' ');
0123         seekResult = myHandler->Seek(myHandler, 1);
0124         QCOMPARE(seekResult, true);
0125         readResult = myHandler->Read(myHandler, myByteArray.data(), 1, 2);
0126         QCOMPARE(readResult, 2);
0127         QCOMPARE(myByteArray, QByteArrayLiteral("bc   "));
0128         QCOMPARE(myHandler->Tell(myHandler), 3);
0129 
0130         myByteArray.fill(' ');
0131         seekResult = myHandler->Seek(myHandler, 1);
0132         QCOMPARE(seekResult, true);
0133         QCOMPARE(myHandler->Tell(myHandler), 1);
0134         myHandler->Seek(myHandler, 8); // Out-of-range
0135         qInstallMessageHandler(voidMessageHandler); // suppress warnings
0136         readResult = myHandler->Read(myHandler, myByteArray.data(), 1, 2);
0137         qInstallMessageHandler(nullptr); // do not suppress warning anymore
0138         QCOMPARE(readResult, 0);
0139         QCOMPARE(myByteArray, QByteArrayLiteral("     "));
0140 
0141         myByteArray.fill('x');
0142         myHandler->Seek(myHandler, 1);
0143         QCOMPARE(myHandler->Tell(myHandler), 1); // Assertion
0144         writeResult = myHandler->Write(myHandler, 2, myByteArray.data());
0145         QCOMPARE(writeResult, false);
0146         QCOMPARE(myHandler->Tell(myHandler), 1);
0147 
0148         closeResult = myHandler->Close(myHandler);
0149         QCOMPARE(closeResult, true);
0150     }
0151 
0152     void testNonExisting()
0153     {
0154         const cmsIOHANDLER *myHandler = IOHandlerFactory::createReadOnly( //
0155             nullptr,
0156             QStringLiteral("../testbed/nonexistingname"));
0157         QVERIFY(myHandler == nullptr);
0158     }
0159 
0160     void testDirectory1()
0161     {
0162         const cmsIOHANDLER *myHandler = IOHandlerFactory::createReadOnly( //
0163             nullptr,
0164             // Try the name of a directory with trailing /
0165             QStringLiteral("../testbed/"));
0166         QVERIFY(myHandler == nullptr);
0167     }
0168 
0169     void testDirectory2()
0170     {
0171         const cmsIOHANDLER *myHandler = IOHandlerFactory::createReadOnly( //
0172             nullptr,
0173             // Try the name of a directory without trailing /
0174             QStringLiteral("../testbed"));
0175         QVERIFY(myHandler == nullptr);
0176     }
0177 };
0178 
0179 } // namespace PerceptualColor
0180 
0181 QTEST_MAIN(PerceptualColor::TestIOHandlerFactory)
0182 
0183 // The following “include” is necessary because we do not use a header file:
0184 #include "testiohandlerfactory.moc"