2525namespace tmp {
2626namespace {
2727
28- // / Returns whether the underlying raw file device object is open
29- bool is_open (const file& file) {
30- std::filebuf* filebuf = dynamic_cast <std::filebuf*>(file.rdbuf ());
31- return filebuf != nullptr && filebuf->is_open ();
32- }
28+ // / Test fixture for `basic_file` tests
29+ template <class charT > class file : public testing ::Test {
30+ public:
31+ // / Returns whether the file device object is open
32+ bool is_open (const std::basic_streambuf<charT>* streambuf) {
33+ auto filebuf = dynamic_cast <const std::basic_filebuf<charT>*>(streambuf);
34+ return filebuf != nullptr && filebuf->is_open ();
35+ }
3336
34- // / Checks if the given file handle is valid
35- // / @param handle handle to check
36- // / @returns whether the handle is valid
37- bool is_open (file::native_handle_type handle) {
37+ // / Returns whether the given file handle is open
38+ bool is_open (typename basic_file<charT>::native_handle_type handle) {
3839#ifdef _WIN32
39- BY_HANDLE_FILE_INFORMATION info;
40- return GetFileInformationByHandle (handle, &info);
40+ BY_HANDLE_FILE_INFORMATION info;
41+ return GetFileInformationByHandle (handle, &info);
4142#else
42- return fcntl (handle, F_GETFD) != -1 ;
43+ return fcntl (handle, F_GETFD) != -1 ;
4344#endif
44- }
45+ }
46+
47+ // / Converts the string to the `charT` string type
48+ constexpr std::basic_string<charT> convert_string (std::string_view string) {
49+ std::basic_string<charT> result;
50+
51+ for (char character : string) {
52+ result += static_cast <charT>(character);
53+ }
54+
55+ return result;
56+ }
57+ };
58+
59+ // / Name generator for typed test suite
60+ struct name_generator {
61+ template <typename T> static std::string GetName (int ) {
62+ return typeid (T).name ();
63+ }
64+ };
65+
66+ using char_types = testing::Types<char , wchar_t >;
67+ TYPED_TEST_SUITE (file, char_types, name_generator);
4568
4669// / Tests file type traits and member types
47- TEST (file, type_traits) {
48- using traits = std::char_traits<char >;
49-
50- static_assert (std::is_base_of_v<std::basic_iostream<char >, file>);
51- static_assert (std::is_same_v<file::char_type, char >);
52- static_assert (std::is_same_v<file::traits_type, traits>);
53- static_assert (std::is_same_v<file::int_type, traits::int_type>);
54- static_assert (std::is_same_v<file::pos_type, traits::pos_type>);
55- static_assert (std::is_same_v<file::off_type, traits::off_type>);
70+ TYPED_TEST (file, type_traits) {
71+ using traits = std::char_traits<TypeParam>;
72+ using file_t = basic_file<TypeParam>;
73+ using testing::StaticAssertTypeEq;
74+
75+ static_assert (std::is_base_of_v<std::basic_iostream<TypeParam>, file_t >);
76+ StaticAssertTypeEq<typename file_t ::char_type, TypeParam>();
77+ StaticAssertTypeEq<typename file_t ::traits_type, traits>();
78+ StaticAssertTypeEq<typename file_t ::int_type, typename traits::int_type>();
79+ StaticAssertTypeEq<typename file_t ::pos_type, typename traits::pos_type>();
80+ StaticAssertTypeEq<typename file_t ::off_type, typename traits::off_type>();
5681}
5782
5883// / Tests file creation
59- TEST (file, create) {
60- file tmpfile = file ();
61- EXPECT_TRUE (is_open (tmpfile));
62- EXPECT_TRUE (is_open (tmpfile.native_handle ()));
84+ TYPED_TEST (file, create) {
85+ basic_file<TypeParam> tmpfile = basic_file<TypeParam> ();
86+ EXPECT_TRUE (TestFixture:: is_open (tmpfile. rdbuf () ));
87+ EXPECT_TRUE (TestFixture:: is_open (tmpfile.native_handle ()));
6388}
6489
6590// / Tests multiple file creation
66- TEST (file, create_multiple) {
67- file fst = file ();
68- file snd = file ();
91+ TYPED_TEST (file, create_multiple) {
92+ basic_file<TypeParam> fst = basic_file<TypeParam> ();
93+ basic_file<TypeParam> snd = basic_file<TypeParam> ();
6994
7095 EXPECT_NE (fst.native_handle (), snd.native_handle ());
7196}
7297
7398// / Tests file open mode
74- TEST (file, openmode) {
75- file tmpfile = file ();
99+ TYPED_TEST (file, openmode) {
100+ basic_file<TypeParam> tmpfile = basic_file<TypeParam> ();
76101 tmpfile << " Hello, World!" << std::flush;
77102 tmpfile.seekg (0 );
78103 tmpfile << " Goodbye!" << std::flush;
@@ -83,72 +108,72 @@ TEST(file, openmode) {
83108}
84109
85110// / Tests that destructor removes a file
86- TEST (file, destructor) {
87- file ::native_handle_type handle;
111+ TYPED_TEST (file, destructor) {
112+ typename basic_file<TypeParam> ::native_handle_type handle;
88113
89114 {
90- file tmpfile = file ();
115+ basic_file<TypeParam> tmpfile = basic_file<TypeParam> ();
91116 handle = tmpfile.native_handle ();
92117 }
93118
94- EXPECT_FALSE (is_open (handle));
119+ EXPECT_FALSE (TestFixture:: is_open (handle));
95120}
96121
97122// / Tests file move constructor
98- TEST (file, move_constructor) {
99- file fst = file ();
123+ TYPED_TEST (file, move_constructor) {
124+ basic_file<TypeParam> fst = basic_file<TypeParam> ();
100125 fst << " Hello!" ;
101126
102- file snd = file (std::move (fst));
127+ basic_file<TypeParam> snd = basic_file<TypeParam> (std::move (fst));
103128
104- EXPECT_TRUE (is_open (snd));
129+ EXPECT_TRUE (TestFixture:: is_open (snd. rdbuf () ));
105130
106131 snd.seekg (0 );
107- std::string content;
132+ std::basic_string<TypeParam> content;
108133 snd >> content;
109- EXPECT_EQ (content, " Hello!" );
134+ EXPECT_EQ (content, TestFixture::convert_string ( " Hello!" ) );
110135}
111136
112137// / Tests file move assignment operator
113- TEST (file, move_assignment) {
114- file fst = file ();
138+ TYPED_TEST (file, move_assignment) {
139+ basic_file<TypeParam> fst = basic_file<TypeParam> ();
115140
116141 {
117- file snd = file ();
142+ basic_file<TypeParam> snd = basic_file<TypeParam> ();
118143 snd << " Hello!" ;
119144
120- file ::native_handle_type fst_handle = fst.native_handle ();
121- file ::native_handle_type snd_handle = snd.native_handle ();
145+ typename decltype (fst) ::native_handle_type fst_handle = fst.native_handle ();
146+ typename decltype (snd) ::native_handle_type snd_handle = snd.native_handle ();
122147
123148 fst = std::move (snd);
124149
125- EXPECT_FALSE (is_open (fst_handle));
126- EXPECT_TRUE (is_open (snd_handle));
150+ EXPECT_FALSE (TestFixture:: is_open (fst_handle));
151+ EXPECT_TRUE (TestFixture:: is_open (snd_handle));
127152 EXPECT_EQ (fst.native_handle (), snd_handle);
128153 }
129154
130- EXPECT_TRUE (is_open (fst));
155+ EXPECT_TRUE (TestFixture:: is_open (fst. rdbuf () ));
131156
132157 fst.seekg (0 );
133- std::string content;
158+ std::basic_string<TypeParam> content;
134159 fst >> content;
135- EXPECT_EQ (content, " Hello!" );
160+ EXPECT_EQ (content, TestFixture::convert_string ( " Hello!" ) );
136161}
137162
138163// / Tests file swapping
139- TEST (file, swap) {
140- file fst = file ();
141- file snd = file ();
164+ TYPED_TEST (file, swap) {
165+ basic_file<TypeParam> fst = basic_file<TypeParam> ();
166+ basic_file<TypeParam> snd = basic_file<TypeParam> ();
142167
143- file ::native_handle_type fst_handle = fst.native_handle ();
144- file ::native_handle_type snd_handle = snd.native_handle ();
168+ typename decltype (fst) ::native_handle_type fst_handle = fst.native_handle ();
169+ typename decltype (snd) ::native_handle_type snd_handle = snd.native_handle ();
145170
146171 std::swap (fst, snd);
147172
148173 EXPECT_EQ (fst.native_handle (), snd_handle);
149174 EXPECT_EQ (snd.native_handle (), fst_handle);
150- EXPECT_TRUE (is_open (fst));
151- EXPECT_TRUE (is_open (snd));
175+ EXPECT_TRUE (TestFixture:: is_open (fst. rdbuf () ));
176+ EXPECT_TRUE (TestFixture:: is_open (snd. rdbuf () ));
152177}
153178} // namespace
154179} // namespace tmp
0 commit comments