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
<base::Tuple
<base::string16
, base::string16
>>& expected
,
31 const std::vector
<base::Tuple
<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(base::get
<0>(expected
[i
]), base::get
<0>(actual
[i
]))
40 << "Mismatch at index " << i
;
41 EXPECT_EQ(base::get
<1>(expected
[i
]), base::get
<1>(actual
[i
]))
42 << "Mismatch at index " << i
;
46 void CheckFilterString(const base::string16
& expected
,
47 const ui::win::OpenFileName
& ofn
) {
48 if (!ofn
.GetOPENFILENAME()->lpstrFilter
) {
49 ADD_FAILURE() << "Filter string is NULL.";
52 if (expected
.size() == 0) {
53 EXPECT_EQ(0, ofn
.GetOPENFILENAME()->lpstrFilter
[0]);
56 memcmp(expected
.c_str(),
57 ofn
.GetOPENFILENAME()->lpstrFilter
,
58 expected
.size() + 1 * sizeof(expected
[0])));
62 void CheckResult(const base::string16
& expected
,
63 const ui::win::OpenFileName
& ofn
) {
64 if (!ofn
.GetOPENFILENAME()->lpstrFile
) {
65 ADD_FAILURE() << "File string is NULL.";
68 if (expected
.size() == 0) {
69 EXPECT_EQ(0, ofn
.GetOPENFILENAME()->lpstrFile
[0]);
72 memcmp(expected
.c_str(),
73 ofn
.GetOPENFILENAME()->lpstrFile
,
74 expected
.size() + 1 * sizeof(expected
[0])));
80 TEST(OpenFileNameTest
, Initialization
) {
81 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
82 EXPECT_EQ(kHwnd
, ofn
.GetOPENFILENAME()->hwndOwner
);
83 EXPECT_EQ(kFlags
, ofn
.GetOPENFILENAME()->Flags
);
84 EXPECT_EQ(sizeof(OPENFILENAME
), ofn
.GetOPENFILENAME()->lStructSize
);
85 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
86 ASSERT_GT(ofn
.GetOPENFILENAME()->nMaxFile
, 0u);
87 EXPECT_EQ(0, ofn
.GetOPENFILENAME()->lpstrFile
[0]);
90 TEST(OpenFileNameTest
, SetInitialSelection
) {
91 const base::FilePath
kDirectory(L
"C:\\directory\\child_directory");
92 const base::FilePath
kFile(L
"file_name.ext");
93 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
94 ofn
.SetInitialSelection(kDirectory
, kFile
);
95 EXPECT_EQ(kDirectory
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrInitialDir
));
96 EXPECT_EQ(kFile
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
98 ofn
.SetInitialSelection(kDirectory
, base::FilePath());
99 EXPECT_EQ(kDirectory
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrInitialDir
));
100 // Filename buffer will still be a valid pointer, to receive a result.
101 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
102 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
104 ofn
.SetInitialSelection(base::FilePath(), base::FilePath());
105 // No initial directory will lead to a NULL buffer.
106 ASSERT_FALSE(ofn
.GetOPENFILENAME()->lpstrInitialDir
);
107 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
108 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
110 // Make sure that both values are cleared when directory is missing.
111 ofn
.SetInitialSelection(kDirectory
, kFile
);
112 EXPECT_EQ(kDirectory
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrInitialDir
));
113 EXPECT_EQ(kFile
, base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
114 ofn
.SetInitialSelection(base::FilePath(), base::FilePath());
115 ASSERT_FALSE(ofn
.GetOPENFILENAME()->lpstrInitialDir
);
116 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
117 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
119 // File is ignored in absence of a directory.
120 ofn
.SetInitialSelection(base::FilePath(), kFile
);
121 ASSERT_FALSE(ofn
.GetOPENFILENAME()->lpstrInitialDir
);
122 ASSERT_TRUE(ofn
.GetOPENFILENAME()->lpstrFile
);
123 EXPECT_EQ(base::FilePath(), base::FilePath(ofn
.GetOPENFILENAME()->lpstrFile
));
126 TEST(OpenFileNameTest
, GetSingleResultFromSingleSelect
) {
127 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
128 base::FilePath result
;
130 SetResult(L
"C:\\dir\\file", &ofn
);
131 result
= ofn
.GetSingleResult();
132 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
134 SetResult(L
"", &ofn
);
135 result
= ofn
.GetSingleResult();
136 EXPECT_EQ(base::FilePath(), result
);
139 TEST(OpenFileNameTest
, GetSingleResultFromMultiSelect
) {
140 const base::string16
kNull(L
"\0", 1);
141 ui::win::OpenFileName
ofn(kHwnd
, kFlags
| OFN_ALLOWMULTISELECT
);
142 base::FilePath result
;
144 SetResult(L
"C:\\dir\\file" + kNull
, &ofn
);
145 result
= ofn
.GetSingleResult();
146 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
148 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
, &ofn
);
149 result
= ofn
.GetSingleResult();
150 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
152 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, &ofn
);
153 result
= ofn
.GetSingleResult();
154 EXPECT_EQ(base::FilePath(), result
);
156 SetResult(L
"", &ofn
);
157 result
= ofn
.GetSingleResult();
158 EXPECT_EQ(base::FilePath(), result
);
161 TEST(OpenFileNameTest
, GetResult
) {
162 const base::string16
kNull(L
"\0", 1);
164 ui::win::OpenFileName
ofn(kHwnd
, kFlags
| OFN_ALLOWMULTISELECT
);
165 base::FilePath directory
;
166 std::vector
<base::FilePath
> filenames
;
168 SetResult(L
"C:\\dir\\file" + kNull
, &ofn
);
169 ofn
.GetResult(&directory
, &filenames
);
170 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
171 ASSERT_EQ(1u, filenames
.size());
172 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
177 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
, &ofn
);
178 ofn
.GetResult(&directory
, &filenames
);
179 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
180 ASSERT_EQ(1u, filenames
.size());
181 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
186 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, &ofn
);
187 ofn
.GetResult(&directory
, &filenames
);
188 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
189 ASSERT_EQ(2u, filenames
.size());
190 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
191 EXPECT_EQ(base::FilePath(L
"otherfile"), filenames
[1]);
196 SetResult(L
"", &ofn
);
197 ofn
.GetResult(&directory
, &filenames
);
198 EXPECT_EQ(base::FilePath(), directory
);
199 ASSERT_EQ(0u, filenames
.size());
202 TEST(OpenFileNameTest
, SetAndGetFilters
) {
203 const base::string16
kNull(L
"\0", 1);
205 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
206 std::vector
<base::Tuple
<base::string16
, base::string16
>> filters
;
207 ofn
.SetFilters(filters
);
208 EXPECT_FALSE(ofn
.GetOPENFILENAME()->lpstrFilter
);
209 CheckFilters(filters
,
210 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
212 filters
.push_back(base::MakeTuple(base::string16(L
"a"), base::string16(L
"b")));
213 ofn
.SetFilters(filters
);
214 CheckFilterString(L
"a" + kNull
+ L
"b" + kNull
, ofn
);
215 CheckFilters(filters
,
216 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
218 filters
.push_back(base::MakeTuple(base::string16(L
"X"), base::string16(L
"Y")));
219 ofn
.SetFilters(filters
);
220 CheckFilterString(L
"a" + kNull
+ L
"b" + kNull
+ L
"X" + kNull
+ L
"Y" + kNull
,
222 CheckFilters(filters
,
223 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
226 TEST(OpenFileNameTest
, SetResult
) {
227 const base::string16
kNull(L
"\0", 1);
229 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
230 base::FilePath directory
;
231 std::vector
<base::FilePath
> filenames
;
233 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
234 CheckResult(L
"", ofn
);
236 directory
= base::FilePath(L
"C:\\dir");
237 filenames
.push_back(base::FilePath(L
"file"));
238 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
239 CheckResult(L
"C:\\dir\\file" + kNull
, ofn
);
241 filenames
.push_back(base::FilePath(L
"otherfile"));
242 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
243 CheckResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, ofn
);
245 base::char16 short_buffer
[10] = L
"";
247 ofn
.GetOPENFILENAME()->lpstrFile
= short_buffer
;
248 ofn
.GetOPENFILENAME()->nMaxFile
= arraysize(short_buffer
);
249 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
250 CheckResult(L
"", ofn
);