1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/base/win/open_file_name_win.h"
7 #include "base/files/file_path.h"
8 #include "testing/gtest/include/gtest/gtest.h"
11 const HWND kHwnd
= reinterpret_cast<HWND
>(0xDEADBEEF);
12 const DWORD kFlags
= OFN_OVERWRITEPROMPT
| OFN_EXPLORER
| OFN_ENABLESIZING
;
14 void SetResult(const base::string16
& result
, ui::win::OpenFileName
* ofn
) {
15 if (ofn
->GetOPENFILENAME()->nMaxFile
<= result
.size()) {
16 ADD_FAILURE() << "filename buffer insufficient.";
20 ofn
->GetOPENFILENAME()->lpstrFile
[0] = 0;
22 // Because the result has embedded nulls, we must memcpy.
23 memcpy(ofn
->GetOPENFILENAME()->lpstrFile
,
25 (result
.size() + 1) * sizeof(result
[0]));
30 const std::vector
<Tuple2
<base::string16
, base::string16
> >& expected
,
31 const std::vector
<Tuple2
<base::string16
, base::string16
> >& actual
) {
32 if (expected
.size() != actual
.size()) {
33 ADD_FAILURE() << "filter count mismatch. Got " << actual
.size()
34 << " expected " << expected
.size() << ".";
38 for (size_t i
= 0; i
< expected
.size(); ++i
) {
39 EXPECT_EQ(expected
[i
].a
, actual
[i
].a
) << "Mismatch at index " << i
;
40 EXPECT_EQ(expected
[i
].b
, actual
[i
].b
) << "Mismatch at index " << i
;
44 void CheckFilterString(const base::string16
& expected
,
45 const ui::win::OpenFileName
& ofn
) {
46 if (!ofn
.GetOPENFILENAME()->lpstrFilter
) {
47 ADD_FAILURE() << "Filter string is NULL.";
50 if (expected
.size() == 0) {
51 EXPECT_EQ(0, ofn
.GetOPENFILENAME()->lpstrFilter
[0]);
54 memcmp(expected
.c_str(),
55 ofn
.GetOPENFILENAME()->lpstrFilter
,
56 expected
.size() + 1 * sizeof(expected
[0])));
60 void CheckResult(const base::string16
& expected
,
61 const ui::win::OpenFileName
& ofn
) {
62 if (!ofn
.GetOPENFILENAME()->lpstrFile
) {
63 ADD_FAILURE() << "File string is NULL.";
66 if (expected
.size() == 0) {
67 EXPECT_EQ(0, ofn
.GetOPENFILENAME()->lpstrFile
[0]);
70 memcmp(expected
.c_str(),
71 ofn
.GetOPENFILENAME()->lpstrFile
,
72 expected
.size() + 1 * sizeof(expected
[0])));
78 TEST(OpenFileNameTest
, Initialization
) {
79 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
80 EXPECT_EQ(kHwnd
, ofn
.GetOPENFILENAME()->hwndOwner
);
81 EXPECT_EQ(kFlags
, ofn
.GetOPENFILENAME()->Flags
);
82 EXPECT_EQ(sizeof(OPENFILENAME
), ofn
.GetOPENFILENAME()->lStructSize
);
83 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
84 ASSERT_GT(ofn
.GetOPENFILENAME()->nMaxFile
, 0u);
85 EXPECT_EQ(0, ofn
.GetOPENFILENAME()->lpstrFile
[0]);
88 TEST(OpenFileNameTest
, SetInitialSelection
) {
89 const base::FilePath
kDirectory(L
"C:\\directory\\child_directory");
90 const base::FilePath
kFile(L
"file_name.ext");
91 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
92 ofn
.SetInitialSelection(kDirectory
, kFile
);
93 EXPECT_EQ(kDirectory
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrInitialDir
));
94 EXPECT_EQ(kFile
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
96 ofn
.SetInitialSelection(kDirectory
, base::FilePath());
97 EXPECT_EQ(kDirectory
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrInitialDir
));
98 // Filename buffer will still be a valid pointer, to receive a result.
99 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
100 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
102 ofn
.SetInitialSelection(base::FilePath(), base::FilePath());
103 // No initial directory will lead to a NULL buffer.
104 ASSERT_FALSE(ofn
.GetOPENFILENAME()->lpstrInitialDir
);
105 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
106 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
108 // Make sure that both values are cleared when directory is missing.
109 ofn
.SetInitialSelection(kDirectory
, kFile
);
110 EXPECT_EQ(kDirectory
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrInitialDir
));
111 EXPECT_EQ(kFile
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
112 ofn
.SetInitialSelection(base::FilePath(), base::FilePath());
113 ASSERT_FALSE(ofn
.GetOPENFILENAME()->lpstrInitialDir
);
114 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
115 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
117 // File is ignored in absence of a directory.
118 ofn
.SetInitialSelection(base::FilePath(), kFile
);
119 ASSERT_FALSE(ofn
.GetOPENFILENAME()->lpstrInitialDir
);
120 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
121 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
124 TEST(OpenFileNameTest
, GetSingleResultFromSingleSelect
) {
125 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
126 base::FilePath result
;
128 SetResult(L
"C:\\dir\\file", &ofn
);
129 result
= ofn
.GetSingleResult();
130 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
132 SetResult(L
"", &ofn
);
133 result
= ofn
.GetSingleResult();
134 EXPECT_EQ(base::FilePath(), result
);
137 TEST(OpenFileNameTest
, GetSingleResultFromMultiSelect
) {
138 const base::string16
kNull(L
"\0", 1);
139 ui::win::OpenFileName
ofn(kHwnd
, kFlags
| OFN_ALLOWMULTISELECT
);
140 base::FilePath result
;
142 SetResult(L
"C:\\dir\\file" + kNull
, &ofn
);
143 result
= ofn
.GetSingleResult();
144 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
146 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
, &ofn
);
147 result
= ofn
.GetSingleResult();
148 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
150 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, &ofn
);
151 result
= ofn
.GetSingleResult();
152 EXPECT_EQ(base::FilePath(), result
);
154 SetResult(L
"", &ofn
);
155 result
= ofn
.GetSingleResult();
156 EXPECT_EQ(base::FilePath(), result
);
159 TEST(OpenFileNameTest
, GetResult
) {
160 const base::string16
kNull(L
"\0", 1);
162 ui::win::OpenFileName
ofn(kHwnd
, kFlags
| OFN_ALLOWMULTISELECT
);
163 base::FilePath directory
;
164 std::vector
<base::FilePath
> filenames
;
166 SetResult(L
"C:\\dir\\file" + kNull
, &ofn
);
167 ofn
.GetResult(&directory
, &filenames
);
168 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
169 ASSERT_EQ(1u, filenames
.size());
170 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
175 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
, &ofn
);
176 ofn
.GetResult(&directory
, &filenames
);
177 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
178 ASSERT_EQ(1u, filenames
.size());
179 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
184 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, &ofn
);
185 ofn
.GetResult(&directory
, &filenames
);
186 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
187 ASSERT_EQ(2u, filenames
.size());
188 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
189 EXPECT_EQ(base::FilePath(L
"otherfile"), filenames
[1]);
194 SetResult(L
"", &ofn
);
195 ofn
.GetResult(&directory
, &filenames
);
196 EXPECT_EQ(base::FilePath(), directory
);
197 ASSERT_EQ(0u, filenames
.size());
200 TEST(OpenFileNameTest
, SetAndGetFilters
) {
201 const base::string16
kNull(L
"\0", 1);
203 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
204 std::vector
<Tuple2
<base::string16
, base::string16
> > filters
;
205 ofn
.SetFilters(filters
);
206 EXPECT_FALSE(ofn
.GetOPENFILENAME()->lpstrFilter
);
207 CheckFilters(filters
,
208 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
210 filters
.push_back(MakeTuple(base::string16(L
"a"), base::string16(L
"b")));
211 ofn
.SetFilters(filters
);
212 CheckFilterString(L
"a" + kNull
+ L
"b" + kNull
, ofn
);
213 CheckFilters(filters
,
214 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
216 filters
.push_back(MakeTuple(base::string16(L
"X"), base::string16(L
"Y")));
217 ofn
.SetFilters(filters
);
218 CheckFilterString(L
"a" + kNull
+ L
"b" + kNull
+ L
"X" + kNull
+ L
"Y" + kNull
,
220 CheckFilters(filters
,
221 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
224 TEST(OpenFileNameTest
, SetResult
) {
225 const base::string16
kNull(L
"\0", 1);
227 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
228 base::FilePath directory
;
229 std::vector
<base::FilePath
> filenames
;
231 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
232 CheckResult(L
"", ofn
);
234 directory
= base::FilePath(L
"C:\\dir");
235 filenames
.push_back(base::FilePath(L
"file"));
236 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
237 CheckResult(L
"C:\\dir\\file" + kNull
, ofn
);
239 filenames
.push_back(base::FilePath(L
"otherfile"));
240 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
241 CheckResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, ofn
);
243 base::char16 short_buffer
[10] = L
"";
245 ofn
.GetOPENFILENAME()->lpstrFile
= short_buffer
;
246 ofn
.GetOPENFILENAME()->nMaxFile
= arraysize(short_buffer
);
247 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
248 CheckResult(L
"", ofn
);