Index: base/time/time_unittest.cc |
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc |
index 8a6a7f517728335660c180788cadcd158abcb78a..3bb7c509ae39322663e2c873e1ad967a236f3945 100644 |
--- a/base/time/time_unittest.cc |
+++ b/base/time/time_unittest.cc |
@@ -21,6 +21,87 @@ namespace base { |
namespace { |
+const struct DateTestData { |
+ Time::Exploded explode; |
+ bool is_valid; |
+} kDateTestData[] = { |
+ // 31st of February |
+ {{2016, 2, 0, 31, 12, 30, 0, 0}, true}, |
+ // 31st of April |
+ {{2016, 4, 0, 31, 8, 43, 0, 0}, true}, |
+ // Negative month |
+ {{2016, -5, 0, 2, 4, 10, 0, 0}, false}, |
+ // Negative date of month |
+ {{2016, 6, 0, -15, 2, 50, 0, 0}, false}, |
+ // Negative hours |
+ {{2016, 7, 0, 10, -11, 29, 0, 0}, false}, |
+ // Negative minutes |
+ {{2016, 3, 0, 14, 10, -29, 0, 0}, false}, |
+ // Negative seconds |
+ {{2016, 10, 0, 25, 7, 47, -30, 0}, false}, |
+ // Negative milliseconds |
+ {{2016, 10, 0, 25, 7, 47, 20, -500}, false}, |
+ // Hours are too large |
+ {{2016, 7, 0, 10, 26, 29, 0, 0}, false}, |
+ // Minutes are too large |
+ {{2016, 3, 0, 14, 10, 78, 0, 0}, false}, |
+ // Seconds are too large |
+ {{2016, 10, 0, 25, 7, 47, 234, 0}, false}, |
+ // Milliseconds are too large |
+ {{2016, 10, 0, 25, 6, 31, 23, 1643}, false}, |
+}; |
+ |
+void PrintTo(const DateTestData& test_data, std::ostream* os) { |
+ *os << " year: " << test_data.explode.year |
+ << "; month: " << test_data.explode.month |
+ << "; day_of_month: " << test_data.explode.day_of_month |
+ << "; hour: " << test_data.explode.hour |
+ << "; minute: " << test_data.explode.minute |
+ << "; second: " << test_data.explode.second |
+ << "; millisecond: " << test_data.explode.millisecond; |
+} |
+ |
+// Class for testing out of real bounds times. |
+// For example, setting day 31 on 30 day month. |
+class TimeTestOutOfBounds : public testing::TestWithParam<DateTestData> { |
+public: |
+ virtual ~TimeTestOutOfBounds() {} |
+ void SetUp() override { test_data_ = GetParam(); } |
+ |
+ protected: |
+ DateTestData test_data_; |
+}; |
+ |
+TEST_P(TimeTestOutOfBounds, FromExplodedOutOfBoundsTimeOld) { |
+ // FromUTCExploded must return Time(0), if the day is set to 31 on a |
+ // 28-30 day month. Test if |exploded| returns Time(0) on 31st of February and |
+ // 31st of April. Test fails because old implementation does not handle this. |
+ // The test is to be deleted after we check which environments fail. |
+ EXPECT_EQ(test_data_.explode.HasValidValues(), test_data_.is_valid); |
+ |
+ base::Time t_time = base::Time::FromUTCExploded(test_data_.explode); |
+ EXPECT_TRUE(t_time.is_null()); // must fail |
+ t_time = base::Time::FromLocalExploded(test_data_.explode); |
+ EXPECT_TRUE(t_time.is_null()); // must fail |
+} |
+ |
+TEST_P(TimeTestOutOfBounds, FromExplodedOutOfBoundsTimeNew) { |
+ // FromUTCExploded must set time to Time(0) and failure, if the day is set to |
+ // 31 on a 28-30 day month. Test |exploded| returns Time(0) on 31st of |
+ // February and 31st of April. New implementation handles this. |
+ EXPECT_EQ(test_data_.explode.HasValidValues(), test_data_.is_valid); |
+ |
+ base::Time t_time; |
+ EXPECT_FALSE(base::Time::FromUTCExploded(test_data_.explode, t_time)); |
+ EXPECT_TRUE(t_time.is_null()); |
+ EXPECT_FALSE(base::Time::FromLocalExploded(test_data_.explode, t_time)); |
+ EXPECT_TRUE(t_time.is_null()); |
+} |
+ |
+INSTANTIATE_TEST_CASE_P(, |
+ TimeTestOutOfBounds, |
+ testing::ValuesIn(kDateTestData)); |
+ |
// Specialized test fixture allowing time strings without timezones to be |
// tested by comparing them to a known time in the local zone. |
// See also pr_time_unittests.cc |