Compare commits

...

5 commits

Author SHA1 Message Date
D. Moonfire 5a993e85cb fix(html): added validatiors to Autofac module
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2023-01-21 21:49:41 -06:00
D. Moonfire aac4b4373d feat(html): added identify operations
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2023-01-21 21:14:36 -06:00
D. Moonfire 22ddae11f8 fix(temporal): added CurrentInstant and CurrentDateTime to TimeService
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2023-01-21 17:48:39 -06:00
D. Moonfire b32ca7582c fix(schedules): protect against null schedules 2023-01-21 12:13:09 -06:00
D. Moonfire 07eb12414a refactor(temporal)!: renamed Timekeeper to TimeService
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2023-01-21 01:52:52 -06:00
37 changed files with 263 additions and 137 deletions

View file

@ -28,13 +28,13 @@ namespace MfGames.Nitride.Calendar;
[WithProperties]
public partial class CreateCalender : OperationBase
{
private readonly Timekeeper clock;
private readonly TimeService clock;
private readonly IValidator<CreateCalender> validator;
public CreateCalender(
IValidator<CreateCalender> validator,
Timekeeper clock)
TimeService clock)
{
this.validator = validator;
this.clock = clock;

View file

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Threading;
using FluentValidation;
using MfGames.Gallium;
using MfGames.Nitride.Contents;
using MfGames.Nitride.Generators;
using Zio;
namespace MfGames.Nitride.Html;
/// <summary>
/// An operation that identifies Markdown files by their common extensions
/// and converts them to text input while also adding the IsMarkdown
/// component to identify them.
/// </summary>
[WithProperties]
public partial class IdentifyHtml : IOperation
{
private readonly IValidator<IdentifyHtml> validator;
public IdentifyHtml(IValidator<IdentifyHtml> validator)
{
this.validator = validator;
}
public Func<Entity, UPath, bool> IsHtmlTest { get; set; } = null!;
/// <inheritdoc />
public IEnumerable<Entity> Run(
IEnumerable<Entity> input,
CancellationToken cancellationToken = default)
{
this.validator.ValidateAndThrow(this);
return input.SelectEntity<UPath, ITextContent>(this.MarkTextEntities)
.SelectEntity<UPath, IBinaryContent>(this.MarkBinaryEntities);
}
private Entity MarkBinaryEntities(
Entity entity,
UPath path,
IBinaryContent binary)
{
// If we aren't a Markdown file, then there is nothing we can do about that.
if (!this.IsHtmlTest(entity, path))
{
return entity;
}
// Convert the file as a binary.
if (binary is ITextContentConvertable textConvertable)
{
entity = entity.SetTextContent(textConvertable.ToTextContent())
.SetIsHtml();
}
else
{
throw new InvalidOperationException(
"Cannot convert a binary content to a text without ITextContentConvertable.");
}
return entity;
}
private Entity MarkTextEntities(
Entity entity,
UPath path,
ITextContent _)
{
return this.IsHtmlTest(entity, path)
? entity.SetIsHtml()
: entity;
}
}

View file

@ -0,0 +1,29 @@
using FluentValidation;
using MfGames.Gallium;
using Zio;
namespace MfGames.Nitride.Html;
public class IdentifyHtmlFromPath : IdentifyHtml
{
public IdentifyHtmlFromPath(IValidator<IdentifyHtml> validator)
: base(validator)
{
this.IsHtmlTest = DefaultIsHtml;
}
private static bool DefaultIsHtml(
Entity entity,
UPath path)
{
return (path.GetExtensionWithDot() ?? string.Empty).ToLowerInvariant()
switch
{
".htm" => true,
".html" => true,
_ => false,
};
}
}

View file

@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj"/>
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj" />
</ItemGroup>
<!-- Include the source generator -->
@ -25,7 +25,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="MfGames.Gallium" Version="0.4.0"/>
<PackageReference Include="MfGames.Gallium" Version="0.4.0" />
</ItemGroup>
</Project>

View file

@ -8,5 +8,6 @@ public class NitrideHtmlModule : Module
protected override void Load(ContainerBuilder builder)
{
builder.RegisterOperators(this);
builder.RegisterValidators(this);
}
}

View file

@ -0,0 +1,12 @@
using FluentValidation;
namespace MfGames.Nitride.Html.Validators;
public class IdentifyHtmlValidator : AbstractValidator<IdentifyHtml>
{
public IdentifyHtmlValidator()
{
this.RuleFor(x => x.IsHtmlTest)
.NotNull();
}
}

