@@ -58,100 +58,182 @@ TEST_CASE_FIXTURE(
5858 CHECK_EQ (storage (sut).size (), constants::n_hyperedges - 1uz);
5959}
6060
61- TEST_CASE_FIXTURE (test_undirected_hyperedge_list, " hyperedge_size should return 0 by default" ) {
61+ TEST_CASE_FIXTURE (
62+ test_undirected_hyperedge_list, " incident_vertices should remove an empty view by default"
63+ ) {
6264 sut_type sut{constants::n_vertices, constants::n_hyperedges};
6365 CHECK (std::ranges::all_of (constants::hyperedge_ids_view, [&sut](const auto hyperedge_id) {
64- return sut.hyperedge_size (hyperedge_id) == 0uz ;
66+ return std::ranges::empty ( sut.incident_vertices (hyperedge_id)) ;
6567 }));
6668}
6769
68- TEST_CASE_FIXTURE (
69- test_undirected_hyperedge_list, " hyperedge_vertices should remove an empty view by default"
70- ) {
70+ TEST_CASE_FIXTURE (test_undirected_hyperedge_list, " hyperedge_size should return 0 by default" ) {
7171 sut_type sut{constants::n_vertices, constants::n_hyperedges};
7272 CHECK (std::ranges::all_of (constants::hyperedge_ids_view, [&sut](const auto hyperedge_id) {
73- return std::ranges::empty ( sut.hyperedge_vertices (hyperedge_id)) ;
73+ return sut.hyperedge_size (hyperedge_id) == 0uz ;
7474 }));
7575}
7676
7777TEST_CASE_FIXTURE (
7878 test_undirected_hyperedge_list,
79- " bind(hyperedge, vertex) should add the vertex to the given hyperedge's storage only if the "
80- " they are not bound"
79+ " bind should add the vertex to the given hyperedge's storage only if the they are not bound"
8180) {
8281 sut_type sut{constants::n_vertices, constants::n_hyperedges};
83- REQUIRE (std::ranges::empty (sut.hyperedge_vertices (constants::id1)));
82+ REQUIRE (std::ranges::empty (sut.incident_vertices (constants::id1)));
8483
8584 sut.bind (constants::id1, constants::id1);
86- const auto vertices1 = sut.hyperedge_vertices (constants::id1) | std::ranges::to<std::vector>();
85+ const auto vertices1 = sut.incident_vertices (constants::id1) | std::ranges::to<std::vector>();
8786 CHECK_EQ (sut.hyperedge_size (constants::id1), 1uz);
8887 CHECK_EQ (std::ranges::size (vertices1), 1uz);
8988 CHECK (std::ranges::contains (vertices1, constants::id1));
9089 CHECK (std::ranges::equal (vertices1, storage (sut)[constants::id1]));
9190
9291 sut.bind (constants::id1, constants::id1);
93- const auto vertices2 = sut.hyperedge_vertices (constants::id1) | std::ranges::to<std::vector>();
92+ const auto vertices2 = sut.incident_vertices (constants::id1) | std::ranges::to<std::vector>();
9493 CHECK_EQ (std::ranges::size (vertices2), 1uz);
9594 CHECK (std::ranges::equal (vertices2, vertices1));
9695}
9796
9897TEST_CASE_FIXTURE (
9998 test_undirected_hyperedge_list,
100- " unbind(hyperedge, vertex) should remove the vertex from the given hyperedge's storage only if "
101- " the they are bound"
99+ " unbind should remove the vertex from the given hyperedge's storage only if the they are bound"
102100) {
103101 sut_type sut{constants::n_vertices, constants::n_hyperedges};
104- REQUIRE (std::ranges::empty (sut.hyperedge_vertices (constants::id1)));
102+ REQUIRE (std::ranges::empty (sut.incident_vertices (constants::id1)));
105103
106104 sut.bind (constants::id1, constants::id1);
107- const auto vertices1 = sut.hyperedge_vertices (constants::id1) | std::ranges::to<std::vector>();
105+ const auto vertices1 = sut.incident_vertices (constants::id1) | std::ranges::to<std::vector>();
108106 REQUIRE_EQ (sut.hyperedge_size (constants::id1), 1uz);
109107 REQUIRE (std::ranges::contains (vertices1, constants::id1));
110108
111109 sut.unbind (constants::id1, constants::id2);
112- const auto vertices2 = sut.hyperedge_vertices (constants::id1) | std::ranges::to<std::vector>();
110+ const auto vertices2 = sut.incident_vertices (constants::id1) | std::ranges::to<std::vector>();
113111 REQUIRE_EQ (std::ranges::size (vertices2), 1uz);
114112 REQUIRE (std::ranges::equal (vertices2, vertices1));
115113
116114 sut.unbind (constants::id1, constants::id1);
117- CHECK (std::ranges::empty (sut.hyperedge_vertices (constants::id1)));
115+ CHECK (std::ranges::empty (sut.incident_vertices (constants::id1)));
118116}
119117
120118TEST_CASE_FIXTURE (
121119 test_undirected_hyperedge_list,
122- " are_bound(hyperedge, vertex) should return true only when the given vertex is present in the "
123- " hyperedge's storage"
120+ " are_bound should return true only when the given vertex is present in the hyperedge's storage"
124121) {
125122 sut_type sut{constants::n_vertices, constants::n_hyperedges};
126- REQUIRE (std::ranges::empty (sut.hyperedge_vertices (constants::id1)));
123+ REQUIRE (std::ranges::empty (sut.incident_vertices (constants::id1)));
127124
128125 sut.bind (constants::id1, constants::id1);
129- const auto vertices1 = sut.hyperedge_vertices (constants::id1) | std::ranges::to<std::vector>();
130126 REQUIRE_EQ (sut.hyperedge_size (constants::id1), 1uz);
131- REQUIRE (std::ranges::contains (vertices1 , constants::id1));
127+ REQUIRE (std::ranges::contains (sut. incident_vertices (constants::id1) , constants::id1));
132128
133129 CHECK (sut.are_bound (constants::id1, constants::id1));
134130 CHECK_FALSE (sut.are_bound (constants::id1, constants::id2));
135131 CHECK_FALSE (sut.are_bound (constants::id2, constants::id1));
136132}
137133
134+ TEST_CASE_FIXTURE (test_undirected_hyperedge_list, " add_vertices should do nothing" ) {
135+ sut_type sut{};
136+ sut.add_vertices (constants::n_vertices);
137+ CHECK (storage (sut).empty ());
138+ }
139+
140+ TEST_CASE_FIXTURE (
141+ test_undirected_hyperedge_list,
142+ " remove_vertex should properly unbind (if necessary) the given vertex and align ids > vertex_id"
143+ ) {
144+ constexpr hgl::types::size_type n_vertices = 4uz, n_hyperedges = 1uz;
145+ constexpr hgl::types::id_type hyperedge_id = constants::id1;
146+
147+ sut_type sut{n_vertices, n_hyperedges};
148+ sut.bind (constants::id2, hyperedge_id);
149+ sut.bind (constants::id4, hyperedge_id);
150+
151+ hgl::types::id_type rem_vid;
152+ std::vector<hgl::types::id_type> expected_vertices;
153+
154+ SUBCASE (" not present vertex < first incident vertex" ) {
155+ rem_vid = constants::id1;
156+ expected_vertices = {constants::id2 - 1uz, constants::id4 - 1uz};
157+ }
158+
159+ SUBCASE (" present vertex = first incident vertex" ) {
160+ rem_vid = constants::id2;
161+ expected_vertices = {constants::id4 - 1uz};
162+ }
163+
164+ SUBCASE (" not present vertex > first incident vertex" ) {
165+ rem_vid = constants::id3;
166+ expected_vertices = {constants::id2, constants::id4 - 1uz};
167+ }
168+
169+ SUBCASE (" present vertex = last incident vertex" ) {
170+ rem_vid = constants::id4;
171+ expected_vertices = {constants::id2};
172+ }
173+
174+ SUBCASE (" not present vertex > last incident vertex" ) {
175+ rem_vid = constants::id4 + 1uz;
176+ expected_vertices = {constants::id2, constants::id4};
177+ }
178+
179+ CAPTURE (rem_vid);
180+ CAPTURE (expected_vertices);
181+
182+ sut.remove_vertex (rem_vid);
183+ CHECK (std::ranges::equal (sut.incident_vertices (hyperedge_id), expected_vertices));
184+ }
185+
138186TEST_CASE_FIXTURE (
139187 test_undirected_hyperedge_list,
140- " remove_vertex should unbind the given vertex from all hyperedges"
188+ " remove_vertex should unbind the given vertex from all hyperedges and align ids > vertex_id "
141189) {
142190 sut_type sut{constants::n_vertices, constants::n_hyperedges};
143- for (const auto hyperedge_id : constants::hyperedge_ids_view)
144- sut.bind (hyperedge_id, constants::id1);
191+ for (const auto vid : constants::vertex_ids_view)
192+ for (const auto heid : constants::hyperedge_ids_view)
193+ sut.bind (vid, heid);
194+
195+ constexpr auto vertex_id = constants::id1;
145196 REQUIRE (std::ranges::all_of (constants::hyperedge_ids_view, [&sut](const auto hyperedge_id) {
146- return sut.are_bound (hyperedge_id, constants::id1 );
197+ return sut.are_bound (vertex_id, hyperedge_id );
147198 }));
148199
149- sut.remove_vertex (constants::id1 );
200+ sut.remove_vertex (vertex_id );
150201 CHECK (std::ranges::all_of (constants::hyperedge_ids_view, [&sut](const auto hyperedge_id) {
151- return std::ranges::empty (sut.hyperedge_vertices (hyperedge_id));
202+ return std::ranges::equal (
203+ sut.incident_vertices (hyperedge_id),
204+ std::views::iota (constants::id1, constants::n_vertices - 1uz)
205+ );
152206 }));
153207}
154208
209+ TEST_CASE_FIXTURE (
210+ test_undirected_hyperedge_list,
211+ " incident_hyperedges should return a view of the vertex's incident hyperedge ids"
212+ ) {
213+ sut_type sut{constants::n_vertices, constants::n_hyperedges};
214+
215+ constexpr auto vertex_id = constants::id1;
216+ REQUIRE (std::ranges::empty (sut.incident_hyperedges (vertex_id)));
217+
218+ for (const auto hyperedge_id : constants::hyperedge_ids_view)
219+ sut.bind (vertex_id, hyperedge_id);
220+ CHECK (std::ranges::equal (sut.incident_hyperedges (vertex_id), constants::hyperedge_ids_view));
221+ }
222+
223+ TEST_CASE_FIXTURE (
224+ test_undirected_hyperedge_list,
225+ " degree should return the number of the vertex's incident hyperedges"
226+ ) {
227+ sut_type sut{constants::n_vertices, constants::n_hyperedges};
228+
229+ constexpr auto vertex_id = constants::id1;
230+ REQUIRE_EQ (sut.degree (vertex_id), 0uz);
231+
232+ for (const auto hyperedge_id : constants::hyperedge_ids_view)
233+ sut.bind (vertex_id, hyperedge_id);
234+ CHECK_EQ (sut.degree (vertex_id), constants::n_hyperedges);
235+ }
236+
155237TEST_SUITE_END (); // test_hyperedge_list
156238
157239} // namespace hgl_testing
0 commit comments