Skip to content

Commit d7785a2

Browse files
committed
Add property-based test for Snapshot Display impl
Add a property-based test for the Display impl of the Snapshot type, asserting that the time stamp part uses fixed size components throughout.
1 parent ec5e6af commit d7785a2

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ btrfs-backup = { path = ".", features = ["test"] }
5858
glob = "0.3.1"
5959
goblin = "0.10.0"
6060
memmap = "0.7.0"
61+
quickcheck = "1"
6162
serial_test = "4.0.1"
6263
tempfile = "3.3.0"
6364
time-macros = "0.2.24"

src/snapshot.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,16 @@ mod tests {
381381

382382
use std::cmp::Ordering;
383383

384+
use quickcheck::Arbitrary;
385+
use quickcheck::Gen;
386+
use quickcheck::QuickCheck;
387+
use quickcheck::TestResult;
388+
389+
use time::Date;
384390
use time::Month;
391+
use time::OffsetDateTime;
392+
use time::Time;
393+
use time::UtcOffset;
385394

386395

387396
/// Check that trailing path separators are handled properly.
@@ -472,4 +481,71 @@ mod tests {
472481
test(Path::new("/snapshots/xxx/yyy"));
473482
test(Path::new("/snapshots/xxx-yyy"));
474483
}
484+
485+
486+
#[derive(Clone, Debug)]
487+
struct Timestamp {
488+
year: i32,
489+
month: Month,
490+
day: u8,
491+
hour: u8,
492+
minute: u8,
493+
second: u8,
494+
offset_hour: i8,
495+
offset_minute: i8,
496+
}
497+
498+
impl Arbitrary for Timestamp {
499+
fn arbitrary(g: &mut Gen) -> Self {
500+
let year = 1000 + u16::arbitrary(g) % 9000;
501+
let month = Month::try_from(1 + u8::arbitrary(g) % 12).unwrap();
502+
let day = 1 + u8::arbitrary(g) % month.length(year as i32);
503+
504+
Self {
505+
year: year as i32,
506+
month,
507+
day,
508+
hour: u8::arbitrary(g) % 24,
509+
minute: u8::arbitrary(g) % 60,
510+
second: u8::arbitrary(g) % 60,
511+
offset_hour: i8::arbitrary(g) % 24,
512+
offset_minute: i8::arbitrary(g) % 60,
513+
}
514+
}
515+
}
516+
517+
impl Timestamp {
518+
fn into_offset_date_time(self) -> OffsetDateTime {
519+
let date = Date::from_calendar_date(self.year, self.month, self.day).unwrap();
520+
let time = Time::from_hms(self.hour, self.minute, self.second).unwrap();
521+
let offset = UtcOffset::from_hms(self.offset_hour, self.offset_minute, 0).unwrap();
522+
523+
date.with_time(time).assume_offset(offset)
524+
}
525+
}
526+
527+
/// Check that variable [`Snapshot::timestamp`] values keep overall
528+
/// formatted [`Snapshot`] string length constant.
529+
#[test]
530+
fn snapshot_display_length() {
531+
fn property(timestamp: Timestamp) -> TestResult {
532+
let mut snapshot = Snapshot::builder()
533+
.try_build(Path::new("/tmp/foobar"))
534+
.unwrap();
535+
536+
let before = snapshot.to_string();
537+
snapshot.timestamp = timestamp.into_offset_date_time();
538+
let after = snapshot.to_string();
539+
540+
if before.len() == after.len() {
541+
TestResult::passed()
542+
} else {
543+
TestResult::error(format!("display length changed: {before} -> {after}"))
544+
}
545+
}
546+
547+
QuickCheck::new()
548+
.tests(1000)
549+
.quickcheck(property as fn(_) -> _);
550+
}
475551
}

0 commit comments

Comments
 (0)