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
, GetSingleResult
) {
125 const base::string16
kNull(L
"\0", 1);
126 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
127 base::FilePath result
;
129 SetResult(L
"C:\\dir\\file" + kNull
, &ofn
);
130 result
= ofn
.GetSingleResult();
131 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
133 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
, &ofn
);
134 result
= ofn
.GetSingleResult();
135 EXPECT_EQ(base::FilePath(L
"C:\\dir\\file"), result
);
137 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, &ofn
);
138 result
= ofn
.GetSingleResult();
139 EXPECT_EQ(base::FilePath(), result
);
141 SetResult(L
"", &ofn
);
142 result
= ofn
.GetSingleResult();
143 EXPECT_EQ(base::FilePath(), result
);
146 TEST(OpenFileNameTest
, GetResult
) {
147 const base::string16
kNull(L
"\0", 1);
149 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
150 base::FilePath directory
;
151 std::vector
<base::FilePath
> filenames
;
153 SetResult(L
"C:\\dir\\file" + kNull
, &ofn
);
154 ofn
.GetResult(&directory
, &filenames
);
155 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
156 ASSERT_EQ(1u, filenames
.size());
157 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
162 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
, &ofn
);
163 ofn
.GetResult(&directory
, &filenames
);
164 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
165 ASSERT_EQ(1u, filenames
.size());
166 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
171 SetResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, &ofn
);
172 ofn
.GetResult(&directory
, &filenames
);
173 EXPECT_EQ(base::FilePath(L
"C:\\dir"), directory
);
174 ASSERT_EQ(2u, filenames
.size());
175 EXPECT_EQ(base::FilePath(L
"file"), filenames
[0]);
176 EXPECT_EQ(base::FilePath(L
"otherfile"), filenames
[1]);
181 SetResult(L
"", &ofn
);
182 ofn
.GetResult(&directory
, &filenames
);
183 EXPECT_EQ(base::FilePath(), directory
);
184 ASSERT_EQ(0u, filenames
.size());
187 TEST(OpenFileNameTest
, SetAndGetFilters
) {
188 const base::string16
kNull(L
"\0", 1);
190 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
191 std::vector
<Tuple2
<base::string16
, base::string16
> > filters
;
192 ofn
.SetFilters(filters
);
193 EXPECT_FALSE(ofn
.GetOPENFILENAME()->lpstrFilter
);
194 CheckFilters(filters
,
195 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
197 filters
.push_back(MakeTuple(base::string16(L
"a"), base::string16(L
"b")));
198 ofn
.SetFilters(filters
);
199 CheckFilterString(L
"a" + kNull
+ L
"b" + kNull
, ofn
);
200 CheckFilters(filters
,
201 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
203 filters
.push_back(MakeTuple(base::string16(L
"X"), base::string16(L
"Y")));
204 ofn
.SetFilters(filters
);
205 CheckFilterString(L
"a" + kNull
+ L
"b" + kNull
+ L
"X" + kNull
+ L
"Y" + kNull
,
207 CheckFilters(filters
,
208 ui::win::OpenFileName::GetFilters(ofn
.GetOPENFILENAME()));
211 TEST(OpenFileNameTest
, SetResult
) {
212 const base::string16
kNull(L
"\0", 1);
214 ui::win::OpenFileName
ofn(kHwnd
, kFlags
);
215 base::FilePath directory
;
216 std::vector
<base::FilePath
> filenames
;
218 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
219 CheckResult(L
"", ofn
);
221 directory
= base::FilePath(L
"C:\\dir");
222 filenames
.push_back(base::FilePath(L
"file"));
223 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
224 CheckResult(L
"C:\\dir\\file" + kNull
, ofn
);
226 filenames
.push_back(base::FilePath(L
"otherfile"));
227 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
228 CheckResult(L
"C:\\dir" + kNull
+ L
"file" + kNull
+ L
"otherfile" + kNull
, ofn
);
230 base::char16 short_buffer
[10] = L
"";
232 ofn
.GetOPENFILENAME()->lpstrFile
= short_buffer
;
233 ofn
.GetOPENFILENAME()->nMaxFile
= arraysize(short_buffer
);
234 ui::win::OpenFileName::SetResult(directory
, filenames
, ofn
.GetOPENFILENAME());
235 CheckResult(L
"", ofn
);