apptests.cpp raw
1 // Copyright (c) 2018-2022 The Limenka developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <qt/test/apptests.h>
6
7 #include <chainparams.h>
8 #include <common/args.h>
9 #include <key.h>
10 #include <logging.h>
11 #include <qt/limenka.h>
12 #include <qt/limenkagui.h>
13 #include <qt/networkstyle.h>
14 #include <qt/rpcconsole.h>
15 #include <test/util/setup_common.h>
16 #include <validation.h>
17
18 #include <QAction>
19 #include <QLineEdit>
20 #include <QRegularExpression>
21 #include <QScopedPointer>
22 #include <QSignalSpy>
23 #include <QString>
24 #include <QTest>
25 #include <QTextEdit>
26 #include <QtGlobal>
27 #include <QtTest/QtTestWidgets>
28 #include <QtTest/QtTestGui>
29
30 namespace {
31 //! Regex find a string group inside of the console output
32 QString FindInConsole(const QString& output, const QString& pattern)
33 {
34 const QRegularExpression re(pattern);
35 return re.match(output).captured(1);
36 }
37
38 //! Call getblockchaininfo RPC and check first field of JSON output.
39 void TestRpcCommand(RPCConsole* console)
40 {
41 QTextEdit* messagesWidget = console->findChild<QTextEdit*>("messagesWidget");
42 QLineEdit* lineEdit = console->findChild<QLineEdit*>("lineEdit");
43 QSignalSpy mw_spy(messagesWidget, &QTextEdit::textChanged);
44 QVERIFY(mw_spy.isValid());
45 QTest::keyClicks(lineEdit, "getblockchaininfo");
46 QTest::keyClick(lineEdit, Qt::Key_Return);
47 QVERIFY(mw_spy.wait(1000));
48 QCOMPARE(mw_spy.count(), 4);
49 const QString output = messagesWidget->toPlainText();
50 const QString pattern = QStringLiteral("\"chain\": \"(\\w+)\"");
51 QCOMPARE(FindInConsole(output, pattern), QString("regtest"));
52 }
53 } // namespace
54
55 //! Entry point for LimenkaApplication tests.
56 void AppTests::appTests()
57 {
58 #ifdef Q_OS_MACOS
59 if (QApplication::platformName() == "minimal") {
60 // Disable for mac on "minimal" platform to avoid crashes inside the Qt
61 // framework when it tries to look up unimplemented cocoa functions,
62 // and fails to handle returned nulls
63 // (https://bugreports.qt.io/browse/QTBUG-49686).
64 qWarning() << "Skipping AppTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
65 "with 'QT_QPA_PLATFORM=cocoa test_limenka-qt' on mac, or else use a linux or windows build.";
66 return;
67 }
68 #endif
69
70 {
71 // Need to ensure datadir is setup so resetting settings can delete the non-existent limenka_rw.conf
72 std::string error;
73 if (!gArgs.ReadConfigFiles(error, true)) {
74 qWarning() << "Error in readConfigFiles";
75 }
76 }
77
78 qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>("interfaces::BlockAndHeaderTipInfo");
79 m_app.parameterSetup();
80 QVERIFY(m_app.createOptionsModel(/*resetSettings=*/true));
81 QScopedPointer<const NetworkStyle> style(NetworkStyle::instantiate(Params().GetChainType()));
82 m_app.setupPlatformStyle();
83 m_app.createWindow(style.data());
84 connect(&m_app, &LimenkaApplication::windowShown, this, &AppTests::guiTests);
85 expectCallback("guiTests");
86 m_app.baseInitialize();
87 m_app.requestInitialize();
88 m_app.exec();
89 m_app.requestShutdown();
90 m_app.exec();
91
92 // Reset global state to avoid interfering with later tests.
93 LogInstance().DisconnectTestLogger();
94 }
95
96 //! Entry point for LimenkaGUI tests.
97 void AppTests::guiTests(LimenkaGUI* window)
98 {
99 HandleCallback callback{"guiTests", *this};
100 connect(window, &LimenkaGUI::consoleShown, this, &AppTests::consoleTests);
101 expectCallback("consoleTests");
102 QAction* action = window->findChild<QAction*>("openRPCConsoleAction");
103 action->activate(QAction::Trigger);
104 }
105
106 //! Entry point for RPCConsole tests.
107 void AppTests::consoleTests(RPCConsole* console)
108 {
109 HandleCallback callback{"consoleTests", *this};
110 TestRpcCommand(console);
111 }
112
113 //! Destructor to shut down after the last expected callback completes.
114 AppTests::HandleCallback::~HandleCallback()
115 {
116 auto& callbacks = m_app_tests.m_callbacks;
117 auto it = callbacks.find(m_callback);
118 assert(it != callbacks.end());
119 callbacks.erase(it);
120 if (callbacks.empty()) {
121 m_app_tests.m_app.exit(0);
122 }
123 }
124