Skip to content

Commit b813274

Browse files
committed
Issue 02: add OptionsQmlModel unit-test seam and coverage
1 parent b79976d commit b813274

5 files changed

Lines changed: 355 additions & 43 deletions

File tree

qml/models/options_model.cpp

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5-
#include <qml/models/options_model.h>
6-
75
#include <common/args.h>
86
#include <common/settings.h>
97
#include <common/system.h>
108
#include <interfaces/node.h>
9+
#include <kernel/caches.h>
1110
#include <mapport.h>
1211
#include <node/caches.h>
1312
#include <node/chainstatemanager_args.h>
14-
#include <qml/guiconstants.h>
15-
#include <qml/models/proxysettings.h>
1613
#include <txdb.h>
17-
#include <univalue.h>
1814
#include <util/fs.h>
1915
#include <util/fs_helpers.h>
2016
#include <validation.h>
17+
#include <qml/models/options_model.h>
18+
#include <qml/guiconstants.h>
19+
#include <qml/models/proxysettings.h>
20+
#include <univalue.h>
2121

2222
#include <algorithm>
2323
#include <cassert>
24+
#include <memory>
2425

2526
#include <QDebug>
2627
#include <QDir>
@@ -31,6 +32,30 @@ namespace {
3132
constexpr auto SETTINGS_KEY_DISPLAY_UNIT = "DisplayBitcoinUnit";
3233
constexpr auto SETTINGS_KEY_RESTART_REQUIRED = "fRestartRequired";
3334

35+
class NodeSettingsBackend : public OptionsQmlModel::SettingsBackend
36+
{
37+
public:
38+
explicit NodeSettingsBackend(interfaces::Node& node) : m_node(node) {}
39+
40+
common::SettingsValue getPersistentSetting(const std::string_view name) override
41+
{
42+
return m_node.getPersistentSetting(std::string{name});
43+
}
44+
45+
void updateRwSetting(const std::string_view name, const common::SettingsValue& value) override
46+
{
47+
m_node.updateRwSetting(std::string{name}, value);
48+
}
49+
50+
void resetSettings() override
51+
{
52+
m_node.resetSettings();
53+
}
54+
55+
private:
56+
interfaces::Node& m_node;
57+
};
58+
3459
int PruneMiBtoGB(int64_t mib)
3560
{
3661
return (mib * 1024 * 1024 + GB_BYTES - 1) / GB_BYTES;
@@ -60,34 +85,43 @@ QString NormalizeLocaleTag(QString locale_tag)
6085
}
6186
} // namespace
6287