View file

@ -71,16 +71,8 @@ public partial class IdentifyMarkdown : IOperation
UPath path,
ITextContent _)
{
// If we aren't a Markdown file, then there is nothing
// we can do about that.
if (!this.IsMarkdownTest(entity, path))
{
return entity;
}
// We are already text, so just mark it as Markdown.
entity = entity.Set(IsMarkdown.Instance);
return entity;
return this.IsMarkdownTest(entity, path)
? entity.SetIsMarkdown()
: entity;
}
}

View file

@ -10,17 +10,17 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MfGames.Nitride.Gemtext\MfGames.Nitride.Gemtext.csproj"/>
<ProjectReference Include="..\MfGames.Nitride.Html\MfGames.Nitride.Html.csproj"/>
<ProjectReference Include="..\MfGames.Nitride.Slugs\MfGames.Nitride.Slugs.csproj"/>
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj"/>
<ProjectReference Include="..\MfGames.Nitride.Gemtext\MfGames.Nitride.Gemtext.csproj" />
<ProjectReference Include="..\MfGames.Nitride.Html\MfGames.Nitride.Html.csproj" />
<ProjectReference Include="..\MfGames.Nitride.Slugs\MfGames.Nitride.Slugs.csproj" />
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MfGames.Gallium" Version="0.4.0"/>
<PackageReference Include="Markdig" Version="0.30.3"/>
<PackageReference Include="MfGames.Markdown.Gemtext" Version="1.2.2"/>
<PackageReference Include="Zio" Version="0.15.0"/>
<PackageReference Include="MfGames.Gallium" Version="0.4.0" />
<PackageReference Include="Markdig" Version="0.30.3" />
<PackageReference Include="MfGames.Markdown.Gemtext" Version="1.2.2" />
<PackageReference Include="Zio" Version="0.15.0" />
</ItemGroup>
<!-- Include the source generator -->

View file

@ -1,6 +1,6 @@
using FluentValidation;
namespace MfGames.Nitride.Markdown;
namespace MfGames.Nitride.Markdown.Validators;
public class ConvertMarkdownToBaseValidator
: AbstractValidator<ConvertMarkdownToBase>

View file

@ -1,6 +1,6 @@
using FluentValidation;
namespace MfGames.Nitride.Markdown;
namespace MfGames.Nitride.Markdown.Validators;
public class IdentifyMarkdownValidator : AbstractValidator<IdentifyMarkdown>
{

View file

@ -20,9 +20,9 @@ public partial class ApplySchedules : OperationBase
public ApplySchedules(
IValidator<ApplySchedules> validator,
Timekeeper timekeeper)
TimeService timeService)
{
this.Timekeeper = timekeeper;
this.TimeService = timeService;
this.validator = validator;
}
@ -35,9 +35,9 @@ public partial class ApplySchedules : OperationBase
public Func<Entity, IList<ISchedule>?>? GetSchedules { get; set; }
/// <summary>
/// Gets or sets the timekeeper associated with this operation.
/// Gets or sets the time service associated with this operation.
/// </summary>
public Timekeeper Timekeeper { get; set; }
public TimeService TimeService { get; set; }
/// <inheritdoc />
public override IEnumerable<Entity> Run(
@ -49,6 +49,15 @@ public partial class ApplySchedules : OperationBase
return input.Select(this.Apply);
}
/// <summary>
/// Adds a single schedule into the apply schedules and returns the ApplySchedule
/// class.
/// </summary>
public ApplySchedules WithGetSchedules(Func<Entity, ISchedule> schedule)
{
return this.WithGetSchedules(entity => new[] { schedule(entity) });
}
public ApplySchedules WithGetSchedules<TType>(
Func<Entity, IEnumerable<TType>?> value)
where TType : ISchedule
@ -74,12 +83,12 @@ public partial class ApplySchedules : OperationBase
// Otherwise, apply the schedules to this entity.
foreach (ISchedule schedule in schedules)
{
if (!schedule.CanApply(entity))
if (schedule == null! || !schedule.CanApply(entity))
{
continue;
}
entity = schedule.Apply(entity, this.Timekeeper);
entity = schedule.Apply(entity, this.TimeService);
}
return entity;

View file

