File indexing completed on 2024-05-19 04:39:58

0001 /*
0002     SPDX-FileCopyrightText: 2015 Artur Puzio <cytadela88@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "test_environment.h"
0008 
0009 #include "util/environmentprofilelist.h"
0010 
0011 #include <QTest>
0012 #include <QProcessEnvironment>
0013 #include <QStandardPaths>
0014 
0015 QTEST_MAIN(TestEnvironment)
0016 
0017 using ProcEnv = QMap<QString, QString>;
0018 
0019 void TestEnvironment::initTestCase()
0020 {
0021     QStandardPaths::setTestModeEnabled(true);
0022 }
0023 
0024 void TestEnvironment::testExpandVariables_data()
0025 {
0026     QTest::addColumn<ProcEnv>("env");
0027     QTest::addColumn<ProcEnv>("expectedEnv");
0028 
0029     QTest::newRow("no variables") << ProcEnv({}) << ProcEnv({});
0030     QTest::newRow("simple variables") << ProcEnv{
0031         {"VAR1", "data"},
0032         {"Var2", "some other data"}
0033         } << ProcEnv({
0034         {"VAR1", "data"},
0035         {"Var2", "some other data"}
0036     });
0037     QTest::newRow("PATH append and prepend") << ProcEnv({
0038         {"PATH", "/home/usr/bin:$PATH:/home/user/folder"}
0039     }) << ProcEnv({
0040         {"PATH", "/home/usr/bin:/bin:/usr/bin:/home/user/folder"}
0041     });
0042     QTest::newRow("\\$VAR") << ProcEnv({
0043         {"MY_VAR", "\\$PATH something \\$HOME"}
0044     }) << ProcEnv({
0045         {"MY_VAR", "$PATH something $HOME"}
0046     });
0047     QTest::newRow("spaces, \\$VAR after $VAR") << ProcEnv({
0048         {"MY_VAR", "$PATH:$HOME something \\$HOME"}
0049     }) << ProcEnv({
0050         {"MY_VAR", "/bin:/usr/bin:/home/tom something $HOME"}
0051     });
0052     QTest::newRow("VAR2=$VAR1") << ProcEnv({
0053         {"VAR1", "/some/path"}, {"VAR2", "$VAR1"}
0054     }) << ProcEnv({
0055         {"VAR1", "/some/path"}, {"VAR2", "/some/path"}
0056     });
0057      QTest::newRow("expanding with not yet expanded variable") << ProcEnv({
0058         {"VAR1", "$VAR2"}, {"VAR2", "$PATH"}
0059     }) << ProcEnv({
0060         {"VAR1", "/bin:/usr/bin"}, {"VAR2", "/bin:/usr/bin"}
0061     });
0062     QTest::newRow("adding to a variable not in the environment") << ProcEnv({
0063         {"VAR1", "data:$VAR1"}
0064     }) << ProcEnv({
0065         {"VAR1", "data:"}
0066     });
0067     QTest::newRow("cycle") << ProcEnv({
0068         {"VAR1", "$VAR2"},
0069         {"VAR2", "/usr/$VAR2"}
0070     }) << ProcEnv({
0071         {"VAR1", "/usr/"},
0072         {"VAR2", "/usr/"}
0073     });
0074     QTest::newRow("order") << ProcEnv({
0075         {"VAR1", "$VAR3"},
0076         {"VAR2", "foo"},
0077         {"VAR3", "$VAR2"},
0078     }) << ProcEnv({
0079         {"VAR1", "foo"},
0080         {"VAR2", "foo"},
0081         {"VAR3", "foo"},
0082     });
0083     QTest::newRow("escaped backslash before dollar") << ProcEnv({
0084         {"var1", "\\\\$var2"},
0085         {"var2", "x"},
0086     }) << ProcEnv({
0087         {"var1", "\\x"},
0088         {"var2", "x"},
0089     });
0090     QTest::newRow("non-escaping backslashes") << ProcEnv({
0091         {"var1", "\\abc\\def\\"},
0092     }) << ProcEnv({
0093         {"var1", "\\abc\\def\\"},
0094     });
0095     QTest::newRow("verbatim dollars") << ProcEnv({
0096         {"var1", "a\\$b$.$\\c$"},
0097     }) << ProcEnv({
0098         {"var1", "a$b$.$\\c$"},
0099     });
0100     QTest::newRow("expansion priority") << ProcEnv({
0101         {"A", "$PATH"},
0102         {"HOME", "my$HOME"},
0103         {"PATH", "."},
0104         {"X", "$A$HOME$Z"},
0105         {"Z", "-$PATH+"},
0106     }) << ProcEnv({
0107         {"A", "/bin:/usr/bin"},
0108         {"HOME", "my/home/tom"},
0109         {"PATH", "."},
0110         {"X", "/bin:/usr/bin/home/tom-/bin:/usr/bin+"},
0111         {"Z", "-/bin:/usr/bin+"},
0112     });
0113 
0114     QTest::newRow("braced variable") << ProcEnv({
0115         {"u", "${PATH}"},
0116     }) << ProcEnv({
0117         {"u", "/bin:/usr/bin"},
0118     });
0119     QTest::newRow("braced variables") << ProcEnv({
0120         {"u", "${PATH}${vw}"},
0121         {"vw", "${MISSING_VAR}/w"},
0122     }) << ProcEnv({
0123         {"u", "/bin:/usr/bin/w"},
0124         {"vw", "/w"},
0125     });
0126     QTest::newRow("braced non-variables") << ProcEnv({
0127         {"u", "\\${PATH}${v.w}{u}"},
0128         {"w", "$ {PATH}/${:} {}-${} ${2}"},
0129     }) << ProcEnv({
0130         {"u", "${PATH}${v.w}{u}"},
0131         {"w", "$ {PATH}/${:} {}-${} ${2}"},
0132     });
0133 
0134     // The mutual recursion tests below process unreasonable input. The purpose
0135     // of these tests is to verify that KDevelop does not crash or hang with
0136     // such input. The actual results are unimportant.
0137     QTest::newRow("mutual recursion") << ProcEnv({
0138         {"VAR1", "$VAR2"},
0139         {"VAR2", "$VAR1"},
0140     }) << ProcEnv({
0141         {"VAR1", ""},
0142         {"VAR2", ""},
0143     });
0144     QTest::newRow("mutual recursion - prefix") << ProcEnv({
0145         {"VAR1", "/bin/$VAR2"},
0146         {"VAR2", "/usr/$VAR1"},
0147     }) << ProcEnv({
0148         {"VAR1", "/bin//usr//bin/"},
0149         {"VAR2", "/usr//bin/"},
0150     });
0151     QTest::newRow("mutual recursion - suffix") << ProcEnv({
0152         {"VAR1", "$VAR2/"},
0153         {"VAR2", "$VAR1."},
0154     }) << ProcEnv({
0155         {"VAR1", "./"},
0156         {"VAR2", "."},
0157     });
0158     QTest::newRow("mutual recursion - middle") << ProcEnv({
0159         {"VAR1", "a$VAR2."},
0160         {"VAR2", "b$VAR1,"},
0161     }) << ProcEnv({
0162         {"VAR1", "aba,."},
0163         {"VAR2", "ba,"},
0164     });
0165     QTest::newRow("3-way recursion") << ProcEnv({
0166         {"a", "1$b-2"},
0167         {"b", "3$c-4"},
0168         {"c", "5$a-6"},
0169     }) << ProcEnv({
0170         {"a", "1351-6-4-2"},
0171         {"b", "351-6-4"},
0172         {"c", "51-6"},
0173     });
0174 }
0175 
0176 void TestEnvironment::testExpandVariables()
0177 {
0178     QFETCH(ProcEnv, env);
0179     QFETCH(ProcEnv, expectedEnv);
0180 
0181     QProcessEnvironment fakeSysEnv;
0182     fakeSysEnv.insert(QStringLiteral("PATH"), QStringLiteral("/bin:/usr/bin"));
0183     fakeSysEnv.insert(QStringLiteral("HOME"), QStringLiteral("/home/tom"));
0184 
0185     KDevelop::expandVariables(env, fakeSysEnv);
0186 
0187     for (auto it = expectedEnv.cbegin(); it != expectedEnv.cend(); ++it) {
0188         QCOMPARE(env.value(it.key()), it.value());
0189     }
0190 }
0191 
0192 #include "moc_test_environment.cpp"