Add test coverage for Qt initialization code & basic RPC console functionality.pull/643/head
parent
ca20b65cc0
commit
7e4bd19785
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <qt/bitcoin.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
/** Translate string to current locale using Qt. */
|
||||
extern const std::function<std::string(const char*)> G_TRANSLATION_FUN = [](const char* psz) {
|
||||
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) { return GuiMain(argc, argv); }
|
@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <qt/test/apptests.h>
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <init.h>
|
||||
#include <qt/bitcoin.h>
|
||||
#include <qt/bitcoingui.h>
|
||||
#include <qt/networkstyle.h>
|
||||
#include <qt/rpcconsole.h>
|
||||
#include <shutdown.h>
|
||||
#include <validation.h>
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/bitcoin-config.h>
|
||||
#endif
|
||||
#ifdef ENABLE_WALLET
|
||||
#include <wallet/db.h>
|
||||
#endif
|
||||
|
||||
#include <QAction>
|
||||
#include <QEventLoop>
|
||||
#include <QLineEdit>
|
||||
#include <QScopedPointer>
|
||||
#include <QTest>
|
||||
#include <QTextEdit>
|
||||
#include <QtGlobal>
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtTest/QtTestWidgets>
|
||||
#endif
|
||||
#include <QtTest/QtTestGui>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <univalue.h>
|
||||
|
||||
namespace {
|
||||
//! Call getblockchaininfo RPC and check first field of JSON output.
|
||||
void TestRpcCommand(RPCConsole* console)
|
||||
{
|
||||
QEventLoop loop;
|
||||
QTextEdit* messagesWidget = console->findChild<QTextEdit*>("messagesWidget");
|
||||
QObject::connect(messagesWidget, &QTextEdit::textChanged, &loop, &QEventLoop::quit);
|
||||
QLineEdit* lineEdit = console->findChild<QLineEdit*>("lineEdit");
|
||||
QTest::keyClicks(lineEdit, "getblockchaininfo");
|
||||
QTest::keyClick(lineEdit, Qt::Key_Return);
|
||||
loop.exec();
|
||||
QString output = messagesWidget->toPlainText();
|
||||
UniValue value;
|
||||
value.read(output.right(output.size() - output.lastIndexOf(QChar::ObjectReplacementCharacter) - 1).toStdString());
|
||||
QCOMPARE(value["chain"].get_str(), std::string("regtest"));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//! Entry point for BitcoinApplication tests.
|
||||
void AppTests::appTests()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
if (QApplication::platformName() == "minimal") {
|
||||
// Disable for mac on "minimal" platform to avoid crashes inside the Qt
|
||||
// framework when it tries to look up unimplemented cocoa functions,
|
||||
// and fails to handle returned nulls
|
||||
// (https://bugreports.qt.io/browse/QTBUG-49686).
|
||||
QWARN("Skipping AppTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
|
||||
"with 'test_bitcoin-qt -platform cocoa' on mac, or else use a linux or windows build.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_app.parameterSetup();
|
||||
m_app.createOptionsModel(true /* reset settings */);
|
||||
QScopedPointer<const NetworkStyle> style(
|
||||
NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
|
||||
m_app.setupPlatformStyle();
|
||||
m_app.createWindow(style.data());
|
||||
connect(&m_app, &BitcoinApplication::windowShown, this, &AppTests::guiTests);
|
||||
expectCallback("guiTests");
|
||||
m_app.baseInitialize();
|
||||
m_app.requestInitialize();
|
||||
m_app.exec();
|
||||
m_app.requestShutdown();
|
||||
m_app.exec();
|
||||
|
||||
// Reset global state to avoid interfering with later tests.
|
||||
AbortShutdown();
|
||||
UnloadBlockIndex();
|
||||
}
|
||||
|
||||
//! Entry point for BitcoinGUI tests.
|
||||
void AppTests::guiTests(BitcoinGUI* window)
|
||||
{
|
||||
HandleCallback callback{"guiTests", *this};
|
||||
connect(window, &BitcoinGUI::consoleShown, this, &AppTests::consoleTests);
|
||||
expectCallback("consoleTests");
|
||||
QAction* action = window->findChild<QAction*>("openRPCConsoleAction");
|
||||
action->activate(QAction::Trigger);
|
||||
}
|
||||
|
||||
//! Entry point for RPCConsole tests.
|
||||
void AppTests::consoleTests(RPCConsole* console)
|
||||
{
|
||||
HandleCallback callback{"consoleTests", *this};
|
||||
TestRpcCommand(console);
|
||||
}
|
||||
|
||||
//! Destructor to shut down after the last expected callback completes.
|
||||
AppTests::HandleCallback::~HandleCallback()
|
||||
{
|
||||
auto& callbacks = m_app_tests.m_callbacks;
|
||||
auto it = callbacks.find(m_callback);
|
||||
assert(it != callbacks.end());
|
||||
callbacks.erase(it);
|
||||
if (callbacks.empty()) {
|
||||
m_app_tests.m_app.quit();
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_QT_TEST_APPTESTS_H
|
||||
#define BITCOIN_QT_TEST_APPTESTS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
class BitcoinApplication;
|
||||
class BitcoinGUI;
|
||||
class RPCConsole;
|
||||
|
||||
class AppTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppTests(BitcoinApplication& app) : m_app(app) {}
|
||||
|
||||
private Q_SLOTS:
|
||||
void appTests();
|
||||
void guiTests(BitcoinGUI* window);
|
||||
void consoleTests(RPCConsole* console);
|
||||
|
||||
private:
|
||||
//! Add expected callback name to list of pending callbacks.
|
||||
void expectCallback(std::string callback) { m_callbacks.emplace(std::move(callback)); }
|
||||
|
||||
//! RAII helper to remove no-longer-pending callback.
|
||||
struct HandleCallback
|
||||
{
|
||||
std::string m_callback;
|
||||
AppTests& m_app_tests;
|
||||
~HandleCallback();
|
||||
};
|
||||
|
||||
//! Bitcoin application.
|
||||
BitcoinApplication& m_app;
|
||||
|
||||
//! Set of pending callback names. Used to track expected callbacks and shut
|
||||
//! down the app after the last callback has been handled and all tests have
|
||||
//! either run or thrown exceptions. This could be a simple int counter
|
||||
//! instead of a set of names, but the names might be useful for debugging.
|
||||
std::multiset<std::string> m_callbacks;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_QT_TEST_APPTESTS_H
|
Loading…
Reference in new issue