History

add test to check times before unix epoch

Sebastian Thiel committed 4 years ago

Commit eb304ea1 parent e1a14062 files · +20 −2Browse files

Unified · Split

2 files
  1. git-date/src/parse.rs +12 −1
  2. git-date/tests/time/parse.rs +8 −1
git-date/src/parse.rs+12−1
@@ -1,6 +1,8 @@
1#[derive(thiserror::Error, Debug)]1#[derive(thiserror::Error, Debug)]
2#[allow(missing_docs)]2#[allow(missing_docs)]
3pub enum Error {3pub enum Error {
4 #[error("Cannot represent times before UNIX epoch at timestamp {timestamp}")]
5 TooEarly { timestamp: i64 },
4 #[error("Date string can not be parsed")]6 #[error("Date string can not be parsed")]
5 InvalidDateString,7 InvalidDateString,
6 #[error("Dates past 2038 can not be represented.")]8 #[error("Dates past 2038 can not be represented.")]
@@ -44,12 +46,21 @@ pub(crate) mod function { · 37 unmodified lines
44 // Format::Raw46 // Format::Raw
45 val47 val
46 } else if let Some(time) = relative::parse(input, now).transpose()? {48 } else if let Some(time) = relative::parse(input, now).transpose()? {
47 Time::new(time.unix_timestamp().try_into()?, time.offset().whole_seconds())49 Time::new(timestamp(time)?, time.offset().whole_seconds())
48 } else {50 } else {
49 return Err(Error::InvalidDateString);51 return Err(Error::InvalidDateString);
50 })52 })
51 }53 }
52 54
55 fn timestamp(date: OffsetDateTime) -> Result<u32, Error> {
56 let timestamp = date.unix_timestamp();
57 if timestamp < 0 {
58 Err(Error::TooEarly { timestamp })
59 } else {
60 Ok(timestamp.try_into()?)
61 }
62 }
63
53 fn parse_raw(input: &str) -> Option<Time> {64 fn parse_raw(input: &str) -> Option<Time> {
54 let mut split = input.split_whitespace();65 let mut split = input.split_whitespace();
55 let seconds_since_unix_epoch: u32 = split.next()?.parse().ok()?;66 let seconds_since_unix_epoch: u32 = split.next()?.parse().ok()?;
git-date/tests/time/parse.rs+8−1
@@ -89,6 +89,7 @@ fn invalid_dates_can_be_produced_without_current_time() { · 88 unmodified lines
89}89}
90 90
91mod relative {91mod relative {
92 use git_date::parse::Error;
92 use git_date::time::Sign;93 use git_date::time::Sign;
93 use std::time::SystemTime;94 use std::time::SystemTime;
94 use time::{Duration, OffsetDateTime};95 use time::{Duration, OffsetDateTime};
@@ -101,10 +102,16 @@ mod relative { · 6 unmodified lines
101 102
102 #[test]103 #[test]
103 #[should_panic] // TODO: fix104 #[should_panic] // TODO: fix
104 fn large_ffsets_can_panic_elsewhere() {105 fn large_offsets_can_panic_elsewhere() {
105 git_date::parse("9999999999 weeks ago", Some(std::time::UNIX_EPOCH)).ok();106 git_date::parse("9999999999 weeks ago", Some(std::time::UNIX_EPOCH)).ok();
106 }107 }
107 108
109 #[test]
110 fn offset_leading_to_before_unix_epoch_cannot_be_represented() {
111 let err = git_date::parse("1 second ago", Some(std::time::UNIX_EPOCH)).unwrap_err();
112 assert!(matches!(err, Error::TooEarly{timestamp} if timestamp == -1));
113 }
114
108 #[test]115 #[test]
109 fn various() {116 fn various() {
110 let now = Some(SystemTime::now());117 let now = Some(SystemTime::now());