63-
OptionsQmlModel::OptionsQmlModel(interfaces::Node& node, bool is_onboarded)
64-
: m_node{node}
88+
OptionsQmlModel::OptionsQmlModel(interfaces::Node& node, const bool is_onboarded)
89+
: OptionsQmlModel(std::make_unique<NodeSettingsBackend>(node), is_onboarded)
90+
{
91+
}
92+
93+
OptionsQmlModel::OptionsQmlModel(std::unique_ptr<SettingsBackend> settings_backend, const bool is_onboarded)
94+
: m_settings_backend{std::move(settings_backend)}
6595
, m_onboarded{is_onboarded}
96+
, m_min_dbcache_size_mib{MIN_DB_CACHE >> 20}
97+
, m_max_dbcache_size_mib{MAX_COINS_DB_CACHE >> 20}
98+
, m_max_script_threads{MAX_SCRIPTCHECK_THREADS}
99+
, m_min_script_threads{-GetNumCores()}
66100
{
67-
m_dbcache_size_mib = SettingToInt(m_node.getPersistentSetting("dbcache"), DEFAULT_DB_CACHE >> 20);
101+
m_dbcache_size_mib = SettingToInt(m_settings_backend->getPersistentSetting("dbcache"), DEFAULT_DB_CACHE >> 20);
68102

69-
m_listen = SettingToBool(m_node.getPersistentSetting("listen"), DEFAULT_LISTEN);
103+
m_listen = SettingToBool(m_settings_backend->getPersistentSetting("listen"), DEFAULT_LISTEN);
70104

71-
m_natpmp = SettingToBool(m_node.getPersistentSetting("natpmp"), DEFAULT_NATPMP);
105+
m_natpmp = SettingToBool(m_settings_backend->getPersistentSetting("natpmp"), DEFAULT_NATPMP);
72106

73-
int64_t prune_value{SettingToInt(m_node.getPersistentSetting("prune"), 0)};
107+
int64_t prune_value{SettingToInt(m_settings_backend->getPersistentSetting("prune"), 0)};
74108
m_prune = (prune_value > 1);
75109
m_prune_size_gb = m_prune ? PruneMiBtoGB(prune_value) : DEFAULT_PRUNE_TARGET_GB;
76110

77-
m_script_threads = SettingToInt(m_node.getPersistentSetting("par"), DEFAULT_SCRIPTCHECK_THREADS);
111+
m_script_threads = SettingToInt(m_settings_backend->getPersistentSetting("par"), DEFAULT_SCRIPTCHECK_THREADS);
78112

79-
m_server = SettingToBool(m_node.getPersistentSetting("server"), false);
113+
m_server = SettingToBool(m_settings_backend->getPersistentSetting("server"), false);
80114

81-
const ProxySettingState default_proxy = ReadProxySetting(m_node.getPersistentSetting("proxy"));
115+
const ProxySettingState default_proxy = ReadProxySetting(m_settings_backend->getPersistentSetting("proxy"));
82116
m_default_proxy_enabled = default_proxy.enabled;
83117
m_default_proxy_address = default_proxy.address;
84118

85-
const ProxySettingState tor_proxy = ReadProxySetting(m_node.getPersistentSetting("onion"));
119+
const ProxySettingState tor_proxy = ReadProxySetting(m_settings_backend->getPersistentSetting("onion"));
86120
m_tor_proxy_enabled = tor_proxy.enabled;
87121
m_tor_proxy_address = tor_proxy.address;
88122

89123
m_dataDir = getDefaultDataDirString();
90-
m_language = QString::fromStdString(SettingToString(m_node.getPersistentSetting("lang"), "")).trimmed();
124+
m_language = QString::fromStdString(SettingToString(m_settings_backend->getPersistentSetting("lang"), "")).trimmed();
91125
m_available_languages = BuildLanguageList();
92126

93127
QSettings settings;
@@ -107,7 +141,7 @@ void OptionsQmlModel::setDbcacheSizeMiB(int new_dbcache_size_mib)
107141
if (new_dbcache_size_mib != m_dbcache_size_mib) {
108142
m_dbcache_size_mib = new_dbcache_size_mib;
109143
if (m_onboarded) {
110-
m_node.updateRwSetting("dbcache", new_dbcache_size_mib);
144+
m_settings_backend->updateRwSetting("dbcache", new_dbcache_size_mib);
111145
}
112146
Q_EMIT dbcacheSizeMiBChanged(new_dbcache_size_mib);
113147
}
@@ -118,7 +152,7 @@ void OptionsQmlModel::setListen(bool new_listen)
118152
if (new_listen != m_listen) {
119153
m_listen = new_listen;
120154
if (m_onboarded) {
121-
m_node.updateRwSetting("listen", new_listen);
155+
m_settings_backend->updateRwSetting("listen", new_listen);
122156
}
123157
Q_EMIT listenChanged(new_listen);
124158
}
@@ -129,7 +163,7 @@ void OptionsQmlModel::setNatpmp(bool new_natpmp)
129163
if (new_natpmp != m_natpmp) {
130164
m_natpmp = new_natpmp;
131165
if (m_onboarded) {
132-
m_node.updateRwSetting("natpmp", new_natpmp);
166+
m_settings_backend->updateRwSetting("natpmp", new_natpmp);
133167
}
134168
Q_EMIT natpmpChanged(new_natpmp);
135169
}
@@ -140,7 +174,7 @@ void OptionsQmlModel::setPrune(bool new_prune)
140174
if (new_prune != m_prune) {
141175
m_prune = new_prune;
142176
if (m_onboarded) {
143-
m_node.updateRwSetting("prune", pruneSetting());
177+
m_settings_backend->updateRwSetting("prune", pruneSetting());
144178
}
145179
Q_EMIT pruneChanged(new_prune);
146180
}
@@ -151,7 +185,7 @@ void OptionsQmlModel::setPruneSizeGB(int new_prune_size_gb)
151185
if (new_prune_size_gb != m_prune_size_gb) {
152186
m_prune_size_gb = new_prune_size_gb;
153187
if (m_onboarded) {
154-
m_node.updateRwSetting("prune", pruneSetting());
188+
m_settings_backend->updateRwSetting("prune", pruneSetting());
155189
}
156190
Q_EMIT pruneSizeGBChanged(new_prune_size_gb);
157191
}
@@ -162,7 +196,7 @@ void OptionsQmlModel::setScriptThreads(int new_script_threads)
162196
if (new_script_threads != m_script_threads) {
163197
m_script_threads = new_script_threads;
164198
if (m_onboarded) {
165-
m_node.updateRwSetting("par", new_script_threads);
199+
m_settings_backend->updateRwSetting("par", new_script_threads);
166200
}
167201
Q_EMIT scriptThreadsChanged(new_script_threads);
168202
}
@@ -173,7 +207,7 @@ void OptionsQmlModel::setServer(bool new_server)
173207
if (new_server != m_server) {
174208
m_server = new_server;
175209
if (m_onboarded) {
176-
m_node.updateRwSetting("server", new_server);
210+
m_settings_backend->updateRwSetting("server", new_server);
177211
}
178212
Q_EMIT serverChanged(new_server);
179213
}
@@ -185,7 +219,7 @@ void OptionsQmlModel::persistProxySetting(const std::string& setting_key, const
185219
if (!SerializeProxySetting(enabled, address, serialized_setting)) {
186220
return;
187221
}
188-
m_node.updateRwSetting(setting_key, serialized_setting);
222+
m_settings_backend->updateRwSetting(setting_key, serialized_setting);
189223
}
190224

191225
void OptionsQmlModel::setDefaultProxyEnabled(const bool new_default_proxy_enabled)
@@ -259,7 +293,7 @@ void OptionsQmlModel::setLanguage(const QString& new_language)
259293

260294
m_language = normalized_language;
261295
if (m_onboarded) {
262-
m_node.updateRwSetting("lang", m_language.toStdString());
296+
m_settings_backend->updateRwSetting("lang", m_language.toStdString());
263297
}
264298
setRestartRequired(true);
265299
Q_EMIT languageChanged(m_language);
@@ -443,27 +477,27 @@ QStringList OptionsQmlModel::BuildLanguageList()
443477

444478
void OptionsQmlModel::onboard()
445479
{
446-
m_node.resetSettings();
480+
m_settings_backend->resetSettings();
447481
if (m_dbcache_size_mib != DEFAULT_DB_CACHE >> 20) {
448-
m_node.updateRwSetting("dbcache", m_dbcache_size_mib);
482+
m_settings_backend->updateRwSetting("dbcache", m_dbcache_size_mib);
449483
}
450484
if (m_listen) {
451-
m_node.updateRwSetting("listen", m_listen);
485+
m_settings_backend->updateRwSetting("listen", m_listen);
452486
}
453487
if (m_natpmp) {
454-
m_node.updateRwSetting("natpmp", m_natpmp);
488+
m_settings_backend->updateRwSetting("natpmp", m_natpmp);
455489
}
456490
if (m_prune) {
457-
m_node.updateRwSetting("prune", pruneSetting());
491+
m_settings_backend->updateRwSetting("prune", pruneSetting());
458492
}
459493
if (m_script_threads != DEFAULT_SCRIPTCHECK_THREADS) {
460-
m_node.updateRwSetting("par", m_script_threads);
494+
m_settings_backend->updateRwSetting("par", m_script_threads);
461495
}
462496
if (m_server) {
463-
m_node.updateRwSetting("server", m_server);
497+
m_settings_backend->updateRwSetting("server", m_server);
464498
}
465499
if (!m_language.isEmpty()) {
466-
m_node.updateRwSetting("lang", m_language.toStdString());
500+
m_settings_backend->updateRwSetting("lang", m_language.toStdString());
467501
}
468502
persistProxySetting("proxy", m_default_proxy_enabled, m_default_proxy_address);
469503
persistProxySetting("onion", m_tor_proxy_enabled, m_tor_proxy_address);

qml/models/options_model.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@
55
#ifndef BITCOIN_QML_MODELS_OPTIONS_MODEL_H
66
#define BITCOIN_QML_MODELS_OPTIONS_MODEL_H
77

8-
#include <txdb.h>
98
#include <common/settings.h>
10-
#include <node/caches.h>
11-
#include <kernel/caches.h>
12-
#include <common/system.h>
13-
#include <validation.h>
149

1510
#include <QObject>
1611
#include <QString>
1712
#include <QStringList>
1813
#include <QUrl>
1914

2015
#include <string>
16+
#include <memory>
17+
#include <string_view>
2118

2219
namespace interfaces {
2320
class Node;
@@ -53,7 +50,17 @@ class OptionsQmlModel : public QObject
5350
Q_PROPERTY(bool restartRequired READ restartRequired NOTIFY restartRequiredChanged)
5451

5552
public:
53+
class SettingsBackend
54+
{
55+
public:
56+
virtual ~SettingsBackend() = default;
57+
virtual common::SettingsValue getPersistentSetting(std::string_view name) = 0;
58+
virtual void updateRwSetting(std::string_view name, const common::SettingsValue& value) = 0;
59+
virtual void resetSettings() = 0;
60+
};
61+
5662
explicit OptionsQmlModel(interfaces::Node& node, bool is_onboarded);
63+
explicit OptionsQmlModel(std::unique_ptr<SettingsBackend> settings_backend, bool is_onboarded);
5764

5865
enum DisplayUnit {
5966
DisplayUnitBTC = 0,
@@ -128,16 +135,16 @@ public Q_SLOTS:
128135
void restartRequiredChanged(bool restart_required);
129136

130137
private:
131-
interfaces::Node& m_node;
138+
std::unique_ptr<SettingsBackend> m_settings_backend;
132139
bool m_onboarded;
133140

134141
// Properties that are exposed to QML.
135142
int m_dbcache_size_mib;
136-
const int m_min_dbcache_size_mib{MIN_DB_CACHE >> 20};
137-
const int m_max_dbcache_size_mib{MAX_COINS_DB_CACHE >> 20};
143+
const int m_min_dbcache_size_mib;
144+
const int m_max_dbcache_size_mib;
138145
bool m_listen;
139-
const int m_max_script_threads{MAX_SCRIPTCHECK_THREADS};
140-
const int m_min_script_threads{-GetNumCores()};
146+
const int m_max_script_threads;
147+
const int m_min_script_threads;
141148
bool m_natpmp;
142149
bool m_prune;
143150
int m_prune_size_gb;

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add_executable(bitcoinqml_unit_tests
2828
test_mempooldiagnosticsmodel.cpp
2929
test_rpccommandexecutor.cpp
3030
test_proxysettings.cpp
31+
test_optionsmodel.cpp
3132
test_sendrecipientslistmodel.cpp
3233
test_desktopwindowbehaviormodel.cpp
3334
test_walletlistmodel.cpp
@@ -68,6 +69,7 @@ add_executable(bitcoinqml_unit_tests
6869
${CMAKE_CURRENT_SOURCE_DIR}/../qml/models/mempooldiagnosticsmodel.cpp
6970
${CMAKE_CURRENT_SOURCE_DIR}/../qml/models/rpccommandexecutor.cpp
7071
${CMAKE_CURRENT_SOURCE_DIR}/../qml/models/proxysettings.cpp
72+
${CMAKE_CURRENT_SOURCE_DIR}/../qml/models/options_model.cpp
7173
${CMAKE_CURRENT_SOURCE_DIR}/../qml/models/desktopwindowbehaviormodel.cpp
7274
${CMAKE_CURRENT_SOURCE_DIR}/../qml/models/walletlistmodel.cpp
7375
${CMAKE_CURRENT_SOURCE_DIR}/../qml/models/walletloaderror.cpp

0 commit comments

Comments
 (0)