Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve and extend DateTime/DateTimeOffset generation #252

Merged
merged 9 commits into from
Jan 6, 2021
31 changes: 21 additions & 10 deletions src/Hedgehog/Gen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -515,21 +515,32 @@ module Gen =
return System.Guid bs
}

/// Generates a random instant in time expressed as a date and time of day.
/// Generates a random DateTime using the specified range.
cmeeren marked this conversation as resolved.
Show resolved Hide resolved
[<CompiledName("DateTime")>]
let dateTime : Gen<System.DateTime> =
let minTicks =
System.DateTime.MinValue.Ticks
let maxTicks =
System.DateTime.MaxValue.Ticks
let dateTime (range : Range<DateTime>) : Gen<System.DateTime> =
gen {
let! ticks =
Range.constantFrom
(System.DateTime (2000, 1, 1)).Ticks minTicks maxTicks
|> integral
let! ticks = range |> Range.map (fun dt -> dt.Ticks) |> integral
return System.DateTime ticks
}

/// Generates a random DateTimeOffset using the specified range.
[<CompiledName("DateTimeOffset")>]
let dateTimeOffset (range : Range<DateTimeOffset>) : Gen<System.DateTimeOffset> =
gen {
let! ticks = range |> Range.map (fun dt -> dt.Ticks) |> integral
// Ensure there is no overflow near the edges when adding the offset
let minOffsetMinutes =
max
(-14L * 60L)
((DateTimeOffset.MaxValue.Ticks - ticks) / TimeSpan.TicksPerMinute * -1L)
let maxOffsetMinutes =
min
(14L * 60L)
((ticks - DateTimeOffset.MinValue.Ticks) / TimeSpan.TicksPerMinute)
let! offsetMinutes = int (Range.linearFrom 0 (Operators.int minOffsetMinutes) (Operators.int maxOffsetMinutes))
return System.DateTimeOffset(ticks, TimeSpan.FromMinutes (Operators.float offsetMinutes))
}

//
// Sampling
//
Expand Down
8 changes: 5 additions & 3 deletions tests/Hedgehog.Tests/GenTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ open Xunit
[<InlineData(256)>]
[<InlineData(512)>]
let ``dateTime creates System.DateTime instances`` count =
let actual = Gen.dateTime |> Gen.sample 0 count
let actual = Gen.dateTime (Range.constant System.DateTime.MinValue System.DateTime.MaxValue) |> Gen.sample 0 count
actual
|> List.distinct
|> List.length
Expand Down Expand Up @@ -45,7 +45,7 @@ let ``dateTime randomly generates value between max and min ticks`` () =
|> Random.run seed1 0
let expected = System.DateTime ticks

let actual = Gen.dateTime
let actual = Gen.dateTime (Range.constant System.DateTime.MinValue System.DateTime.MaxValue)

let result = actual |> Gen.toRandom |> Random.run seed0 0 |> Tree.outcome
expected =! result
Expand All @@ -54,7 +54,9 @@ let ``dateTime randomly generates value between max and min ticks`` () =
let ``dateTime shrinks to correct mid-value`` () =
let result =
property {
let! actual = Gen.dateTime
let! actual =
Range.constantFrom (System.DateTime (2000, 1, 1)) System.DateTime.MinValue System.DateTime.MaxValue
|> Gen.dateTime
System.DateTime.Now =! actual
}
|> Property.report
Expand Down