• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 18246927847

04 Oct 2025 04:44PM UTC coverage: 71.826% (+0.6%) from 71.188%
18246927847

push

github

paulmthompson
refactor out media producer consumer pipeline

0 of 120 new or added lines in 2 files covered. (0.0%)

646 existing lines in 14 files now uncovered.

48895 of 68074 relevant lines covered (71.83%)

1193.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.16
/src/WhiskerToolbox/GroupManagementWidget/GroupManagementWidget.test.cpp
1
#include "GroupManagementWidget.hpp"
2
#include "Entity/EntityGroupManager.hpp"
3
#include "DataManager/DataManager.hpp"
4
#include "GroupManager.hpp"
5

6
#include <catch2/catch_test_macros.hpp>
7

8
#include <QApplication>
9
#include <QTableWidget>
10
#include <QCheckBox>
11

12
#include <optional>
13
#include <unordered_set>
14

15
namespace {
16
// Match TableDesignerWidget test pattern: own a QApplication via fixture to avoid exit-order issues
17
class GroupManagementWidgetQtFixture {
18
protected:
19
    GroupManagementWidgetQtFixture() {
4✔
20
        if (!QApplication::instance()) {
4✔
21
            qputenv("QT_QPA_PLATFORM", QByteArray("offscreen"));
4✔
22
            int argc = 0;
4✔
23
            char ** argv = nullptr;
4✔
24
            app = std::make_unique<QApplication>(argc, argv);
4✔
25
        }
26
    }
4✔
27

28
    ~GroupManagementWidgetQtFixture() = default;
4✔
29

30
private:
31
    std::unique_ptr<QApplication> app;
32
};
33

34
QTableWidget * findGroupsTable(GroupManagementWidget & widget) {
4✔
35
    auto * table = widget.findChild<QTableWidget *>("groupsTable");
8✔
36
    REQUIRE(table != nullptr);
4✔
37
    return table;
4✔
38
}
39

40
int findRowForGroupId(QTableWidget * table, int group_id) {
6✔
41
    for (int row = 0; row < table->rowCount(); ++row) {
6✔
42
        QTableWidgetItem * item = table->item(row, 0);
6✔
43
        if (item && item->data(Qt::UserRole).toInt() == group_id) {
6✔
44
            return row;
6✔
45
        }
46
    }
UNCOV
47
    return -1;
×
48
}
49
}// namespace
50

51
TEST_CASE_METHOD(GroupManagementWidgetQtFixture, "GroupManagementWidget - Rows update on group CRUD", "[groupmanagementwidget][rows]") {
1✔
52
    EntityGroupManager egm;
1✔
53
    auto dm = std::make_shared<DataManager>();
1✔
54
    GroupManager gm(&egm, dm);
1✔
55
    GroupManagementWidget widget(&gm);
1✔
56

57
    auto * table = findGroupsTable(widget);
1✔
58
    QCoreApplication::processEvents();
1✔
59
    REQUIRE(table->rowCount() == 0);
1✔
60

61
    int g1 = gm.createGroup(QString("A"));
1✔
62
    int g2 = gm.createGroup(QString("B"));
1✔
63
    QCoreApplication::processEvents();
1✔
64
    REQUIRE(table->rowCount() == 2);
1✔
65

66
    REQUIRE(gm.removeGroup(g1));
1✔
67
    QCoreApplication::processEvents();
1✔
68
    REQUIRE(table->rowCount() == 1);
1✔
69
}
2✔
70

71
TEST_CASE_METHOD(GroupManagementWidgetQtFixture, "GroupManagementWidget - Member counts update after assignments (via groupModified)", "[groupmanagementwidget][members]") {
1✔
72
    EntityGroupManager egm;
1✔
73
    auto dm = std::make_shared<DataManager>();
1✔
74
    GroupManager gm(&egm, dm);
1✔
75
    GroupManagementWidget widget(&gm);
1✔
76
    auto * table = findGroupsTable(widget);
1✔
77

78
    int g = gm.createGroup(QString("M"));
1✔
79
    GroupId gid = static_cast<GroupId>(g);
1✔
80
    QCoreApplication::processEvents();
1✔
81
    REQUIRE(table->rowCount() == 1);
1✔
82

83
    // Assign entities using GroupManager API
84
    std::unordered_set<EntityId> ids = {1, 2, 3};
3✔
85
    REQUIRE(gm.assignEntitiesToGroup(g, ids));
1✔
86

87
    // Force UI refresh of member counts via a groupModified signal
88
    QColor c(12, 34, 56);
1✔
89
    REQUIRE(gm.setGroupColor(g, c));
1✔
90
    QCoreApplication::processEvents();
1✔
91

92
    int row = findRowForGroupId(table, g);
1✔
93
    REQUIRE(row >= 0);
1✔
94
    QTableWidgetItem * members_item = table->item(row, 3);
1✔
95
    REQUIRE(members_item != nullptr);
1✔
96
    REQUIRE(members_item->text().toInt() == 3);
1✔
97

98
    // Remove a subset
99
    std::unordered_set<EntityId> rem = {2};
3✔
100
    REQUIRE(gm.removeEntitiesFromGroup(g, rem));
1✔
101

102
    // Trigger another UI update through group rename
103
    REQUIRE(gm.setGroupName(g, QString("M2")));
1✔
104
    QCoreApplication::processEvents();
1✔
105

106
    row = findRowForGroupId(table, g);
1✔
107
    REQUIRE(row >= 0);
1✔
108
    members_item = table->item(row, 3);
1✔
109
    REQUIRE(members_item != nullptr);
1✔
110
    REQUIRE(members_item->text().toInt() == 2);
1✔
111
}
2✔
112

