Skip to content

Commit f8c6524

Browse files
authored
DisplayManager tests (#1192)
1 parent 12ab4c8 commit f8c6524

4 files changed

Lines changed: 246 additions & 3 deletions

File tree

src/settings/SettingsComponent.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ void SettingsComponent::componentPostInitialize()
3535
InputComponent::Get().registerHostCommand("set_setting", this, "setSettingCommand");
3636
}
3737

38+
///////////////////////////////////////////////////////////////////////////////////////////////////
39+
void SettingsComponent::registerSection(SettingsSection* section)
40+
{
41+
m_sections.insert(section->sectionName(), section);
42+
}
43+
3844
/////////////////////////////////////////////////////////////////////////////////////////
3945
void SettingsComponent::cycleSettingCommand(const QString& args)
4046
{
@@ -281,7 +287,7 @@ void SettingsComponent::loadConf(const QString& path, bool storage)
281287
sec = new SettingsSection(section, PLATFORM_ANY, -1, this);
282288
sec->setHidden(true);
283289
sec->setStorage(true);
284-
m_sections.insert(section, sec);
290+
registerSection(sec);
285291
}
286292
else if (!sec)
287293
{
@@ -398,7 +404,7 @@ void SettingsComponent::setValues(const QVariantMap& options)
398404
section = new SettingsSection(key, PLATFORM_ANY, -1, this);
399405
section->setHidden(true);
400406
section->setStorage(true);
401-
m_sections.insert(key, section);
407+
registerSection(section);
402408
}
403409

404410
if (values.isNull())
@@ -620,7 +626,7 @@ void SettingsComponent::parseSection(const QJsonObject& sectionObject)
620626
section->registerSetting(setting);
621627
}
622628

623-
m_sections.insert(sectionName, section);
629+
registerSection(section);
624630
}
625631

626632
/////////////////////////////////////////////////////////////////////////////////////////

src/settings/SettingsComponent.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class SettingsComponent : public ComponentBase
102102
//
103103
static bool resetAndSaveOldConfiguration();
104104

105+
void registerSection(SettingsSection* section);
106+
105107
private:
106108
explicit SettingsComponent(QObject *parent = nullptr);
107109
bool loadDescription();

tests/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,9 @@ target_link_libraries(test_settings jmp_core Qt6::Test)
3333
target_include_directories(test_settings PRIVATE ${TEST_INCLUDE_DIRS})
3434
target_compile_definitions(test_settings PRIVATE ${TEST_COMPILE_DEFS})
3535
add_test(NAME test_settings COMMAND test_settings)
36+
37+
add_executable(test_displaymanager test_displaymanager.cpp)
38+
target_link_libraries(test_displaymanager jmp_core Qt6::Test)
39+
target_include_directories(test_displaymanager PRIVATE ${TEST_INCLUDE_DIRS})
40+
target_compile_definitions(test_displaymanager PRIVATE ${TEST_COMPILE_DEFS})
41+
add_test(NAME test_displaymanager COMMAND test_displaymanager)

