#![cfg(kani)]
#![cfg(feature = "time")]
use elicitation::{Generator, InstantGenerationMode, InstantGenerator};
use elicitation::{OffsetDateTimeGenerationMode, OffsetDateTimeGenerator};
use std::time::{Duration, Instant};
use time::OffsetDateTime;
#[kani::proof]
fn verify_instant_generator_mode_preserved() {
let mode = InstantGenerationMode::Offset {
seconds: 42,
nanos: 1000,
};
match mode {
InstantGenerationMode::Now => {
assert!(matches!(mode, InstantGenerationMode::Now));
}
InstantGenerationMode::Offset { seconds, nanos } => {
assert_eq!(seconds, 42);
assert_eq!(nanos, 1000);
}
}
}
#[kani::proof]
fn verify_instant_generator_now_mode_logic() {
let mode = InstantGenerationMode::Now;
match mode {
InstantGenerationMode::Now => {
assert!(true, "Now mode branch taken");
}
InstantGenerationMode::Offset { .. } => {
assert!(false, "Wrong branch");
}
}
}
#[kani::proof]
fn verify_instant_generator_offset_positive_logic() {
let seconds: i64 = kani::any();
let nanos: u32 = kani::any();
kani::assume(seconds > 0);
kani::assume(nanos < 1_000_000_000);
let mode = InstantGenerationMode::Offset { seconds, nanos };
match mode {
InstantGenerationMode::Now => {
assert!(false, "Wrong branch");
}
InstantGenerationMode::Offset {
seconds: s,
nanos: n,
} => {
assert!(s > 0, "Positive seconds");
assert_eq!(s, seconds);
assert_eq!(n, nanos);
}
}
}
#[kani::proof]
fn verify_instant_generator_offset_negative_logic() {
let seconds: i64 = kani::any();
let nanos: u32 = kani::any();
kani::assume(seconds < 0);
kani::assume(nanos < 1_000_000_000);
let mode = InstantGenerationMode::Offset { seconds, nanos };
match mode {
InstantGenerationMode::Now => {
assert!(false, "Wrong branch");
}
InstantGenerationMode::Offset {
seconds: s,
nanos: n,
} => {
assert!(s < 0, "Negative seconds");
assert_eq!(s, seconds);
assert_eq!(n, nanos);
}
}
}
#[kani::proof]
fn verify_instant_generator_offset_zero_logic() {
let mode = InstantGenerationMode::Offset {
seconds: 0,
nanos: 0,
};
match mode {
InstantGenerationMode::Offset { seconds, nanos } => {
assert_eq!(seconds, 0);
assert_eq!(nanos, 0);
}
_ => assert!(false, "Wrong branch"),
}
}
#[kani::proof]
fn verify_offsetdatetime_generator_unix_epoch() {
let mode = OffsetDateTimeGenerationMode::UnixEpoch;
let reference = OffsetDateTime::UNIX_EPOCH;
let generator = OffsetDateTimeGenerator::with_reference(mode, reference);
let dt = generator.generate();
assert_eq!(
dt,
OffsetDateTime::UNIX_EPOCH,
"UnixEpoch mode produces UNIX_EPOCH"
);
}
#[kani::proof]
fn verify_offsetdatetime_generator_offset_positive() {
let seconds: i64 = kani::any();
let nanos: i32 = kani::any();
kani::assume(seconds > 0);
kani::assume(seconds < 100_000);
kani::assume(nanos >= 0);
kani::assume(nanos < 1_000_000_000);
let mode = OffsetDateTimeGenerationMode::Offset { seconds, nanos };
let reference = OffsetDateTime::UNIX_EPOCH;
let generator = OffsetDateTimeGenerator::with_reference(mode, reference);
let dt = generator.generate();
assert!(dt > reference, "Positive offset produces future time");
}
#[kani::proof]
fn verify_offsetdatetime_generator_offset_negative() {
let seconds: i64 = kani::any();
let nanos: i32 = kani::any();
kani::assume(seconds < 0);
kani::assume(seconds > -100_000);
kani::assume(nanos >= 0);
kani::assume(nanos < 1_000_000_000);
let mode = OffsetDateTimeGenerationMode::Offset { seconds, nanos };
let reference = OffsetDateTime::UNIX_EPOCH + Duration::from_secs(200_000);
let generator = OffsetDateTimeGenerator::with_reference(mode, reference);
let dt = generator.generate();
assert!(dt < reference, "Negative offset produces past time");
}
#[kani::proof]
fn verify_offsetdatetime_generator_offset_zero() {
let mode = OffsetDateTimeGenerationMode::Offset {
seconds: 0,
nanos: 0,
};
let reference = OffsetDateTime::UNIX_EPOCH;
let generator = OffsetDateTimeGenerator::with_reference(mode, reference);
let dt = generator.generate();
assert_eq!(dt, reference, "Zero offset returns reference unchanged");
}
#[kani::proof]
fn verify_offsetdatetime_generator_mode_preserved() {
let mode = OffsetDateTimeGenerationMode::UnixEpoch;
let reference = OffsetDateTime::UNIX_EPOCH;
let generator = OffsetDateTimeGenerator::with_reference(mode, reference);
assert_eq!(generator.mode(), mode, "Generator preserves mode");
}
#[kani::proof]
fn verify_offsetdatetime_generator_reference_preserved() {
let mode = OffsetDateTimeGenerationMode::UnixEpoch;
let reference = OffsetDateTime::UNIX_EPOCH;
let generator = OffsetDateTimeGenerator::with_reference(mode, reference);
assert_eq!(
generator.reference(),
reference,
"Generator preserves reference"
);
}