| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Copyright (C) 2016 Intel Corporation. | 
| 5 | ** Contact: https://www.qt.io/licensing/ | 
| 6 | ** | 
| 7 | ** This file is part of the test suite of the Qt Toolkit. | 
| 8 | ** | 
| 9 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ | 
| 10 | ** Commercial License Usage | 
| 11 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 12 | ** accordance with the commercial license agreement provided with the | 
| 13 | ** Software or, alternatively, in accordance with the terms contained in | 
| 14 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 15 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 16 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 17 | ** | 
| 18 | ** GNU General Public License Usage | 
| 19 | ** Alternatively, this file may be used under the terms of the GNU | 
| 20 | ** General Public License version 3 as published by the Free Software | 
| 21 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
| 22 | ** included in the packaging of this file. Please review the following | 
| 23 | ** information to ensure the GNU General Public License requirements will | 
| 24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 25 | ** | 
| 26 | ** $QT_END_LICENSE$ | 
| 27 | ** | 
| 28 | ****************************************************************************/ | 
| 29 |  | 
| 30 | #include <qdebug.h> | 
| 31 | #include <QtTest/QtTest> | 
| 32 |  | 
| 33 | #include <qglobal.h> | 
| 34 | #ifdef Q_OS_WIN | 
| 35 | #include <qt_windows.h> | 
| 36 | #endif | 
| 37 |  | 
| 38 | class tst_QGetPutEnv : public QObject | 
| 39 | { | 
| 40 | Q_OBJECT | 
| 41 | private slots: | 
| 42 |     void getSetCheck(); | 
| 43 |     void encoding(); | 
| 44 |     void intValue_data(); | 
| 45 |     void intValue(); | 
| 46 | }; | 
| 47 |  | 
| 48 | void tst_QGetPutEnv::getSetCheck() | 
| 49 | { | 
| 50 |     const char varName[] = "should_not_exist" ; | 
| 51 |  | 
| 52 |     bool ok; | 
| 53 |  | 
| 54 |     QVERIFY(!qEnvironmentVariableIsSet(varName)); | 
| 55 |     QVERIFY(qEnvironmentVariableIsEmpty(varName)); | 
| 56 |     ok = true; | 
| 57 |     QCOMPARE(qEnvironmentVariableIntValue(varName), 0); | 
| 58 |     QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); | 
| 59 |     QVERIFY(!ok); | 
| 60 |     QByteArray result = qgetenv(varName); | 
| 61 |     QVERIFY(result.isNull()); | 
| 62 |     QString sresult = qEnvironmentVariable(varName); | 
| 63 |     QVERIFY(sresult.isNull()); | 
| 64 |     sresult = qEnvironmentVariable(varName, defaultValue: "hello" ); | 
| 65 |     QCOMPARE(sresult, QString("hello" )); | 
| 66 |  | 
| 67 | #ifndef Q_OS_WIN | 
| 68 |     QVERIFY(qputenv(varName, "" )); // deletes varName instead of making it empty, on Windows | 
| 69 |  | 
| 70 |     QVERIFY(qEnvironmentVariableIsSet(varName)); | 
| 71 |     QVERIFY(qEnvironmentVariableIsEmpty(varName)); | 
| 72 |     ok = true; | 
| 73 |     QCOMPARE(qEnvironmentVariableIntValue(varName), 0); | 
| 74 |     QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); | 
| 75 |     QVERIFY(!ok); | 
| 76 |  | 
| 77 |     result = qgetenv(varName); | 
| 78 |     QVERIFY(!result.isNull()); | 
| 79 |     QCOMPARE(result, QByteArray()); | 
| 80 |     sresult = qEnvironmentVariable(varName); | 
| 81 |     QVERIFY(!sresult.isNull()); | 
| 82 |     QCOMPARE(sresult, QString()); | 
| 83 |     sresult = qEnvironmentVariable(varName, defaultValue: "hello" ); | 
| 84 |     QVERIFY(!sresult.isNull()); | 
| 85 |     QCOMPARE(sresult, QString()); | 
| 86 | #endif | 
| 87 |  | 
| 88 |     QVERIFY(qputenv(varName, QByteArray("supervalue" ))); | 
| 89 |  | 
| 90 |     QVERIFY(qEnvironmentVariableIsSet(varName)); | 
| 91 |     QVERIFY(!qEnvironmentVariableIsEmpty(varName)); | 
| 92 |     ok = true; | 
| 93 |     QCOMPARE(qEnvironmentVariableIntValue(varName), 0); | 
| 94 |     QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); | 
| 95 |     QVERIFY(!ok); | 
| 96 |     result = qgetenv(varName); | 
| 97 |     QCOMPARE(result, QByteArrayLiteral("supervalue" )); | 
| 98 |     sresult = qEnvironmentVariable(varName); | 
| 99 |     QCOMPARE(sresult, QString("supervalue" )); | 
| 100 |     sresult = qEnvironmentVariable(varName, defaultValue: "hello" ); | 
| 101 |     QCOMPARE(sresult, QString("supervalue" )); | 
| 102 |  | 
| 103 |     qputenv(varName,value: QByteArray()); | 
| 104 |  | 
| 105 |     // Now test qunsetenv | 
| 106 |     QVERIFY(qunsetenv(varName)); | 
| 107 |     QVERIFY(!qEnvironmentVariableIsSet(varName)); // note: might fail on some systems! | 
| 108 |     QVERIFY(qEnvironmentVariableIsEmpty(varName)); | 
| 109 |     ok = true; | 
| 110 |     QCOMPARE(qEnvironmentVariableIntValue(varName), 0); | 
| 111 |     QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0); | 
| 112 |     QVERIFY(!ok); | 
| 113 |  | 
| 114 |     result = qgetenv(varName); | 
| 115 |     QVERIFY(result.isNull()); | 
| 116 |     sresult = qEnvironmentVariable(varName); | 
| 117 |     QVERIFY(sresult.isNull()); | 
| 118 |     sresult = qEnvironmentVariable(varName, defaultValue: "hello" ); | 
| 119 |     QCOMPARE(sresult, QString("hello" )); | 
| 120 | } | 
| 121 |  | 
| 122 | void tst_QGetPutEnv::encoding() | 
| 123 | { | 
| 124 |     // The test string is: | 
| 125 |     //  U+0061      LATIN SMALL LETTER A | 
| 126 |     //  U+00E1      LATIN SMALL LETTER A WITH ACUTE | 
| 127 |     //  U+03B1      GREEK SMALL LETTER ALPHA | 
| 128 |     //  U+0430      CYRILLIC SMALL LETTER A | 
| 129 |     // This has letters in three different scripts, so no locale besides | 
| 130 |     // UTF-8 is able handle them all. | 
| 131 |     // The LATIN SMALL LETTER A WITH ACUTE is NFC for NFD: | 
| 132 |     //  U+0061 U+0301   LATIN SMALL LETTER A + COMBINING ACUTE ACCENT | 
| 133 |  | 
| 134 |     const char varName[] = "should_not_exist" ; | 
| 135 |     static const wchar_t rawvalue[] = { 'a', 0x00E1, 0x03B1, 0x0430, 0 }; | 
| 136 |     QString value = QString::fromWCharArray(string: rawvalue); | 
| 137 |  | 
| 138 | #if defined(Q_OS_WINRT) | 
| 139 |     QSKIP("Test cannot be run on this platform" ); | 
| 140 | #elif defined(Q_OS_WIN) | 
| 141 |     const wchar_t wvarName[] = L"should_not_exist" ; | 
| 142 |     _wputenv_s(wvarName, rawvalue); | 
| 143 | #else | 
| 144 |     // confirm the locale is UTF-8 | 
| 145 |     if (value.toLocal8Bit() != "a\xc3\xa1\xce\xb1\xd0\xb0" ) | 
| 146 |         QSKIP("Locale is not UTF-8, cannot test" ); | 
| 147 |  | 
| 148 |     qputenv(varName, value: QFile::encodeName(fileName: value)); | 
| 149 | #endif | 
| 150 |  | 
| 151 |     QVERIFY(qEnvironmentVariableIsSet(varName)); | 
| 152 |     QCOMPARE(qEnvironmentVariable(varName), value); | 
| 153 | } | 
| 154 |  | 
| 155 | void tst_QGetPutEnv::intValue_data() | 
| 156 | { | 
| 157 |     QTest::addColumn<QByteArray>(name: "value" ); | 
| 158 |     QTest::addColumn<int>(name: "expected" ); | 
| 159 |     QTest::addColumn<bool>(name: "ok" ); | 
| 160 |  | 
| 161 |     // some repetition from what is tested in getSetCheck() | 
| 162 |     QTest::newRow(dataTag: "empty" ) << QByteArray() << 0 << false; | 
| 163 |     QTest::newRow(dataTag: "spaces-heading" ) << QByteArray(" \n\r\t1" ) << 1 << true; | 
| 164 |     QTest::newRow(dataTag: "spaces-trailing" ) << QByteArray("1 \n\r\t" ) << 1 << true; | 
| 165 |     QTest::newRow(dataTag: "junk-heading" ) << QByteArray("x1" ) << 0 << false; | 
| 166 |     QTest::newRow(dataTag: "junk-trailing" ) << QByteArray("1x" ) << 0 << false; | 
| 167 |  | 
| 168 | #define ROW(x, i, b) \ | 
| 169 |     QTest::newRow(#x) << QByteArray(#x) << (i) << (b) | 
| 170 |     ROW(auto, 0, false); | 
| 171 |     ROW(1auto, 0, false); | 
| 172 |     ROW(0, 0, true); | 
| 173 |     ROW(+0, 0, true); | 
| 174 |     ROW(1, 1, true); | 
| 175 |     ROW(+1, 1, true); | 
| 176 |     ROW(09, 0, false); | 
| 177 |     ROW(010, 8, true); | 
| 178 |     ROW(0x10, 16, true); | 
| 179 |     ROW(0x, 0, false); | 
| 180 |     ROW(0xg, 0, false); | 
| 181 |     ROW(0x1g, 0, false); | 
| 182 |     ROW(000000000000000000000000000000000000000000000000001, 0, false); | 
| 183 |     ROW(+000000000000000000000000000000000000000000000000001, 0, false); | 
| 184 |     ROW(000000000000000000000000000000000000000000000000001g, 0, false); | 
| 185 |     ROW(-0, 0, true); | 
| 186 |     ROW(-1, -1, true); | 
| 187 |     ROW(-010, -8, true); | 
| 188 |     ROW(-000000000000000000000000000000000000000000000000001, 0, false); | 
| 189 |     ROW(2147483648, 0, false); | 
| 190 |     // ROW(0xffffffff, -1, true); // could be expected, but not how QByteArray::toInt() works | 
| 191 |     ROW(0xffffffff, 0, false); | 
| 192 |     const int bases[] = {10, 8, 16}; | 
| 193 |     for (size_t i = 0; i < sizeof bases / sizeof *bases; ++i) { | 
| 194 |         QTest::addRow(format: "INT_MAX, base %d" , bases[i]) | 
| 195 |                 << QByteArray::number(INT_MAX) << INT_MAX << true; | 
| 196 |         QTest::addRow(format: "INT_MAX+1, base %d" , bases[i]) | 
| 197 |                 << QByteArray::number(qlonglong(INT_MAX) + 1) << 0 << false; | 
| 198 |         QTest::addRow(format: "INT_MIN, base %d" , bases[i]) | 
| 199 |                 << QByteArray::number(INT_MIN) << INT_MIN << true; | 
| 200 |         QTest::addRow(format: "INT_MIN-1, base %d" , bases[i]) | 
| 201 |                 << QByteArray::number(qlonglong(INT_MIN) - 1) << 0 << false; | 
| 202 |     }; | 
| 203 | } | 
| 204 |  | 
| 205 | void tst_QGetPutEnv::intValue() | 
| 206 | { | 
| 207 |     const int maxlen = (sizeof(int) * CHAR_BIT + 2) / 3; | 
| 208 |     const char varName[] = "should_not_exist" ; | 
| 209 |  | 
| 210 |     QFETCH(QByteArray, value); | 
| 211 |     QFETCH(int, expected); | 
| 212 |     QFETCH(bool, ok); | 
| 213 |  | 
| 214 |     bool actualOk = !ok; | 
| 215 |  | 
| 216 |     // Self-test: confirm that it was like the docs said it should be | 
| 217 |     if (value.length() < maxlen) { | 
| 218 |         QCOMPARE(value.toInt(&actualOk, 0), expected); | 
| 219 |         QCOMPARE(actualOk, ok); | 
| 220 |     } | 
| 221 |  | 
| 222 |     actualOk = !ok; | 
| 223 |     QVERIFY(qputenv(varName, value)); | 
| 224 |     QCOMPARE(qEnvironmentVariableIntValue(varName), expected); | 
| 225 |     QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), expected); | 
| 226 |     QCOMPARE(actualOk, ok); | 
| 227 | } | 
| 228 |  | 
| 229 | QTEST_MAIN(tst_QGetPutEnv) | 
| 230 | #include "tst_qgetputenv.moc" | 
| 231 |  |