Skip to content
This repository was archived by the owner on Mar 28, 2026. It is now read-only.

Commit b582091

Browse files
authored
Add unit tests for settings (#1169)
1 parent f057bca commit b582091

File tree

2 files changed

+304
-0
lines changed

2 files changed

+304
-0
lines changed

tests/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ target_link_libraries(test_log jmp_core Qt6::Test)
2727
target_include_directories(test_log PRIVATE ${TEST_INCLUDE_DIRS})
2828
target_compile_definitions(test_log PRIVATE ${TEST_COMPILE_DEFS})
2929
add_test(NAME test_log COMMAND test_log)
30+
31+
add_executable(test_settings test_settings.cpp)
32+
target_link_libraries(test_settings jmp_core Qt6::Test)
33+
target_include_directories(test_settings PRIVATE ${TEST_INCLUDE_DIRS})
34+
target_compile_definitions(test_settings PRIVATE ${TEST_COMPILE_DEFS})
35+
add_test(NAME test_settings COMMAND test_settings)

tests/test_settings.cpp

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
#include <QtTest/QtTest>
2+
#include "../src/settings/SettingsValue.h"
3+
#include "../src/settings/SettingsSection.h"
4+
5+
class TestSettings : public QObject
6+
{
7+
Q_OBJECT
8+
9+
private slots:
10+
// SettingsValue tests
11+
void testDefaultValueReturnedWhenNoExplicitValue();
12+
void testExplicitValueOverridesDefault();
13+
void testInvalidValueRestoresDefault();
14+
void testPossibleValues();
15+
void testDescriptionsOutput();
16+
void testDescriptionsWithInputType();
17+
void testIsHiddenPlatformAny();
18+
void testIsHiddenMismatchedPlatform();
19+
20+
// SettingsSection tests
21+
void testRegisterSettingMakesValueRetrievable();
22+
void testDuplicateRegisterSettingRejected();
23+
void testValueForUnknownKeyReturnsInvalid();
24+
void testDefaultValueReturnsSettingDefault();
25+
void testAllValuesReturnsAllRegistered();
26+
void testResetValueDescribedSetting();
27+
void testResetValueDynamicSetting();
28+
void testResetValuesResetsAll();
29+
void testSectionIsHiddenPlatform();
30+
void testSectionOrder();
31+
void testValuesUpdatedSignalOnReset();
32+
};
33+
34+
35+
/*!
36+
SettingsValue tests
37+
*/
38+
39+
void TestSettings::testDefaultValueReturnedWhenNoExplicitValue()
40+
{
41+
SettingsValue sv("keyTest", 42);
42+
QCOMPARE(sv.value(), QVariant(42));
43+
}
44+
45+
void TestSettings::testExplicitValueOverridesDefault()
46+
{
47+
SettingsValue sv("keyTest", 42);
48+
sv.setValue(123);
49+
QCOMPARE(sv.value(), QVariant(123));
50+
}
51+
52+
void TestSettings::testInvalidValueRestoresDefault()
53+
{
54+
SettingsValue sv("keyTest", 42);
55+
sv.setValue(456);
56+
QCOMPARE(sv.value(), QVariant(456));
57+
58+
sv.setValue(QVariant()); // invalid value
59+
QCOMPARE(sv.value(), QVariant(42));
60+
}
61+
62+
void TestSettings::testPossibleValues()
63+
{
64+
SettingsValue sv("keyTest", QString("a"));
65+
sv.addPossibleValue("Option A", QString("a"));
66+
sv.addPossibleValue("Option B", QString("b"));
67+
68+
QVariantList possible = sv.possibleValues();
69+
QCOMPARE(possible.size(), 2);
70+
71+
QVariantMap first = possible[0].toMap();
72+
QCOMPARE(first["title"].toString(), QString("Option A"));
73+
QCOMPARE(first["value"].toString(), QString("a"));
74+
75+
QVariantMap second = possible[1].toMap();
76+
QCOMPARE(second["title"].toString(), QString("Option B"));
77+
QCOMPARE(second["value"].toString(), QString("b"));
78+
79+
// setPossibleValues replaces the list
80+
QVariantList newList;
81+
QVariantMap entry;
82+
entry["value"] = QString("x");
83+
entry["title"] = QString("Option X");
84+
newList << entry;
85+
sv.setPossibleValues(newList);
86+
QCOMPARE(sv.possibleValues().size(), 1);
87+
}
88+
89+
void TestSettings::testDescriptionsOutput()
90+
{
91+
SettingsValue sv("myKey", 10);
92+
sv.setDisplayName("My Setting");
93+
sv.setHelp("Sample help text");
94+
sv.addPossibleValue("Ten", 10);
95+
sv.addPossibleValue("Twenty", 20);
96+
97+
QVariantMap desc = sv.descriptions();
98+
QCOMPARE(desc["key"].toString(), QString("myKey"));
99+
QCOMPARE(desc["displayName"].toString(), QString("My Setting"));
100+
QCOMPARE(desc["help"].toString(), QString("Sample help text"));
101+
QVERIFY(desc.contains("options"));
102+
QCOMPARE(desc["options"].toList().size(), 2);
103+
QVERIFY(!desc.contains("inputType"));
104+
}
105+
106+
void TestSettings::testDescriptionsWithInputType()
107+
{
108+
SettingsValue sv("myKey", QString(""));
109+
sv.setDisplayName("Name");
110+
sv.setHelp("Help");
111+
sv.setInputType("numeric");
112+
113+
QVariantMap desc = sv.descriptions();
114+
QVERIFY(desc.contains("inputType"));
115+
QCOMPARE(desc["inputType"].toString(), QString("numeric"));
116+
QVERIFY(!desc.contains("options"));
117+
}
118+
119+
void TestSettings::testIsHiddenPlatformAny()
120+
{
121+
SettingsValue sv("key", 0, PLATFORM_ANY);
122+
// default hidden=true
123+
QVERIFY(sv.isHidden());
124+
125+
sv.setHidden(false);
126+
QVERIFY(!sv.isHidden());
127+
}
128+
129+
void TestSettings::testIsHiddenMismatchedPlatform()
130+
{
131+
// Use a platform that is not the current one.
132+
quint8 wrongPlatform = PLATFORM_ANY & ~Utils::CurrentPlatform();
133+
SettingsValue sv("key", 0, wrongPlatform);
134+
sv.setHidden(false);
135+
136+
// Wrong platform should override hidden = false.
137+
QVERIFY(sv.isHidden());
138+
}
139+
140+
/*!
141+
SettingsSection tests
142+
*/
143+
144+
void TestSettings::testRegisterSettingMakesValueRetrievable()
145+
{
146+
SettingsSection section("testSection", PLATFORM_ANY, 0);
147+
auto* sv = new SettingsValue("alpaca", 99);
148+
section.registerSetting(sv);
149+
150+
QCOMPARE(section.value("alpaca"), QVariant(99));
151+
}
152+
153+
void TestSettings::testDuplicateRegisterSettingRejected()
154+
{
155+
SettingsSection section("testSection", PLATFORM_ANY, 0);
156+
auto* sv1 = new SettingsValue("llama", 10); // Original value
157+
auto* sv2 = new SettingsValue("llama", 20); // Duplicate value
158+
section.registerSetting(sv1);
159+
section.registerSetting(sv2);
160+
161+
// Original value is retained
162+
QCOMPARE(section.value("llama"), QVariant(10));
163+
164+
// SettingsSection will only delete sv1 so we have to delete sv2 ourselves.
165+
delete sv2;
166+
}
167+
168+
void TestSettings::testValueForUnknownKeyReturnsInvalid()
169+
{
170+
SettingsSection section("testSection", PLATFORM_ANY, 0);
171+
QVariant result = section.value("nonexistent");
172+
QVERIFY(!result.isValid());
173+
}
174+
175+
void TestSettings::testDefaultValueReturnsSettingDefault()
176+
{
177+
SettingsSection section("testSection", PLATFORM_ANY, 0);
178+
auto* sv = new SettingsValue("moose", 55);
179+
section.registerSetting(sv);
180+
181+
// Set a value on the SettingsValue directly
182+
sv->setValue(77);
183+
QCOMPARE(section.value("moose"), QVariant(77));
184+
QCOMPARE(section.defaultValue("moose"), QVariant(55));
185+
}
186+
187+
void TestSettings::testAllValuesReturnsAllRegistered()
188+
{
189+
SettingsSection section("testSection", PLATFORM_ANY, 0);
190+
auto* sv1 = new SettingsValue("a", 1);
191+
auto* sv2 = new SettingsValue("b", 2);
192+
section.registerSetting(sv1);
193+
section.registerSetting(sv2);
194+
195+
QVariantMap all = section.allValues();
196+
QCOMPARE(all.size(), 2);
197+
QCOMPARE(all["a"], QVariant(1));
198+
QCOMPARE(all["b"], QVariant(2));
199+
}
200+
201+
void TestSettings::testResetValueDescribedSetting()
202+
{
203+
SettingsSection section("testSection", PLATFORM_ANY, 0);
204+
auto* sv = new SettingsValue("aardvark", 100);
205+
sv->setHasDescription(true);
206+
section.registerSetting(sv);
207+
208+
// Change from default
209+
sv->setValue(999);
210+
QCOMPARE(section.value("aardvark"), QVariant(999));
211+
212+
section.resetValue("aardvark");
213+
QCOMPARE(section.value("aardvark"), QVariant(100));
214+
}
215+
216+
void TestSettings::testResetValueDynamicSetting()
217+
{
218+
SettingsSection section("testSection", PLATFORM_ANY, 0);
219+
// Dynamic setting: hasDescription = false (the default)
220+
auto* sv = new SettingsValue("dynamic", QString("temp"));
221+
section.registerSetting(sv);
222+
223+
QVERIFY(section.value("dynamic").isValid());
224+
225+
section.resetValue("dynamic");
226+
// Dynamic setting is removed entirely
227+
QVERIFY(!section.value("dynamic").isValid());
228+
}
229+
230+
void TestSettings::testResetValuesResetsAll()
231+
{
232+
SettingsSection section("testSection", PLATFORM_ANY, 0);
233+
234+
auto* sv1 = new SettingsValue("described", 10);
235+
sv1->setHasDescription(true);
236+
section.registerSetting(sv1);
237+
238+
auto* sv2 = new SettingsValue("dynamic", QString("tmp"));
239+
section.registerSetting(sv2);
240+
241+
// Modify the described setting.
242+
sv1->setValue(50);
243+
244+
section.resetValues();
245+
246+
// Described setting resets to default.
247+
QCOMPARE(section.value("described"), QVariant(10));
248+
249+
// Dynamic setting removed.
250+
QVERIFY(!section.value("dynamic").isValid());
251+
}
252+
253+
void TestSettings::testSectionIsHiddenPlatform()
254+
{
255+
// Current platform section.
256+
SettingsSection visible("vis", PLATFORM_ANY, 0);
257+
QVERIFY(!visible.isHidden());
258+
259+
// Other platform section.
260+
quint8 wrongPlatform = PLATFORM_ANY & ~Utils::CurrentPlatform();
261+
SettingsSection hidden("hid", wrongPlatform, 0);
262+
QVERIFY(hidden.isHidden());
263+
264+
// Explicitly hidden section
265+
SettingsSection explicitHidden("hideMe", PLATFORM_ANY, 0);
266+
explicitHidden.setHidden(true);
267+
QVERIFY(explicitHidden.isHidden());
268+
}
269+
270+
void TestSettings::testSectionOrder()
271+
{
272+
SettingsSection section("mySection", PLATFORM_ANY, 5);
273+
QVariantMap order = section.sectionOrder();
274+
QCOMPARE(order["key"].toString(), QString("mySection"));
275+
QCOMPARE(order["order"].toInt(), 5);
276+
}
277+
278+
void TestSettings::testValuesUpdatedSignalOnReset()
279+
{
280+
SettingsSection section("testSection", PLATFORM_ANY, 0);
281+
auto* sv = new SettingsValue("delta", 42);
282+
sv->setHasDescription(true);
283+
section.registerSetting(sv);
284+
285+
// Change from default.
286+
sv->setValue(99);
287+
288+
QSignalSpy spy(&section, &SettingsSection::valuesUpdated);
289+
section.resetValue("delta");
290+
291+
QCOMPARE(spy.count(), 1);
292+
QVariantMap updated = spy.at(0).at(0).toMap();
293+
QVERIFY(updated.contains("delta"));
294+
QCOMPARE(updated["delta"], QVariant(42));
295+
}
296+
297+
QTEST_APPLESS_MAIN(TestSettings)
298+
#include "test_settings.moc"

0 commit comments

Comments
 (0)