@ -12,14 +12,14 @@ public interface ISchedule
/// Applies the schedule changes to the entity and returns the results.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="timekeeper">The timekeeper for apply.</param>
/// <param name="timeService">The service to use for time.</param>
/// <returns>
/// The modified entity, if the changes can be applied, otherwise the same
/// entity.
/// </returns>
Entity Apply(
Entity entity,
Timekeeper timekeeper);
TimeService timeService);
/// <summary>
/// Determines if a schedule applies to a given entity.

View file

@ -34,7 +34,7 @@ public partial class IndexedPathRegexSchedule<TSchedule> : PathRegexScheduleBase
protected override Entity Apply(
Entity entity,
int number,
Timekeeper timekeeper)
TimeService timeService)
{
// Figure out the entry in the index.
var applicableKeys = this.Indexes.Keys
@ -52,6 +52,6 @@ public partial class IndexedPathRegexSchedule<TSchedule> : PathRegexScheduleBase
// Pass everything into the schedule to perform the applying.
int startOffset = number - startIndex;
return schedule.Apply(entity, startOffset, timekeeper);
return schedule.Apply(entity, startOffset, timeService);
}
}

View file

@ -42,7 +42,7 @@ public partial class IndexedSchedule
public virtual Entity Apply(
Entity entity,
int number,
Timekeeper timekeeper)
TimeService timeService)
{
// If we have a "never", then we skip it.
TimeSpan? period = this.SchedulePeriodTimeSpan;
@ -55,10 +55,10 @@ public partial class IndexedSchedule
// Figure out the time from the start.
DateTime when = start.Value + period.Value * number;
Instant instant = timekeeper.CreateInstant(when);
Instant instant = timeService.CreateInstant(when);
// If the time hasn't past, then we don't apply it.
Instant now = timekeeper.Clock.GetCurrentInstant();
Instant now = timeService.Clock.GetCurrentInstant();
return instant > now
? entity

View file

@ -47,7 +47,7 @@ public abstract partial class PathRegexScheduleBase : ISchedule
/// <inheritdoc />
public virtual Entity Apply(
Entity entity,
Timekeeper timekeeper)
TimeService timeService)
{
// Get the path and match it.
string path = this.GetPath(entity);
@ -83,7 +83,7 @@ public abstract partial class PathRegexScheduleBase : ISchedule
number += this.CaptureOffset;
// Pass it onto the extending class.
return this.Apply(entity, number, timekeeper);
return this.Apply(entity, number, timeService);
}
/// <inheritdoc />
@ -107,7 +107,7 @@ public abstract partial class PathRegexScheduleBase : ISchedule
protected abstract Entity Apply(
Entity entity,
int number,
Timekeeper timekeeper);
TimeService timeService);
private Regex? GetRegex()
{

View file

@ -49,7 +49,7 @@ public partial class PeriodicPathRegexSchedule : PathRegexScheduleBase
protected override Entity Apply(
Entity entity,
int number,
Timekeeper timekeeper)
TimeService timeService)
{
// If we have a "never", then we skip it.
TimeSpan? period = this.SchedulePeriodTimeSpan;
@ -62,10 +62,10 @@ public partial class PeriodicPathRegexSchedule : PathRegexScheduleBase
// Figure out the time from the start.
DateTime when = start.Value + period.Value * number;
Instant instant = timekeeper.CreateInstant(when);
Instant instant = timeService.CreateInstant(when);
// If the time hasn't past, then we don't apply it.
Instant now = timekeeper.Clock.GetCurrentInstant();
Instant now = timeService.Clock.GetCurrentInstant();
return instant > now
? entity

View file

@ -10,7 +10,7 @@ date (as provided by the `MfGames.Nitride.Temporal` package).
A schedule is not needed when the date is in the path or inside a component. Using
`MfGames.Nitride.Temporal.SetFromComponent` or `MfGames.Nitride.Temporal.SetFromPath`
would be more than sufficient. This is for dynamically changing entities based on
the date based on `Timekeeper`.
the date based on `TimeService`.
## Configuring
@ -53,7 +53,7 @@ The following properties are available (along with their corresponding `With*` m
- `IList<ISchedule> Schedules`
- Contains the list of schedules to apply against entities.
- Defaults to an empty list.
- `Timekeeper Timekeeper`
- `TimeService TimeService`
- Used to determine when the site is being generated.
- Defaults to the one provided by `MfGames.Nitride.Temporal`.

View file

@ -21,15 +21,15 @@ public partial class SimplePathSchedule : ISchedule
/// <inheritdoc />
public virtual Entity Apply(
Entity entity,
Timekeeper timekeeper)
TimeService timeService)
{
DateTime start = this.ScheduleStart
?? throw new NullReferenceException(
"Cannot use a schedule without a start date.");
Instant instant = timekeeper.CreateInstant(start);
Instant instant = timeService.CreateInstant(start);
// If the time hasn't past, then we don't apply it.
Instant now = timekeeper.Clock.GetCurrentInstant();
Instant now = timeService.Clock.GetCurrentInstant();
return instant > now
? entity

View file

@ -9,7 +9,7 @@ public class ApplySchedulesValidator : AbstractValidator<ApplySchedules>
this.RuleFor(x => x.GetSchedules)
.NotNull();
this.RuleFor(x => x.Timekeeper)
this.RuleFor(x => x.TimeService)
.NotNull();
}
}

View file

@ -20,14 +20,14 @@ public class DatePipelineCommandOption : IPipelineCommandOption
{
private readonly ILogger logger;
private readonly Timekeeper timekeeper;
private readonly TimeService timeService;
public DatePipelineCommandOption(
ILogger logger,
Timekeeper timekeeper)
TimeService timeService)
{
this.logger = logger.ForContext<Instant>();
this.timekeeper = timekeeper;
this.timeService = timeService;
this.Option = new Option<DateTime>("--date")
{
@ -53,15 +53,15 @@ public class DatePipelineCommandOption : IPipelineCommandOption
// date for the entire run.
var local = LocalDateTime.FromDateTime(value.Value);
ZonedDateTime zoned =
local.InZoneStrictly(this.timekeeper.DateTimeZone);
local.InZoneStrictly(this.timeService.DateTimeZone);
var instant = zoned.ToInstant();
this.timekeeper.Clock = new FakeClock(instant);
this.timeService.Clock = new FakeClock(instant);
}
// Report the date we are processing.
Instant now = this.timekeeper.Clock.GetCurrentInstant();
ZonedDateTime dateTime = now.InZone(this.timekeeper.DateTimeZone);
Instant now = this.timeService.Clock.GetCurrentInstant();
ZonedDateTime dateTime = now.InZone(this.timeService.DateTimeZone);
string formatted = dateTime.ToString("G", CultureInfo.InvariantCulture);
this.logger.Information("Setting date/time to {When:l}", formatted);

View file

@ -18,13 +18,13 @@ namespace MfGames.Nitride.Temporal.Cli;
/// </summary>
public class ExpiresPipelineCommandOption : IPipelineCommandOption
{
private readonly Timekeeper clock;
private readonly TimeService clock;
private readonly ILogger logger;
public ExpiresPipelineCommandOption(
ILogger logger,
Timekeeper clock,
TimeService clock,
string? defaultValue = null)
{
this.logger = logger.ForContext<Instant>();

View file

@ -25,10 +25,10 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
public CreateDateIndexes(
IValidator<CreateDateIndexes> validator,
Timekeeper timekeeper)
TimeService timeService)
{
this.validator = validator;
this.Timekeeper = timekeeper;
this.TimeService = timeService;
}
/// <summary>
@ -51,7 +51,7 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
/// </summary>
public int LessThanEqualCollapse { get; set; }
public Timekeeper Timekeeper { get; }
public TimeService TimeService { get; }
/// <inheritdoc />
public override IEnumerable<Entity> Run(
@ -136,7 +136,7 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
Entity? first = pair.Value[0];
string? nextKey = this.Timekeeper
string? nextKey = this.TimeService
.ToDateTime(first.Get<Instant>())
.ToString(this.Formats[i + 1]);
@ -166,7 +166,7 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
List<Dictionary<string, List<Entity>>> grouped,
Entity entity)
{
var dateTime = this.Timekeeper.ToDateTime(instant);
var dateTime = this.TimeService.ToDateTime(instant);
for (int i = 0; i < this.Formats.Count; i++)
{

View file

@ -20,13 +20,13 @@ public partial class FilterOutExpiredInstant : OperationBase
public FilterOutExpiredInstant(
IValidator<FilterOutExpiredInstant> validator,
Timekeeper clock)
TimeService clock)
{
this.validator = validator;
this.Timekeeper = clock;
this.TimeService = clock;
}
public Timekeeper Timekeeper { get; set; }
public TimeService TimeService { get; set; }
/// <inheritdoc />
public override IEnumerable<Entity> Run(
@ -35,7 +35,7 @@ public partial class FilterOutExpiredInstant : OperationBase
{
this.validator.ValidateAndThrow(this);
if (!this.Timekeeper.Expiration.HasValue)
if (!this.TimeService.Expiration.HasValue)
{
return input;
}
@ -48,7 +48,7 @@ public partial class FilterOutExpiredInstant : OperationBase
Instant instant,
CanExpire _)
{
Instant expiration = this.Timekeeper.Expiration!.Value;
Instant expiration = this.TimeService.Expiration!.Value;
bool isExpired = instant.CompareTo(expiration) < 0;
return isExpired ? null : entity;

View file

@ -15,19 +15,19 @@ namespace MfGames.Nitride.Temporal;
[WithProperties]
public partial class FilterOutFutureInstant : OperationBase
{
public FilterOutFutureInstant(Timekeeper timekeeper)
public FilterOutFutureInstant(TimeService timeService)
{
this.Timekeeper = timekeeper;
this.TimeService = timeService;
}
public Timekeeper Timekeeper { get; set; }
public TimeService TimeService { get; set; }
/// <inheritdoc />
public override IEnumerable<Entity> Run(
IEnumerable<Entity> input,
CancellationToken cancellationToken = default)
{
Instant now = this.Timekeeper.Clock.GetCurrentInstant();
Instant now = this.TimeService.Clock.GetCurrentInstant();
return input
.SelectEntity<Instant>(

View file

@ -10,18 +10,18 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="6.4.0"/>
<PackageReference Include="MfGames.Gallium" Version="0.4.0"/>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0"/>
<PackageReference Include="NodaTime" Version="3.1.2"/>
<PackageReference Include="NodaTime.Testing" Version="3.1.2"/>
<PackageReference Include="Serilog" Version="2.11.0"/>
<PackageReference Include="TimeSpanParserUtil" Version="1.2.0"/>
<PackageReference Include="Zio" Version="0.15.0"/>
<PackageReference Include="Autofac" Version="6.4.0" />
<PackageReference Include="MfGames.Gallium" Version="0.4.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="NodaTime" Version="3.1.2" />
<PackageReference Include="NodaTime.Testing" Version="3.1.2" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="TimeSpanParserUtil" Version="1.2.0" />
<PackageReference Include="Zio" Version="0.15.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj"/>
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj" />
</ItemGroup>
<!-- Include the source generator -->

View file

@ -17,11 +17,11 @@ namespace MfGames.Nitride.Temporal;
/// </summary>
public class SetInstantFromComponent<TComponent> : OperationBase
{
private readonly Timekeeper clock;
private readonly TimeService clock;
private readonly IValidator<SetInstantFromComponent<TComponent>> validator;
public SetInstantFromComponent(Timekeeper clock)
public SetInstantFromComponent(TimeService clock)
{
// TODO: Figure out why Autofac won't let us register IValidator of generic classes.
this.validator = new SetInstantFromComponentValidator<TComponent>();
@ -73,6 +73,7 @@ public class SetInstantFromComponent<TComponent> : OperationBase
{
case null:
return entity;
case Instant direct:
instant = direct;

View file

@ -23,13 +23,13 @@ namespace MfGames.Nitride.Temporal;
[WithProperties]
public partial class SetInstantFromPath : OperationBase
{
private readonly Timekeeper clock;
private readonly TimeService clock;
private readonly IValidator<SetInstantFromPath> validator;
public SetInstantFromPath(
IValidator<SetInstantFromPath> validator,
Timekeeper clock)
TimeService clock)
{
this.validator = validator;
this.clock = clock;
@ -67,15 +67,9 @@ public partial class SetInstantFromPath : OperationBase
// Create an Instant from this.
Instant instant = this.clock.CreateInstant(
Convert.ToInt32(
match.Groups["year"]
.Value),
Convert.ToInt32(
match.Groups["month"]
.Value),
Convert.ToInt32(
match.Groups["day"]
.Value));
Convert.ToInt32(match.Groups["year"].Value),
Convert.ToInt32(match.Groups["month"].Value),
Convert.ToInt32(match.Groups["day"].Value));
return entity.Set(instant);
}

View file

@ -45,8 +45,8 @@ public static class NitrideTemporalBuilderExtensions
context =>
{
ILogger logger = context.Resolve<ILogger>();
Timekeeper
clock = context.Resolve<Timekeeper>();
TimeService
clock = context.Resolve<TimeService>();
return new ExpiresPipelineCommandOption(
logger,
@ -65,12 +65,12 @@ public static class NitrideTemporalBuilderExtensions
scope) =>
{
ILogger logger = scope.Resolve<ILogger>();
Timekeeper timekeeper = scope.Resolve<Timekeeper>();
TimeService timeService = scope.Resolve<TimeService>();
timekeeper.DateTimeZone = config.DateTimeZone;
timeService.DateTimeZone = config.DateTimeZone;
logger.Verbose(
"Setting time zone to {Zone:l}",
timekeeper.DateTimeZone);
timeService.DateTimeZone);
});
}

View file

@ -10,7 +10,7 @@ public class NitrideTemporalModule : Module
builder.RegisterOperators(this);
builder.RegisterValidators(this);
builder.RegisterType<Timekeeper>()
builder.RegisterType<TimeService>()
.AsSelf()
.SingleInstance();

View file

@ -10,9 +10,9 @@ namespace MfGames.Nitride.Temporal;
/// the desire time zone along with various methods for processing parsed
/// DateTime objects into NodaTime.Instant.
/// </summary>
public class Timekeeper
public class TimeService
{
public Timekeeper()
public TimeService()
{
// We use FakeClock because we don't want time to advance in the
// middle of running, just in case we are just a few seconds before
@ -28,6 +28,16 @@ public class Timekeeper
/// </summary>
public IClock Clock { get; set; }
/// <summary>
/// Gets the current date time.
/// </summary>
public DateTime CurrentDateTime => this.ToDateTime(this.CurrentInstant);
/// <summary>
/// Gets the current instant.
/// </summary>
public Instant CurrentInstant => this.Clock.GetCurrentInstant();
/// <summary>
/// Gets or sets the date time zone used for processing.
/// </summary>

View file

@ -6,7 +6,7 @@ public class CreateDateIndexesValidator : AbstractValidator<CreateDateIndexes>
{
public CreateDateIndexesValidator()
{
this.RuleFor(a => a.Timekeeper)
this.RuleFor(a => a.TimeService)
.NotNull();
this.RuleFor(a => a.CreateIndex)

View file

@ -7,7 +7,7 @@ public class FilterOutExpiredInstantValidator
{
public FilterOutExpiredInstantValidator()
{
this.RuleFor(x => x.Timekeeper)
this.RuleFor(x => x.TimeService)
.NotNull();
}
}

View file

@ -7,7 +7,7 @@ public class FilterOutFutureInstantValidator
{
public FilterOutFutureInstantValidator()
{
this.RuleFor(x => x.Timekeeper)
this.RuleFor(x => x.TimeService)
.NotNull();
}
}

View file

@ -62,7 +62,7 @@ public class IndexedPathRegexScheduleTest : TemporalSchedulesTestBase
// Create the operation and run it, but treat it as being set after the
// second but before the third item.
Timekeeper time = context.Resolve<Timekeeper>();
TimeService time = context.Resolve<TimeService>();
ApplySchedules op = context.Resolve<ApplySchedules>()
.WithGetSchedules(_ => new ISchedule[] { schedules });
var now = Instant.FromUtc(2023, 1, 3, 0, 0);
@ -120,7 +120,7 @@ public class IndexedPathRegexScheduleTest : TemporalSchedulesTestBase
// Create the operation and run it, but treat it as being set after the
// second but before the third item.
Timekeeper time = context.Resolve<Timekeeper>();
TimeService time = context.Resolve<TimeService>();
ApplySchedules op = context.Resolve<ApplySchedules>()
.WithGetSchedules(_ => new ISchedule[] { schedules });
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
@ -192,7 +192,7 @@ public class IndexedPathRegexScheduleTest : TemporalSchedulesTestBase
// Create the operation and run it, but treat it as being set after the
// second but before the third item.
Timekeeper time = context.Resolve<Timekeeper>();
TimeService time = context.Resolve<TimeService>();
ApplySchedules op = context.Resolve<ApplySchedules>()
.WithGetSchedules(_ => new ISchedule[] { schedules });
var now = Instant.FromUtc(2023, 1, 9, 0, 0);

View file

@ -56,7 +56,7 @@ public class PeriodicPathRegexScheduleTest : TemporalSchedulesTestBase
// Create the operation and run it, but treat it as being set after the
// second but before the third item.
Timekeeper time = context.Resolve<Timekeeper>();
TimeService time = context.Resolve<TimeService>();
ApplySchedules op = context.Resolve<ApplySchedules>()
.WithGetSchedules(_ => schedules);
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
@ -111,7 +111,7 @@ public class PeriodicPathRegexScheduleTest : TemporalSchedulesTestBase
// Create the operation and run it, but treat it as being set after the
// second but before the third item.
Timekeeper time = context.Resolve<Timekeeper>();
TimeService time = context.Resolve<TimeService>();
ApplySchedules op = context.Resolve<ApplySchedules>()
.WithGetSchedules(_ => schedules);
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
@ -167,7 +167,7 @@ public class PeriodicPathRegexScheduleTest : TemporalSchedulesTestBase
// Create the operation and run it, but treat it as being set after the
// second but before the third item.
Timekeeper time = context.Resolve<Timekeeper>();
TimeService time = context.Resolve<TimeService>();
ApplySchedules op = context.Resolve<ApplySchedules>()
.WithGetSchedules(_ => schedules);
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
@ -227,7 +227,7 @@ public class PeriodicPathRegexScheduleTest : TemporalSchedulesTestBase
// Create the operation and run it, but treat it as being set after the
// second but before the third item.
Timekeeper time = context.Resolve<Timekeeper>();
TimeService time = context.Resolve<TimeService>();
ApplySchedules op = context.Resolve<ApplySchedules>()
.WithGetSchedules(_ => schedules);
var now = Instant.FromUtc(2023, 1, 9, 0, 0);

View file

@ -21,7 +21,7 @@ public class CreateDateIndexesTests : TemporalTestBase
public void MonthOnlyIndexes()
{
using TemporalTestContext context = this.CreateContext();
Timekeeper timekeeper = context.Resolve<Timekeeper>();
TimeService timeService = context.Resolve<TimeService>();
CreateDateIndexes op = context.Resolve<CreateDateIndexes>()
.WithFormats("yyyy-MM")
@ -30,11 +30,11 @@ public class CreateDateIndexesTests : TemporalTestBase
List<Entity> input = new()
{
new Entity().Add("page1")
.Add(timekeeper.CreateInstant(2021, 1, 2)),
.Add(timeService.CreateInstant(2021, 1, 2)),
new Entity().Add("page2")
.Add(timekeeper.CreateInstant(2021, 2, 2)),
.Add(timeService.CreateInstant(2021, 2, 2)),
new Entity().Add("page3")
.Add(timekeeper.CreateInstant(2022, 1, 2)),
.Add(timeService.CreateInstant(2022, 1, 2)),
};
List<Tuple<string, List<string>?, List<string>?>> actual =
@ -66,7 +66,7 @@ public class CreateDateIndexesTests : TemporalTestBase
public void YearMonthDayIndexes()
{
using TemporalTestContext context = this.CreateContext();
Timekeeper timekeeper = context.Resolve<Timekeeper>();
TimeService timeService = context.Resolve<TimeService>();
CreateDateIndexes op = context.Resolve<CreateDateIndexes>()
.WithFormats("yyyy/MM/dd", "yyyy/MM", "yyyy")
@ -75,11 +75,11 @@ public class CreateDateIndexesTests : TemporalTestBase
List<Entity> input = new()
{
new Entity().Add("page1")
.Add(timekeeper.CreateInstant(2021, 1, 2)),
.Add(timeService.CreateInstant(2021, 1, 2)),
new Entity().Add("page2")
.Add(timekeeper.CreateInstant(2021, 2, 2)),
.Add(timeService.CreateInstant(2021, 2, 2)),
new Entity().Add("page3")
.Add(timekeeper.CreateInstant(2022, 1, 2)),
.Add(timeService.CreateInstant(2022, 1, 2)),
};
List<Tuple<string, List<string>?, List<string>?>> actual =
@ -131,7 +131,7 @@ public class CreateDateIndexesTests : TemporalTestBase
public void YearMonthDayIndexesThreshold1()
{
using TemporalTestContext context = this.CreateContext();
Timekeeper timekeeper = context.Resolve<Timekeeper>();
TimeService timeService = context.Resolve<TimeService>();
CreateDateIndexes op = context.Resolve<CreateDateIndexes>()
.WithFormats("yyyy/MM/dd", "yyyy/MM", "yyyy")
@ -141,11 +141,11 @@ public class CreateDateIndexesTests : TemporalTestBase
List<Entity> input = new()
{
new Entity().Add("page1")
.Add(timekeeper.CreateInstant(2021, 1, 2)),
.Add(timeService.CreateInstant(2021, 1, 2)),
new Entity().Add("page2")
.Add(timekeeper.CreateInstant(2021, 2, 2)),
.Add(timeService.CreateInstant(2021, 2, 2)),
new Entity().Add("page3")
.Add(timekeeper.CreateInstant(2022, 1, 2)),
.Add(timeService.CreateInstant(2022, 1, 2)),
};
List<Tuple<string, List<string>?, List<string>?>> actual =
@ -197,7 +197,7 @@ public class CreateDateIndexesTests : TemporalTestBase
public void YearMonthIndexes()
{
using TemporalTestContext context = this.CreateContext();
Timekeeper timekeeper = context.Resolve<Timekeeper>();
TimeService timeService = context.Resolve<TimeService>();
CreateDateIndexes op = context.Resolve<CreateDateIndexes>()
.WithFormats("yyyy-MM", "yyyy")
@ -206,11 +206,11 @@ public class CreateDateIndexesTests : TemporalTestBase
List<Entity> input = new()
{
new Entity().Add("page1")
.Add(timekeeper.CreateInstant(2021, 1, 2)),
.Add(timeService.CreateInstant(2021, 1, 2)),
new Entity().Add("page2")
.Add(timekeeper.CreateInstant(2021, 2, 2)),
.Add(timeService.CreateInstant(2021, 2, 2)),
new Entity().Add("page3")
.Add(timekeeper.CreateInstant(2022, 1, 2)),
.Add(timeService.CreateInstant(2022, 1, 2)),
};
List<Tuple<string, List<string>?, List<string>?>> actual =
@ -250,7 +250,7 @@ public class CreateDateIndexesTests : TemporalTestBase
public void YearOnlyIndexes()
{
using TemporalTestContext context = this.CreateContext();
Timekeeper timekeeper = context.Resolve<Timekeeper>();
TimeService timeService = context.Resolve<TimeService>();
CreateDateIndexes op = context.Resolve<CreateDateIndexes>()
.WithFormats("yyyy")
@ -259,11 +259,11 @@ public class CreateDateIndexesTests : TemporalTestBase
List<Entity> input = new()
{
new Entity().Add("page1")
.Add(timekeeper.CreateInstant(2021, 1, 2)),
.Add(timeService.CreateInstant(2021, 1, 2)),
new Entity().Add("page2")
.Add(timekeeper.CreateInstant(2021, 2, 2)),
.Add(timeService.CreateInstant(2021, 2, 2)),
new Entity().Add("page3")
.Add(timekeeper.CreateInstant(2022, 1, 2)),
.Add(timeService.CreateInstant(2022, 1, 2)),
};
List<Tuple<string, List<string>?, List<string>?>> actual =

View file

@ -22,10 +22,10 @@ public class FilterOutFutureInstantTests : TemporalTestBase
{
// Create the context and set the timestamp to a constant value.
using TemporalTestContext context = this.CreateContext();
Timekeeper timekeeper = context.Resolve<Timekeeper>();
TimeService timeService = context.Resolve<TimeService>();
var now = Instant.FromUtc(2000, 6, 1, 0, 0);
timekeeper.Clock = new FakeClock(now);
timeService.Clock = new FakeClock(now);
// Create the entities.
List<Entity> input = new()
@ -52,10 +52,10 @@ public class FilterOutFutureInstantTests : TemporalTestBase
{
// Create the context and set the timestamp to a constant value.
using TemporalTestContext context = this.CreateContext();
Timekeeper timekeeper = context.Resolve<Timekeeper>();
TimeService timeService = context.Resolve<TimeService>();
var now = Instant.FromUtc(2000, 6, 1, 0, 0);
timekeeper.Clock = new FakeClock(now);
timeService.Clock = new FakeClock(now);
// Create the entities.
List<Entity> input = new()