@@ -74,3 +74,118 @@ TEST_CASE("operator<< for rank-0 current_dims_t prints n/a") {
7474 oss << dims;
7575 CHECK (oss.str ().find (" n/a" ) != std::string::npos);
7676}
77+
78+ // ---------------------------------------------------------------------------
79+ // Handle pretty-printers — fd_t / ds_t / gr_t / at_t / dcpl_t / fapl_t plus
80+ // the generic hid_t<...> printer and the invalid-handle (valid=no) branches.
81+ // These exercise H5cout.hpp:138-444, previously uncovered.
82+ // ---------------------------------------------------------------------------
83+
84+ TEST_CASE (" operator<< for fd_t prints path and mode" ) {
85+ h5::test::file_fixture_t f (" test-cout-fd.h5" );
86+ std::ostringstream oss;
87+ oss << f.fd ;
88+ const std::string s = oss.str ();
89+ CHECK (s.find (" fd_t" ) != std::string::npos);
90+ CHECK (s.find (" path='" ) != std::string::npos);
91+ CHECK (s.find (" mode=" ) != std::string::npos);
92+ CHECK (s.find (" size=" ) != std::string::npos);
93+ }
94+
95+ TEST_CASE (" operator<< for ds_t prints chunk dims and filter count" ) {
96+ h5::test::file_fixture_t f (" test-cout-ds.h5" );
97+ h5::ds_t ds = h5::create<int >(f.fd , " chunked" ,
98+ h5::current_dims_t {100 }, h5::chunk{10 } | h5::gzip{6 });
99+ std::ostringstream oss;
100+ oss << ds;
101+ const std::string s = oss.str ();
102+ CHECK (s.find (" ds_t" ) != std::string::npos);
103+ CHECK (s.find (" dtype=INTEGER" ) != std::string::npos);
104+ CHECK (s.find (" layout=CHUNKED" ) != std::string::npos);
105+ CHECK (s.find (" chunk={10}" ) != std::string::npos);
106+ CHECK (s.find (" filters=" ) != std::string::npos);
107+ }
108+
109+ TEST_CASE (" operator<< for gr_t prints path and child count" ) {
110+ h5::test::file_fixture_t f (" test-cout-gr.h5" );
111+ h5::gr_t gr = h5::gcreate (f.fd , " sensors" );
112+ h5::gr_t child = h5::gcreate (gr, " imu" );
113+ (void ) child;
114+ std::ostringstream oss;
115+ oss << gr;
116+ const std::string s = oss.str ();
117+ CHECK (s.find (" gr_t" ) != std::string::npos);
118+ CHECK (s.find (" path='/sensors'" ) != std::string::npos);
119+ CHECK (s.find (" children=1" ) != std::string::npos);
120+ }
121+
122+ TEST_CASE (" operator<< for at_t prints attribute name" ) {
123+ h5::test::file_fixture_t f (" test-cout-at.h5" );
124+ h5::ds_t ds = h5::create<int >(f.fd , " ds" , h5::current_dims_t {1 });
125+ h5::awrite (ds, " units" , 42 );
126+ h5::at_t at{H5Aopen (static_cast <hid_t >(ds), " units" , H5P_DEFAULT)};
127+ std::ostringstream oss;
128+ oss << at;
129+ const std::string s = oss.str ();
130+ CHECK (s.find (" at_t" ) != std::string::npos);
131+ CHECK (s.find (" name='units'" ) != std::string::npos);
132+ CHECK (s.find (" dtype=INTEGER" ) != std::string::npos);
133+ }
134+
135+ TEST_CASE (" operator<< for dcpl_t prints layout, alloc, fill and filter pipeline" ) {
136+ h5::test::file_fixture_t f (" test-cout-dcpl.h5" );
137+ h5::ds_t ds = h5::create<int >(f.fd , " chunked" ,
138+ h5::current_dims_t {100 }, h5::chunk{10 } | h5::gzip{6 });
139+ h5::dcpl_t dcpl{H5Dget_create_plist (static_cast <hid_t >(ds))};
140+ std::ostringstream oss;
141+ oss << dcpl;
142+ const std::string s = oss.str ();
143+ CHECK (s.find (" dcpl_t" ) != std::string::npos);
144+ CHECK (s.find (" layout=CHUNKED" ) != std::string::npos);
145+ CHECK (s.find (" chunk={10}" ) != std::string::npos);
146+ CHECK (s.find (" alloc=" ) != std::string::npos);
147+ CHECK (s.find (" fill=" ) != std::string::npos);
148+ CHECK (s.find (" filters=[" ) != std::string::npos);
149+ }
150+
151+ TEST_CASE (" operator<< for fapl_t prints libver and cache config" ) {
152+ h5::fapl_t fapl{H5Pcreate (H5P_FILE_ACCESS)};
153+ std::ostringstream oss;
154+ oss << fapl;
155+ const std::string s = oss.str ();
156+ CHECK (s.find (" fapl_t" ) != std::string::npos);
157+ CHECK (s.find (" libver=[" ) != std::string::npos);
158+ CHECK (s.find (" cache={" ) != std::string::npos);
159+ }
160+
161+ TEST_CASE (" operator<< generic handle printer covers an unspecialized handle" ) {
162+ // lcpl_t has no dedicated specialization, so it routes through the
163+ // generic hid_t<...> printer and the class_tag<lcpl_t> specialization.
164+ h5::lcpl_t lcpl{H5Pcreate (H5P_LINK_CREATE)};
165+ std::ostringstream oss;
166+ oss << lcpl;
167+ const std::string s = oss.str ();
168+ CHECK (s.find (" lcpl_t" ) != std::string::npos);
169+ CHECK (s.find (" valid=yes" ) != std::string::npos);
170+ CHECK (s.find (" refs=" ) != std::string::npos);
171+ }
172+
173+ TEST_CASE (" operator<< prints valid=no for default-constructed (uninitialized) handles" ) {
174+ h5::fd_t fd;
175+ h5::ds_t ds;
176+ h5::gr_t gr;
177+ h5::at_t at;
178+ h5::dcpl_t dcpl;
179+ h5::fapl_t fapl;
180+ h5::lcpl_t lcpl; // generic printer, invalid branch
181+ for (const std::string& s : {
182+ [&]{ std::ostringstream o; o << fd; return o.str (); }(),
183+ [&]{ std::ostringstream o; o << ds; return o.str (); }(),
184+ [&]{ std::ostringstream o; o << gr; return o.str (); }(),
185+ [&]{ std::ostringstream o; o << at; return o.str (); }(),
186+ [&]{ std::ostringstream o; o << dcpl; return o.str (); }(),
187+ [&]{ std::ostringstream o; o << fapl; return o.str (); }(),
188+ [&]{ std::ostringstream o; o << lcpl; return o.str (); }() }) {
189+ CHECK (s.find (" valid=no" ) != std::string::npos);
190+ }
191+ }
0 commit comments