Home | History | Annotate | Download | only in win
      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.
      4 
      5 #include "ui/base/win/open_file_name_win.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 namespace {
     11 const HWND kHwnd = reinterpret_cast<HWND>(0xDEADBEEF);
     12 const DWORD kFlags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING;
     13 
     14 void SetResult(const base::string16& result, ui::win::OpenFileName* ofn) {
     15   if (ofn->GetOPENFILENAME()->nMaxFile <= result.size()) {
     16     ADD_FAILURE() << "filename buffer insufficient.";
     17     return;
     18   }
     19   if (!result.size()) {
     20     ofn->GetOPENFILENAME()->lpstrFile[0] = 0;
     21   } else {
     22     // Because the result has embedded nulls, we must memcpy.
     23     memcpy(ofn->GetOPENFILENAME()->lpstrFile,
     24            result.c_str(),
     25            (result.size() + 1) * sizeof(result[0]));
     26   }
     27 }
     28 
     29 void CheckFilters(
     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() << ".";
     35     return;
     36   }
     37 
     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;
     41   }
     42 }
     43 
     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.";
     48     return;
     49   }
     50   if (expected.size() == 0) {
     51     EXPECT_EQ(0, ofn.GetOPENFILENAME()->lpstrFilter[0]);
     52   } else {
     53     EXPECT_EQ(0,
     54               memcmp(expected.c_str(),
     55                      ofn.GetOPENFILENAME()->lpstrFilter,
     56                      expected.size() + 1 * sizeof(expected[0])));
     57   }
     58 }
     59 
     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.";
     64     return;
     65   }
     66   if (expected.size() == 0) {
     67     EXPECT_EQ(0, ofn.GetOPENFILENAME()->lpstrFile[0]);
     68   } else {
     69     EXPECT_EQ(0,
     70               memcmp(expected.c_str(),
     71                      ofn.GetOPENFILENAME()->lpstrFile,
     72                      expected.size() + 1 * sizeof(expected[0])));
     73   }
     74 }
     75 
     76 }  // namespace
     77 
     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]);
     86 }
     87 
     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));
     95 
     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));
    101 
    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));
    107 
    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));
    116 
    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));
    122 }
    123 
    124 TEST(OpenFileNameTest, GetSingleResult) {
    125   const base::string16 kNull(L"\0", 1);
    126   ui::win::OpenFileName ofn(kHwnd, kFlags);
    127   base::FilePath result;
    128 
    129   SetResult(L"C:\\dir\\file" + kNull, &ofn);
    130   result = ofn.GetSingleResult();
    131   EXPECT_EQ(base::FilePath(L"C:\\dir\\file"), result);
    132 
    133   SetResult(L"C:\\dir" + kNull + L"file" + kNull, &ofn);
    134   result = ofn.GetSingleResult();
    135   EXPECT_EQ(base::FilePath(L"C:\\dir\\file"), result);
    136 
    137   SetResult(L"C:\\dir" + kNull + L"file" + kNull + L"otherfile" + kNull, &ofn);
    138   result = ofn.GetSingleResult();
    139   EXPECT_EQ(base::FilePath(), result);
    140 
    141   SetResult(L"", &ofn);
    142   result = ofn.GetSingleResult();
    143   EXPECT_EQ(base::FilePath(), result);
    144 }
    145 
    146 TEST(OpenFileNameTest, GetResult) {
    147   const base::string16 kNull(L"\0", 1);
    148 
    149   ui::win::OpenFileName ofn(kHwnd, kFlags);
    150   base::FilePath directory;
    151   std::vector<base::FilePath> filenames;
    152 
    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]);
    158 
    159   directory.clear();
    160   filenames.clear();
    161 
    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]);
    167 
    168   directory.clear();
    169   filenames.clear();
    170 
    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]);
    177 
    178   directory.clear();
    179   filenames.clear();
    180 
    181   SetResult(L"", &ofn);
    182   ofn.GetResult(&directory, &filenames);
    183   EXPECT_EQ(base::FilePath(), directory);
    184   ASSERT_EQ(0u, filenames.size());
    185 }
    186 
    187 TEST(OpenFileNameTest, SetAndGetFilters) {
    188   const base::string16 kNull(L"\0", 1);
    189 
    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()));
    196 
    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()));
    202 
    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,
    206                     ofn);
    207   CheckFilters(filters,
    208                ui::win::OpenFileName::GetFilters(ofn.GetOPENFILENAME()));
    209 }
    210 
    211 TEST(OpenFileNameTest, SetResult) {
    212   const base::string16 kNull(L"\0", 1);
    213 
    214   ui::win::OpenFileName ofn(kHwnd, kFlags);
    215   base::FilePath directory;
    216   std::vector<base::FilePath> filenames;
    217 
    218   ui::win::OpenFileName::SetResult(directory, filenames, ofn.GetOPENFILENAME());
    219   CheckResult(L"", ofn);
    220 
    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);
    225 
    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);
    229 
    230   base::char16 short_buffer[10] = L"";
    231 
    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);
    236 }
    237