1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* ============================================================
 *
 * This file is a part of digiKam project
 * https://www.digikam.org
 *
 * Date        : 2022-10-10
 * Description : Common class to provides convenient access to digiKam
 *               test data directories and files.
 *
 * SPDX-FileCopyrightText: 2022 Steve Robbins <steve at sumost dot ca>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * ============================================================ */

#pragma once

// Qt includes

#include <QDir>

/**
 * @brief Class that provides convenient access to digiKam test data directories and files.
 *
 * When instantiated, the test-data directory is located dynamically; this algorithm works as long as
 * the current directory is the source root directory or any sub-directory.  After construction,
 * the function \ref isValid returns true if the test data was successfully located.
 */

class DTestDataDir
{
public:

    /**
     * True if the instance is correctly instantiated.
     * Valid means that the desired root directory was located.
     */
    bool isValid() const
    {
        return m_isValid;
    }

    /**
     * Root directory of test data hierarchy.
     */
    QDir root() const
    {
        return m_testDataDir;
    }

    /**
     * Path to any test file or directory, specified using relative path from root.
     */
    QString path(const QString& name) const
    {
        return root().filePath(name);
    }

    /**
     * Any test directory, specified using relative path from root.
     */
    QDir dir(const QString& relPath) const<--- Shadowed declaration
    {
        return QDir(path(relPath));
    }

    /**
     * Any test file, specified using relative path from root.
     */
    QFile file(const QString& name) const
    {
        return QFile(path(name));
    }

    /**
     * Returns DTestDataDir for the digiKam Test Data root directory.
     * This provides access to all files in Digikam Test Data.
     */
    static DTestDataDir TestDataRoot()
    {
        return DTestDataDir();
    }

    /**
     * Returns DTestDataDir for a sub-tree of the digiKam Test Data.
     * This provides access to files in the subtree.
     *
     * \param subdirPath path of subdir, relative to the Digikam Test Data root
     */
    static DTestDataDir TestData(const QString& subdirPath)
    {
        return DTestDataDir(subdirPath);
    }

private:

    QDir m_testDataDir;
    bool m_isValid = false;

private:

    static bool s_findDirectoryUpwards(const QDir& directory, const QString& target, QDir& result)
    {
        QDir dir = directory;<--- Shadow variable

        while (dir.exists(target) == false)
        {
            if (!dir.cdUp())
            {
                return false;
            }
        }

        if (!dir.cd(target))
        {
            return false;
        }

        result = dir;

        return true;
    }

    void initialize()
    {
        m_isValid = s_findDirectoryUpwards(QDir(), QString::fromUtf8("test-data"), m_testDataDir);
    }

protected:

    /**
     * Constructor with internal instance creation.
     */
    DTestDataDir()
    {
        initialize();
    }

    explicit DTestDataDir(const QString& subdirPath)
    {
        initialize();

        if (!m_isValid)
        {
            return;
        }

        m_isValid = m_testDataDir.exists(subdirPath);

        if (!m_isValid)
        {
            return;
        }

        bool b = m_testDataDir.cd(subdirPath);

        Q_UNUSED(b);
    }
};