kshelltest.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. This file is part of the KDE libraries
  3. SPDX-FileCopyrightText: 2003, 2007-2008 Oswald Buddenhagen <ossi@kde.org>
  4. SPDX-FileCopyrightText: 2005 Thomas Braxton <brax108@cox.net>
  5. SPDX-License-Identifier: LGPL-2.0-only
  6. */
  7. #include <kshell.h>
  8. #include <kuser.h>
  9. #include <QTest>
  10. #include <QDir>
  11. #include <QObject>
  12. #include <QString>
  13. #include <QStringList>
  14. class KShellTest : public QObject
  15. {
  16. Q_OBJECT
  17. private Q_SLOTS:
  18. void tildeExpand();
  19. void tildeCollapse();
  20. void quoteArg();
  21. void joinArgs();
  22. void splitJoin();
  23. void quoteSplit();
  24. void quoteSplit_data();
  25. void abortOnMeta();
  26. };
  27. // The expansion of ~me isn't exactly QDir::homePath(), in case $HOME has a trailing slash, it's kept.
  28. static QString myHomePath()
  29. {
  30. #ifdef Q_OS_WIN
  31. return QDir::homePath();
  32. #else
  33. return QString::fromLocal8Bit(qgetenv("HOME"));
  34. #endif
  35. }
  36. void KShellTest::tildeExpand()
  37. {
  38. QString me(KUser().loginName());
  39. QCOMPARE(KShell::tildeExpand(QStringLiteral("~")), QDir::homePath());
  40. QCOMPARE(KShell::tildeExpand(QStringLiteral("~/dir")), QString(QDir::homePath() + QStringLiteral("/dir")));
  41. QCOMPARE(KShell::tildeExpand(QLatin1Char('~') + me), myHomePath());
  42. QCOMPARE(KShell::tildeExpand(QLatin1Char('~') + me + QStringLiteral("/dir")), QString(myHomePath() + QStringLiteral("/dir")));
  43. #ifdef Q_OS_WIN
  44. QCOMPARE(KShell::tildeExpand(QStringLiteral("^~") + me), QString(QLatin1Char('~') + me));
  45. #else
  46. QCOMPARE(KShell::tildeExpand(QStringLiteral("\\~") + me), QString(QStringLiteral("~") + me));
  47. #endif
  48. }
  49. void KShellTest::tildeCollapse()
  50. {
  51. QCOMPARE(KShell::tildeCollapse(QDir::homePath()), QStringLiteral("~"));
  52. QCOMPARE(KShell::tildeCollapse(QDir::homePath() + QStringLiteral("/Documents")), QStringLiteral("~/Documents"));
  53. QCOMPARE(KShell::tildeCollapse(QStringLiteral("/test/") + QDir::homePath()), QStringLiteral("/test/") + QDir::homePath());
  54. }
  55. void KShellTest::quoteArg()
  56. {
  57. #ifdef Q_OS_WIN
  58. QCOMPARE(KShell::quoteArg(QStringLiteral("a space")), QStringLiteral("\"a space\""));
  59. QCOMPARE(KShell::quoteArg(QStringLiteral("fds\\\"")), QStringLiteral("fds\\\\\\^\""));
  60. QCOMPARE(KShell::quoteArg(QStringLiteral("\\\\foo")), QStringLiteral("\\\\foo"));
  61. QCOMPARE(KShell::quoteArg(QStringLiteral("\"asdf\"")), QStringLiteral("\\^\"asdf\\^\""));
  62. QCOMPARE(KShell::quoteArg(QStringLiteral("with\\")), QStringLiteral("\"with\\\\\""));
  63. QCOMPARE(KShell::quoteArg(QStringLiteral("\\\\")), QStringLiteral("\"\\\\\\\\\""));
  64. QCOMPARE(KShell::quoteArg(QStringLiteral("\"a space\\\"")), QStringLiteral("\\^\"\"a space\"\\\\\\^\""));
  65. QCOMPARE(KShell::quoteArg(QStringLiteral("as df\\")), QStringLiteral("\"as df\\\\\""));
  66. QCOMPARE(KShell::quoteArg(QStringLiteral("foo bar\"\\\"bla")), QStringLiteral("\"foo bar\"\\^\"\\\\\\^\"\"bla\""));
  67. QCOMPARE(KShell::quoteArg(QStringLiteral("a % space")), QStringLiteral("\"a %PERCENT_SIGN% space\""));
  68. #else
  69. QCOMPARE(KShell::quoteArg(QStringLiteral("a space")), QStringLiteral("'a space'"));
  70. #endif
  71. }
  72. void KShellTest::joinArgs()
  73. {
  74. QStringList list;
  75. list << QStringLiteral("this") << QStringLiteral("is") << QStringLiteral("a") << QStringLiteral("test");
  76. QCOMPARE(KShell::joinArgs(list), QStringLiteral("this is a test"));
  77. }
  78. static QString sj(const QString &str, KShell::Options flags, KShell::Errors *ret)
  79. {
  80. return KShell::joinArgs(KShell::splitArgs(str, flags, ret));
  81. }
  82. void KShellTest::splitJoin()
  83. {
  84. KShell::Errors err = KShell::NoError;
  85. #ifdef Q_OS_WIN
  86. QCOMPARE(sj(QStringLiteral("\"(sulli)\" text"), KShell::NoOptions, &err), QStringLiteral("\"(sulli)\" text"));
  87. QVERIFY(err == KShell::NoError);
  88. QCOMPARE(sj(QStringLiteral(" ha\\ lo "), KShell::NoOptions, &err), QStringLiteral("\"ha\\\\\" lo"));
  89. QVERIFY(err == KShell::NoError);
  90. QCOMPARE(sj(QStringLiteral("say \" error"), KShell::NoOptions, &err), QString());
  91. QVERIFY(err == KShell::BadQuoting);
  92. QCOMPARE(sj(QStringLiteral("no \" error\""), KShell::NoOptions, &err), QStringLiteral("no \" error\""));
  93. QVERIFY(err == KShell::NoError);
  94. QCOMPARE(sj(QStringLiteral("say \" still error"), KShell::NoOptions, &err), QString());
  95. QVERIFY(err == KShell::BadQuoting);
  96. QCOMPARE(sj(QStringLiteral("BLA;asdf sdfess d"), KShell::NoOptions, &err), QStringLiteral("\"BLA;asdf\" sdfess d"));
  97. QVERIFY(err == KShell::NoError);
  98. QCOMPARE(sj(QStringLiteral("B\"L\"A&sdf FOO|bar sdf wer "), KShell::NoOptions, &err), QStringLiteral("\"BLA&sdf\" \"FOO|bar\" sdf wer"));
  99. QVERIFY(err == KShell::NoError);
  100. QCOMPARE(sj(QStringLiteral("\"\"\"just \"\" fine\"\"\""), KShell::NoOptions, &err), QStringLiteral("\\^\"\"just \"\\^\"\" fine\"\\^\""));
  101. QVERIFY(err == KShell::NoError);
  102. #else
  103. QCOMPARE(sj(QString::fromUtf8("\"~qU4rK\" 'text' 'jo'\"jo\" $'crap' $'\\\\\\'\\e\\x21' ha\\ lo \\a"), KShell::NoOptions, &err),
  104. QString::fromUtf8("'~qU4rK' text jojo crap '\\'\\''\x1b!' 'ha lo' a"));
  105. QVERIFY(err == KShell::NoError);
  106. QCOMPARE(sj(QStringLiteral("\"~qU4rK\" 'text'"), KShell::TildeExpand, &err), QStringLiteral("'~qU4rK' text"));
  107. QVERIFY(err == KShell::NoError);
  108. QCOMPARE(sj(QStringLiteral("~\"qU4rK\" 'text'"), KShell::TildeExpand, &err), QStringLiteral("'~qU4rK' text"));
  109. QVERIFY(err == KShell::NoError);
  110. QCOMPARE(sj(QStringLiteral("~/\"dir\" 'text'"), KShell::TildeExpand, &err), QString(QDir::homePath() + QStringLiteral("/dir text")));
  111. QVERIFY(err == KShell::NoError);
  112. QCOMPARE(sj(QStringLiteral("~ 'text' ~"), KShell::TildeExpand, &err), QString(QDir::homePath() + QStringLiteral(" text ") + QDir::homePath()));
  113. QVERIFY(err == KShell::NoError);
  114. QCOMPARE(sj(QStringLiteral("\\~ blah"), KShell::TildeExpand, &err), QStringLiteral("'~' blah"));
  115. QVERIFY(err == KShell::NoError);
  116. QCOMPARE(sj(QStringLiteral("~qU4rK ~") + KUser().loginName(), KShell::TildeExpand, &err), QString(QStringLiteral("'~qU4rK' ") + myHomePath()));
  117. QVERIFY(err == KShell::NoError);
  118. const QString unicodeSpaceFileName = QStringLiteral("test テスト.txt"); // #345140
  119. QCOMPARE(sj(unicodeSpaceFileName, KShell::AbortOnMeta | KShell::TildeExpand, &err), unicodeSpaceFileName);
  120. QVERIFY(err == KShell::NoError);
  121. #endif
  122. }
  123. void KShellTest::quoteSplit_data()
  124. {
  125. QTest::addColumn<QString>("string");
  126. QTest::newRow("no space") << QStringLiteral("hiho");
  127. QTest::newRow("regular space") << QStringLiteral("hi there");
  128. QTest::newRow("special space") << QString::fromUtf8("如何定期清潔典型的電風扇 講義.pdf");
  129. }
  130. void KShellTest::quoteSplit()
  131. {
  132. QFETCH(QString, string);
  133. // Splitting a quote arg should always just return one argument
  134. const QStringList args = KShell::splitArgs(KShell::quoteArg(string));
  135. QCOMPARE(args.count(), 1);
  136. }
  137. void KShellTest::abortOnMeta()
  138. {
  139. KShell::Errors err1 = KShell::NoError;
  140. KShell::Errors err2 = KShell::NoError;
  141. QCOMPARE(sj(QStringLiteral("text"), KShell::AbortOnMeta, &err1), QStringLiteral("text"));
  142. QVERIFY(err1 == KShell::NoError);
  143. #ifdef Q_OS_WIN
  144. QVERIFY(KShell::splitArgs(QStringLiteral("BLA & asdf sdfess d"), KShell::AbortOnMeta, &err1).isEmpty());
  145. QVERIFY(err1 == KShell::FoundMeta);
  146. QVERIFY(KShell::splitArgs(QStringLiteral("foo %PATH% bar"), KShell::AbortOnMeta, &err1).isEmpty());
  147. QVERIFY(err1 == KShell::FoundMeta);
  148. QCOMPARE(sj(QStringLiteral("foo %PERCENT_SIGN% bar"), KShell::AbortOnMeta, &err1), QStringLiteral("foo %PERCENT_SIGN% bar"));
  149. QVERIFY(err1 == KShell::NoError);
  150. QCOMPARE(sj(QStringLiteral("@foo ^& bar"), KShell::AbortOnMeta, &err1), QStringLiteral("foo \"&\" bar"));
  151. QVERIFY(err1 == KShell::NoError);
  152. QCOMPARE(sj(QStringLiteral("\"BLA|asdf\" sdfess d"), KShell::AbortOnMeta, &err1), QStringLiteral("\"BLA|asdf\" sdfess d"));
  153. QVERIFY(err1 == KShell::NoError);
  154. QCOMPARE(sj(QStringLiteral("B\"L\"A\"|\"sdf \"FOO | bar\" sdf wer"), KShell::AbortOnMeta, &err1), QStringLiteral("\"BLA|sdf\" \"FOO | bar\" sdf wer"));
  155. QVERIFY(err1 == KShell::NoError);
  156. QCOMPARE(sj(QStringLiteral("b-q me \\\\^|\\\\\\^\""), KShell::AbortOnMeta, &err1), QStringLiteral("b-q me \"\\\\|\"\\\\\\^\""));
  157. QVERIFY(err1 == KShell::NoError);
  158. #else
  159. QCOMPARE(sj(QStringLiteral("say \" error"), KShell::NoOptions, &err1), QString());
  160. QVERIFY(err1 != KShell::NoError);
  161. QCOMPARE(sj(QStringLiteral("say \" still error"), KShell::AbortOnMeta, &err1), QString());
  162. QVERIFY(err1 != KShell::NoError);
  163. QVERIFY(sj(QStringLiteral("say `echo no error`"), KShell::NoOptions, &err1) != sj(QStringLiteral("say `echo no error`"), KShell::AbortOnMeta, &err2));
  164. QVERIFY(err1 != err2);
  165. QVERIFY(sj(QStringLiteral("BLA=say echo meta"), KShell::NoOptions, &err1) != sj(QStringLiteral("BLA=say echo meta"), KShell::AbortOnMeta, &err2));
  166. QVERIFY(err1 != err2);
  167. QVERIFY(sj(QStringLiteral("B\"L\"A=say FOO=bar echo meta"), KShell::NoOptions, &err1)
  168. == sj(QStringLiteral("B\"L\"A=say FOO=bar echo meta"), KShell::AbortOnMeta, &err2));
  169. #endif
  170. }
  171. QTEST_MAIN(KShellTest)
  172. #include "kshelltest.moc"