tests/test_displaymanager.cpp

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
#include <QtTest/QtTest>
2+
#include "../src/display/DisplayManager.h"
3+
#include "../src/settings/SettingsComponent.h"
4+
#include "../src/settings/SettingsSection.h"
5+
#include "../src/settings/SettingsValue.h"
6+
7+
// Implements the pure virtuals (and some helpers) to test DisplayManager logic.
8+
class TestableDisplayManager : public DisplayManager
9+
{
10+
public:
11+
explicit TestableDisplayManager() : DisplayManager(nullptr), m_currentMode(0) {}
12+
13+
bool setDisplayMode(int, int) override { return true; }
14+
int getCurrentDisplayMode(int) override { return m_currentMode; }
15+
int getMainDisplay() override { return 0; }
16+
int getDisplayFromPoint(int, int) override { return 0; }
17+
18+
void setCurrentMode(int mode) { m_currentMode = mode; }
19+
20+
void addMode(int id, int w, int h, int bpp, float hz, bool interlaced)
21+
{
22+
auto mode = DMVideoModePtr::create();
23+
mode->m_id = id;
24+
mode->m_width = w;
25+
mode->m_height = h;
26+
mode->m_bitsPerPixel = bpp;
27+
mode->m_refreshRate = hz;
28+
mode->m_interlaced = interlaced;
29+
mode->m_privId = id;
30+
31+
if (!m_displays.contains(0))
32+
{
33+
auto disp = DMDisplayPtr::create();
34+
disp->m_id = 0;
35+
disp->m_name = "TestDisplay";
36+
disp->m_privId = 0;
37+
m_displays[0] = disp;
38+
}
39+
m_displays[0]->m_videoModes[id] = mode;
40+
}
41+
42+
private:
43+
int m_currentMode;
44+
};
45+
46+
47+
class TestDisplayManager : public QObject
48+
{
49+
Q_OBJECT
50+
51+
private:
52+
void setAvoid25_30(bool on)
53+
{
54+
auto* section = SettingsComponent::Get().getSection(SETTINGS_SECTION_VIDEO);
55+
section->setValue("refreshrate.avoid_25hz_30hz", on);
56+
}
57+
58+
private slots:
59+
void initTestCase();
60+
void testExactRefreshRateMatch();
61+
void testPrefers60HzOver30HzForFilm();
62+
void testCloseRefreshRateMatch();
63+
void testNoMatchWithDifferentResolution();
64+
void testInterlacedPreference();
65+
void testCurrentModeBonusBreaksTie();
66+
void testAvoid25And30Hz();
67+
void testNoSuitableModeReturnsNegative();
68+
void testFindBestMode();
69+
void testMultipleRefreshRate();
70+
};
71+
72+
// Helper function: Populates a DisplayManager with some typical display modes.
73+
static void setupStandardModes(TestableDisplayManager& mgr)
74+
{
75+
// id, w, h, bpp, hz, interlaced
76+
mgr.addMode(0, 1920, 1080, 32, 24.0f, false);
77+
mgr.addMode(1, 1920, 1080, 32, 30.0f, false);
78+
mgr.addMode(2, 1920, 1080, 32, 50.0f, false);
79+
mgr.addMode(3, 1920, 1080, 32, 60.0f, false); // This will be set as currentMode (see below)
80+
mgr.addMode(4, 1920, 1080, 32, 23.976f, false);
81+
mgr.addMode(5, 1920, 1080, 32, 59.94f, false);
82+
mgr.setCurrentMode(3);
83+
}
84+
85+
void TestDisplayManager::initTestCase()
86+
{
87+
auto* section = new SettingsSection(SETTINGS_SECTION_VIDEO, PLATFORM_ANY, -1,
88+
&SettingsComponent::Get());
89+
auto* avoidSetting = new SettingsValue("refreshrate.avoid_25hz_30hz",
90+
false, PLATFORM_ANY, section);
91+
section->registerSetting(avoidSetting);
92+
SettingsComponent::Get().registerSection(section);
93+
}
94+
95+
void TestDisplayManager::testExactRefreshRateMatch()
96+
{
97+
TestableDisplayManager mgr;
98+
setupStandardModes(mgr);
99+
DMMatchMediaInfo match(24.0f, false);
100+
101+
int best = mgr.findBestMatch(0, match);
102+
QCOMPARE(best, 0); // 24 hz mode
103+
}
104+
105+
void TestDisplayManager::testPrefers60HzOver30HzForFilm()
106+
{
107+
// Prefer 60 hz for 30 fps content.
108+
TestableDisplayManager mgr;
109+
setupStandardModes(mgr);
110+
DMMatchMediaInfo match(30.0f, false);
111+
112+
setAvoid25_30(true);
113+
int best = mgr.findBestMatch(0, match);
114+
QCOMPARE(best, 3);
115+
setAvoid25_30(false);
116+
}
117+
118+
void TestDisplayManager::testCloseRefreshRateMatch()
119+
{
120+
// Prefer 24hz for 23.976 fps content.
121+
TestableDisplayManager mgr;
122+
setupStandardModes(mgr);
123+
DMMatchMediaInfo match(23.976f, false);
124+
125+
int best = mgr.findBestMatch(0, match);
126+
QCOMPARE(best, 4);
127+
}
128+
129+
void TestDisplayManager::testNoMatchWithDifferentResolution()
130+
{
131+
// Prefer 1080p over 720p, regardless of framerate.
132+
TestableDisplayManager mgr;
133+
mgr.addMode(0, 1920, 1080, 32, 60.0f, false);
134+
mgr.addMode(1, 1280, 720, 32, 24.0f, false);
135+
mgr.setCurrentMode(0);
136+
137+
DMMatchMediaInfo match(24.0f, false);
138+
int best = mgr.findBestMatch(0, match);
139+
QCOMPARE(best, 0);
140+
}
141+
142+
void TestDisplayManager::testInterlacedPreference()
143+
{
144+
// Prefer interlaced mode for interlaced content.
145+
TestableDisplayManager mgr;
146+
mgr.addMode(0, 1920, 1080, 32, 50.0f, false);
147+
mgr.addMode(1, 1920, 1080, 32, 50.0f, true);
148+
mgr.setCurrentMode(0); // non-interlaced
149+
150+
DMMatchMediaInfo match(50.0f, true);
151+
int best = mgr.findBestMatch(0, match);
152+
QCOMPARE(best, 1);
153+
}
154+
155+
void TestDisplayManager::testCurrentModeBonusBreaksTie()
156+
{
157+
// Prefer current mode when multiple identical modes available.
158+
TestableDisplayManager mgr;
159+
mgr.addMode(0, 1920, 1080, 32, 60.0f, false);
160+
mgr.addMode(1, 1920, 1080, 32, 60.0f, false);
161+
mgr.setCurrentMode(1);
162+
163+
DMMatchMediaInfo match(60.0f, false);
164+
int best = mgr.findBestMatch(0, match);
165+
QCOMPARE(best, 1);
166+
}
167+
168+
void TestDisplayManager::testAvoid25And30Hz()
169+
{
170+
// Prefer 50 hz for 25 fps content when avoid25_30 is enabled.
171+
TestableDisplayManager mgr;
172+
mgr.addMode(0, 1920, 1080, 32, 25.0f, false);
173+
mgr.addMode(1, 1920, 1080, 32, 50.0f, false);
174+
mgr.setCurrentMode(1);
175+
176+
DMMatchMediaInfo match(25.0f, false);
177+
setAvoid25_30(true);
178+
int best = mgr.findBestMatch(0, match);
179+
QCOMPARE(best, 1);
180+
181+
// Disabling avoid25_30 should produce the opposite result.
182+
setAvoid25_30(false);
183+
best = mgr.findBestMatch(0, match);
184+
QCOMPARE(best, 0);
185+
}
186+
187+
void TestDisplayManager::testNoSuitableModeReturnsNegative()
188+
{
189+
// No preference when resolution doesn't match content.
190+
TestableDisplayManager mgr;
191+
mgr.addMode(0, 1920, 1080, 32, 60.0f, false);
192+
mgr.addMode(1, 1280, 720, 32, 24.0f, false);
193+
mgr.setCurrentMode(0);
194+
mgr.m_displays[0]->m_videoModes.remove(0);
195+
196+
DMMatchMediaInfo match(24.0f, false);
197+
int best = mgr.findBestMatch(0, match);
198+
199+
QCOMPARE(best, -1);
200+
}
201+
202+
void TestDisplayManager::testFindBestMode()
203+
{
204+
// Prefer greatest refresh rate, greatest resolution, and non-interlaced.
205+
TestableDisplayManager mgr;
206+
mgr.addMode(0, 1280, 720, 32, 60.0f, false);
207+
mgr.addMode(1, 1920, 1080, 32, 60.0f, false);
208+
mgr.addMode(2, 1920, 1080, 32, 30.0f, true);
209+
mgr.addMode(3, 1920, 1080, 32, 60.0f, true);
210+
211+
int best = mgr.findBestMode(0);
212+
QCOMPARE(best, 1);
213+
}
214+
215+
void TestDisplayManager::testMultipleRefreshRate()
216+
{
217+
// Prefer exact multiple of fps rate.
218+
TestableDisplayManager mgr;
219+
mgr.addMode(0, 1920, 1080, 32, 47.952f, false);
220+
mgr.addMode(1, 1920, 1080, 32, 60.0f, false);
221+
mgr.setCurrentMode(1);
222+
223+
DMMatchMediaInfo match(23.976f, false);
224+
int best = mgr.findBestMatch(0, match);
225+
QCOMPARE(best, 0);
226+
}
227+
228+
QTEST_APPLESS_MAIN(TestDisplayManager)
229+
#include "test_displaymanager.moc"

0 commit comments

Comments
 (0)