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
38class tst_QGetPutEnv : public QObject
39{
40Q_OBJECT
41private slots:
42 void getSetCheck();
43 void encoding();
44 void intValue_data();
45 void intValue();
46};
47
48void 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
122void 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
155void 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
205void 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
229QTEST_MAIN(tst_QGetPutEnv)
230#include "tst_qgetputenv.moc"
231

source code of qtbase/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp