Skip to content

Commit

Permalink
add DateOnly and TimeOnly
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyLloyd committed Nov 12, 2023
1 parent b7e21a2 commit fc724d2
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 2 deletions.
58 changes: 56 additions & 2 deletions CsCheck/Gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1544,10 +1544,14 @@ public static GenOperation<Actual, Model> Operation<Actual, Model>(Action<Actual
public static readonly GenDouble Double = new();
/// <summary>Generator for decimal.</summary>
public static readonly GenDecimal Decimal = new();
/// <summary>Generator for date.</summary>
/// <summary>Generator for Date.</summary>
public static readonly GenDate Date = new();
/// <summary>Generator for DateOnly.</summary>
public static readonly GenDateOnly DateOnly = new();
/// <summary>Generator for DateTime.</summary>
public static readonly GenDateTime DateTime = new();
/// <summary>Generator for TimeOnly.</summary>
public static readonly GenTimeOnly TimeOnly = new();
/// <summary>Generator for TimeSpan.</summary>
public static readonly GenTimeSpan TimeSpan = new();
/// <summary>Generator for DateTimeOffset.</summary>
Expand Down Expand Up @@ -2324,7 +2328,7 @@ public override DateTime Generate(PCG pcg, Size? min, out Size size)

public sealed class GenDate : Gen<DateTime>
{
const uint max = 3652058U; //(uint)(DateTime.MaxValue.Ticks / TimeSpan.TicksPerDay);
const uint max = 3652059U; //(uint)(DateTime.MaxValue.Ticks / TimeSpan.TicksPerDay);
public override DateTime Generate(PCG pcg, Size? min, out Size size)
{
uint i = pcg.Next(max);
Expand All @@ -2347,6 +2351,56 @@ public override DateTime Generate(PCG pcg, Size? min, out Size size)
: new Range((uint)(start.Ticks / TimeSpan.TicksPerDay), (uint)((finish.Ticks - start.Ticks) / TimeSpan.TicksPerDay) + 1U);
}

public sealed class GenDateOnly : Gen<DateOnly>
{
const uint max = 3652059U;
public override DateOnly Generate(PCG pcg, Size? min, out Size size)
{
uint i = pcg.Next(max);
size = new Size(i);
return DateOnly.FromDayNumber((int)i);
}
sealed class Range(uint s, uint l) : Gen<DateOnly>
{
public override DateOnly Generate(PCG pcg, Size? min, out Size size)
{
var i = s + pcg.Next(l);
size = new Size(i);
return DateOnly.FromDayNumber((int)i);
}
}

/// <summary>Generate DateOnly uniformly distributed in the range <paramref name="start"/> to <paramref name="finish"/> both inclusive.</summary>
public Gen<DateOnly> this[DateOnly start, DateOnly finish]
=> finish < start ? throw new CsCheckException($"GenDateOnly finish {finish} < start {start}")
: new Range((uint)start.GetHashCode(), (uint)(finish.GetHashCode() - start.GetHashCode() + 1));
}

public sealed class GenTimeOnly : Gen<TimeOnly>
{
const ulong max = 864_000_000_000;
public override TimeOnly Generate(PCG pcg, Size? min, out Size size)
{
var i = pcg.Next64(max);
size = new Size(i);
return new TimeOnly((long)i);
}
sealed class Range(ulong s, ulong l) : Gen<TimeOnly>
{
public override TimeOnly Generate(PCG pcg, Size? min, out Size size)
{
var i = s + pcg.Next64(l);
size = new Size(i);
return new TimeOnly((long)i);
}
}

/// <summary>Generate TimeOnly uniformly distributed in the range <paramref name="start"/> to <paramref name="finish"/> both inclusive.</summary>
public Gen<TimeOnly> this[TimeOnly start, TimeOnly finish]
=> finish < start ? throw new CsCheckException($"GenTimeOnly finish {finish} < start {start}")
: new Range((ulong)start.Ticks, (ulong)(finish.Ticks - start.Ticks + 1));
}

public sealed class GenTimeSpan : Gen<TimeSpan>
{
public override TimeSpan Generate(PCG pcg, Size? min, out Size size)
Expand Down
22 changes: 22 additions & 0 deletions Tests/GenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,17 @@ public void Date_Range()
.Sample(i => i.value >= i.start && i.value <= i.finish);
}

[Fact]
public void DateOnly_Range()
{
(from t in Gen.DateOnly.Select(Gen.DateOnly)
let start = t.Item1 < t.Item2 ? t.Item1 : t.Item2
let finish = t.Item1 < t.Item2 ? t.Item2 : t.Item1
from value in Gen.DateOnly[start, finish]
select (value, start, finish))
.Sample(i => i.value >= i.start && i.value <= i.finish);
}

[Fact]
public void DateTime_Range()
{
Expand All @@ -447,6 +458,17 @@ public void DateTime_Range()
.Sample(i => i.value >= i.start && i.value <= i.finish);
}

[Fact]
public void TimeOnly_Range()
{
(from t in Gen.TimeOnly.Select(Gen.TimeOnly)
let start = t.Item1 < t.Item2 ? t.Item1 : t.Item2
let finish = t.Item1 < t.Item2 ? t.Item2 : t.Item1
from value in Gen.TimeOnly[start, finish]
select (value, start, finish))
.Sample(i => i.value >= i.start && i.value <= i.finish);
}

[Fact]
public void TimeSpan_Range()
{
Expand Down

0 comments on commit fc724d2

Please sign in to comment.