113
TEST_CASE_METHOD(GroupManagementWidgetQtFixture, "GroupManagementWidget - Members column updates on add/remove", "[groupmanagementwidget][members][signals]") {
1✔
114
    EntityGroupManager egm;
1✔
115
    auto dm = std::make_shared<DataManager>();
1✔
116
    GroupManager gm(&egm, dm);
1✔
117
    GroupManagementWidget widget(&gm);
1✔
118
    auto * table = findGroupsTable(widget);
1✔
119

120
    int g = gm.createGroup(QString("G"));
1✔
121
    GroupId gid = static_cast<GroupId>(g);
1✔
122
    QCoreApplication::processEvents();
1✔
123
    REQUIRE(table->rowCount() == 1);
1✔
124

125
    int row = findRowForGroupId(table, g);
1✔
126
    REQUIRE(row >= 0);
1✔
127
    QTableWidgetItem * members_item = table->item(row, 3);
1✔
128
    REQUIRE(members_item != nullptr);
1✔
129
    REQUIRE(members_item->text().toInt() == 0);
1✔
130

131
    // Add two entities and expect UI to refresh via groupModified
132
    std::unordered_set<EntityId> ids = {11, 22};
3✔
133
    REQUIRE(gm.assignEntitiesToGroup(g, ids));
1✔
134
    QCoreApplication::processEvents();
1✔
135
    row = findRowForGroupId(table, g);
1✔
136
    REQUIRE(row >= 0);
1✔
137
    members_item = table->item(row, 3);
1✔
138
    REQUIRE(members_item->text().toInt() == 2);
1✔
139

140
    // Remove one entity and expect decrement
141
    std::unordered_set<EntityId> rem = {11};
3✔
142
    REQUIRE(gm.removeEntitiesFromGroup(g, rem));
1✔
143
    QCoreApplication::processEvents();
1✔
144
    row = findRowForGroupId(table, g);
1✔
145
    REQUIRE(row >= 0);
1✔
146
    members_item = table->item(row, 3);
1✔
147
    REQUIRE(members_item->text().toInt() == 1);
1✔
148
}
2✔
149

150
TEST_CASE_METHOD(GroupManagementWidgetQtFixture, "GroupManagementWidget - Visibility column updates", "[groupmanagementwidget][visibility]") {
1✔
151
    EntityGroupManager egm;
1✔
152
    auto dm = std::make_shared<DataManager>();
1✔
153
    GroupManager gm(&egm, dm);
1✔
154
    GroupManagementWidget widget(&gm);
1✔
155
    auto * table = findGroupsTable(widget);
1✔
156

157
    int g = gm.createGroup(QString("TestGroup"));
1✔
158
    QCoreApplication::processEvents();
1✔
159
    REQUIRE(table->rowCount() == 1);
1✔
160

161
    int row = findRowForGroupId(table, g);
1✔
162
    REQUIRE(row >= 0);
1✔
163
    
164
    // Check that visibility checkbox exists and is checked by default
165
    auto * visibility_checkbox = qobject_cast<QCheckBox *>(table->cellWidget(row, 2));
1✔
166
    REQUIRE(visibility_checkbox != nullptr);
1✔
167
    REQUIRE(visibility_checkbox->isChecked() == true);
1✔
168

169
    // Toggle visibility
170
    visibility_checkbox->setChecked(false);
1✔
171
    QCoreApplication::processEvents();
1✔
172
    
173
    // Verify the group visibility was updated
174
    auto group = gm.getGroup(g);
1✔
175
    REQUIRE(group.has_value());
1✔
176
    REQUIRE(group->visible == false);
1✔
177

178
    // Toggle back to visible
179
    visibility_checkbox->setChecked(true);
1✔
180
    QCoreApplication::processEvents();
1✔
181
    
182
    group = gm.getGroup(g);
1✔
183
    REQUIRE(group.has_value());
1✔
184
    REQUIRE(group->visible == true);
1✔
185
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc