1 // Copyright (c) 2011 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 "net/ftp/ftp_util.h" 6 7 #include "base/basictypes.h" 8 #include "base/format_macros.h" 9 #include "base/strings/string_util.h" 10 #include "base/strings/stringprintf.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/time/time.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace { 16 17 TEST(FtpUtilTest, UnixFilePathToVMS) { 18 const struct { 19 const char* input; 20 const char* expected_output; 21 } kTestCases[] = { 22 { "", "" }, 23 { "/", "[]" }, 24 { "/a", "a" }, 25 { "/a/b", "a:[000000]b" }, 26 { "/a/b/c", "a:[b]c" }, 27 { "/a/b/c/d", "a:[b.c]d" }, 28 { "/a/b/c/d/e", "a:[b.c.d]e" }, 29 { "a", "a" }, 30 { "a/b", "[.a]b" }, 31 { "a/b/c", "[.a.b]c" }, 32 { "a/b/c/d", "[.a.b.c]d" }, 33 }; 34 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) { 35 EXPECT_EQ(kTestCases[i].expected_output, 36 net::FtpUtil::UnixFilePathToVMS(kTestCases[i].input)) 37 << kTestCases[i].input; 38 } 39 } 40 41 TEST(FtpUtilTest, UnixDirectoryPathToVMS) { 42 const struct { 43 const char* input; 44 const char* expected_output; 45 } kTestCases[] = { 46 { "", "" }, 47 { "/", "" }, 48 { "/a", "a:[000000]" }, 49 { "/a/", "a:[000000]" }, 50 { "/a/b", "a:[b]" }, 51 { "/a/b/", "a:[b]" }, 52 { "/a/b/c", "a:[b.c]" }, 53 { "/a/b/c/", "a:[b.c]" }, 54 { "/a/b/c/d", "a:[b.c.d]" }, 55 { "/a/b/c/d/", "a:[b.c.d]" }, 56 { "/a/b/c/d/e", "a:[b.c.d.e]" }, 57 { "/a/b/c/d/e/", "a:[b.c.d.e]" }, 58 { "a", "[.a]" }, 59 { "a/", "[.a]" }, 60 { "a/b", "[.a.b]" }, 61 { "a/b/", "[.a.b]" }, 62 { "a/b/c", "[.a.b.c]" }, 63 { "a/b/c/", "[.a.b.c]" }, 64 { "a/b/c/d", "[.a.b.c.d]" }, 65 { "a/b/c/d/", "[.a.b.c.d]" }, 66 }; 67 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) { 68 EXPECT_EQ(kTestCases[i].expected_output, 69 net::FtpUtil::UnixDirectoryPathToVMS(kTestCases[i].input)) 70 << kTestCases[i].input; 71 } 72 } 73 74 TEST(FtpUtilTest, VMSPathToUnix) { 75 const struct { 76 const char* input; 77 const char* expected_output; 78 } kTestCases[] = { 79 { "", "." }, 80 { "[]", "/" }, 81 { "a", "/a" }, 82 { "a:[000000]", "/a" }, 83 { "a:[000000]b", "/a/b" }, 84 { "a:[b]", "/a/b" }, 85 { "a:[b]c", "/a/b/c" }, 86 { "a:[b.c]", "/a/b/c" }, 87 { "a:[b.c]d", "/a/b/c/d" }, 88 { "a:[b.c.d]", "/a/b/c/d" }, 89 { "a:[b.c.d]e", "/a/b/c/d/e" }, 90 { "a:[b.c.d.e]", "/a/b/c/d/e" }, 91 { "[.a]", "a" }, 92 { "[.a]b", "a/b" }, 93 { "[.a.b]", "a/b" }, 94 { "[.a.b]c", "a/b/c" }, 95 { "[.a.b.c]", "a/b/c" }, 96 { "[.a.b.c]d", "a/b/c/d" }, 97 { "[.a.b.c.d]", "a/b/c/d" }, 98 { "[.", "" }, 99 100 // UNIX emulation: 101 { "/", "/" }, 102 { "/a", "/a" }, 103 { "/a/b", "/a/b" }, 104 { "/a/b/c", "/a/b/c" }, 105 { "/a/b/c/d", "/a/b/c/d" }, 106 }; 107 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) { 108 EXPECT_EQ(kTestCases[i].expected_output, 109 net::FtpUtil::VMSPathToUnix(kTestCases[i].input)) 110 << kTestCases[i].input; 111 } 112 } 113 114 TEST(FtpUtilTest, LsDateListingToTime) { 115 base::Time mock_current_time; 116 ASSERT_TRUE(base::Time::FromString("Tue, 15 Nov 1994 12:45:26 GMT", 117 &mock_current_time)); 118 119 const struct { 120 // Input. 121 const char* month; 122 const char* day; 123 const char* rest; 124 125 // Expected output. 126 int expected_year; 127 int expected_month; 128 int expected_day_of_month; 129 int expected_hour; 130 int expected_minute; 131 } kTestCases[] = { 132 { "Nov", "01", "2007", 2007, 11, 1, 0, 0 }, 133 { "Jul", "25", "13:37", 1994, 7, 25, 13, 37 }, 134 135 // Test date listings in German. 136 { "M\xc3\xa4r", "13", "2009", 2009, 3, 13, 0, 0 }, 137 { "Mai", "1", "10:10", 1994, 5, 1, 10, 10 }, 138 { "Okt", "14", "21:18", 1994, 10, 14, 21, 18 }, 139 { "Dez", "25", "2008", 2008, 12, 25, 0, 0 }, 140 141 // Test date listings in Russian. 142 { "\xd1\x8f\xd0\xbd\xd0\xb2", "1", "2011", 2011, 1, 1, 0, 0 }, 143 { "\xd1\x84\xd0\xb5\xd0\xb2", "1", "2011", 2011, 2, 1, 0, 0 }, 144 { "\xd0\xbc\xd0\xb0\xd1\x80", "1", "2011", 2011, 3, 1, 0, 0 }, 145 { "\xd0\xb0\xd0\xbf\xd1\x80", "1", "2011", 2011, 4, 1, 0, 0 }, 146 { "\xd0\xbc\xd0\xb0\xd0\xb9", "1", "2011", 2011, 5, 1, 0, 0 }, 147 { "\xd0\xb8\xd1\x8e\xd0\xbd", "1", "2011", 2011, 6, 1, 0, 0 }, 148 { "\xd0\xb8\xd1\x8e\xd0\xbb", "1", "2011", 2011, 7, 1, 0, 0 }, 149 { "\xd0\xb0\xd0\xb2\xd0\xb3", "1", "2011", 2011, 8, 1, 0, 0 }, 150 { "\xd1\x81\xd0\xb5\xd0\xbd", "1", "2011", 2011, 9, 1, 0, 0 }, 151 { "\xd0\xbe\xd0\xba\xd1\x82", "1", "2011", 2011, 10, 1, 0, 0 }, 152 { "\xd0\xbd\xd0\xbe\xd1\x8f", "1", "2011", 2011, 11, 1, 0, 0 }, 153 { "\xd0\xb4\xd0\xb5\xd0\xba", "1", "2011", 2011, 12, 1, 0, 0 }, 154 155 // Test current year detection. 156 { "Nov", "01", "12:00", 1994, 11, 1, 12, 0 }, 157 { "Nov", "15", "12:00", 1994, 11, 15, 12, 0 }, 158 { "Nov", "16", "12:00", 1993, 11, 16, 12, 0 }, 159 { "Jan", "01", "08:30", 1994, 1, 1, 8, 30 }, 160 { "Sep", "02", "09:00", 1994, 9, 2, 9, 0 }, 161 { "Dec", "06", "21:00", 1993, 12, 6, 21, 0 }, 162 }; 163 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) { 164 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s %s %s", i, 165 kTestCases[i].month, kTestCases[i].day, 166 kTestCases[i].rest)); 167 168 base::Time time; 169 ASSERT_TRUE(net::FtpUtil::LsDateListingToTime( 170 UTF8ToUTF16(kTestCases[i].month), UTF8ToUTF16(kTestCases[i].day), 171 UTF8ToUTF16(kTestCases[i].rest), mock_current_time, &time)); 172 173 base::Time::Exploded time_exploded; 174 time.LocalExplode(&time_exploded); 175 EXPECT_EQ(kTestCases[i].expected_year, time_exploded.year); 176 EXPECT_EQ(kTestCases[i].expected_month, time_exploded.month); 177 EXPECT_EQ(kTestCases[i].expected_day_of_month, time_exploded.day_of_month); 178 EXPECT_EQ(kTestCases[i].expected_hour, time_exploded.hour); 179 EXPECT_EQ(kTestCases[i].expected_minute, time_exploded.minute); 180 EXPECT_EQ(0, time_exploded.second); 181 EXPECT_EQ(0, time_exploded.millisecond); 182 } 183 } 184 185 TEST(FtpUtilTest, WindowsDateListingToTime) { 186 const struct { 187 // Input. 188 const char* date; 189 const char* time; 190 191 // Expected output. 192 int expected_year; 193 int expected_month; 194 int expected_day_of_month; 195 int expected_hour; 196 int expected_minute; 197 } kTestCases[] = { 198 { "11-01-07", "12:42", 2007, 11, 1, 12, 42 }, 199 { "11-01-07", "12:42AM", 2007, 11, 1, 0, 42 }, 200 { "11-01-07", "12:42PM", 2007, 11, 1, 12, 42 }, 201 202 { "11-01-2007", "12:42", 2007, 11, 1, 12, 42 }, 203 }; 204 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) { 205 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s %s", i, 206 kTestCases[i].date, kTestCases[i].time)); 207 208 base::Time time; 209 ASSERT_TRUE(net::FtpUtil::WindowsDateListingToTime( 210 UTF8ToUTF16(kTestCases[i].date), 211 UTF8ToUTF16(kTestCases[i].time), 212 &time)); 213 214 base::Time::Exploded time_exploded; 215 time.LocalExplode(&time_exploded); 216 EXPECT_EQ(kTestCases[i].expected_year, time_exploded.year); 217 EXPECT_EQ(kTestCases[i].expected_month, time_exploded.month); 218 EXPECT_EQ(kTestCases[i].expected_day_of_month, time_exploded.day_of_month); 219 EXPECT_EQ(kTestCases[i].expected_hour, time_exploded.hour); 220 EXPECT_EQ(kTestCases[i].expected_minute, time_exploded.minute); 221 EXPECT_EQ(0, time_exploded.second); 222 EXPECT_EQ(0, time_exploded.millisecond); 223 } 224 } 225 226 TEST(FtpUtilTest, GetStringPartAfterColumns) { 227 const struct { 228 const char* text; 229 int column; 230 const char* expected_result; 231 } kTestCases[] = { 232 { "", 0, "" }, 233 { "", 1, "" }, 234 { "foo abc", 0, "foo abc" }, 235 { "foo abc", 1, "abc" }, 236 { " foo abc", 0, "foo abc" }, 237 { " foo abc", 1, "abc" }, 238 { " foo abc", 2, "" }, 239 { " foo abc ", 0, "foo abc" }, 240 { " foo abc ", 1, "abc" }, 241 { " foo abc ", 2, "" }, 242 }; 243 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); i++) { 244 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s %d", i, 245 kTestCases[i].text, kTestCases[i].column)); 246 247 EXPECT_EQ(ASCIIToUTF16(kTestCases[i].expected_result), 248 net::FtpUtil::GetStringPartAfterColumns( 249 ASCIIToUTF16(kTestCases[i].text), kTestCases[i].column)); 250 } 251 } 252 253 } // namespace 254