fix(scheduler): added better error messages and regular expression for numerical paths
This commit is contained in:
parent
185980b5c4
commit
070cf2bfb8
3 changed files with 84 additions and 8 deletions
|
@ -21,7 +21,7 @@ public partial class NumericalPathSchedule : ISchedule
|
||||||
{
|
{
|
||||||
public NumericalPathSchedule()
|
public NumericalPathSchedule()
|
||||||
{
|
{
|
||||||
this.PathRegex = @"^.*(\d+)";
|
this.PathRegex = @"^.*?(\d+)[^\d]*$";
|
||||||
this.GetPath = entity => entity.Get<UPath>().ToString();
|
this.GetPath = entity => entity.Get<UPath>().ToString();
|
||||||
this.CaptureGroup = 1;
|
this.CaptureGroup = 1;
|
||||||
this.CaptureOffset = -1;
|
this.CaptureOffset = -1;
|
||||||
|
@ -61,11 +61,15 @@ public partial class NumericalPathSchedule : ISchedule
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the schedule period as a TimeSpan object. This is converted
|
/// Gets or sets the schedule period as a TimeSpan object. This is converted
|
||||||
/// from SchedulePeriod using https://github.com/pengowray/TimeSpanParser.
|
/// from SchedulePeriod using https://github.com/pengowray/TimeSpanParser.
|
||||||
/// If the value is null, then this will be instant (TimeSpan.Zero).
|
/// If the value is null or blank or "immediate", then this will be instant
|
||||||
|
/// (TimeSpan.Zero).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual TimeSpan SchedulePeriodTimeSpan
|
public virtual TimeSpan SchedulePeriodTimeSpan
|
||||||
{
|
{
|
||||||
get => this.SchedulePeriod == null
|
get => string.IsNullOrWhiteSpace(this.SchedulePeriod)
|
||||||
|
|| this.SchedulePeriod.Equals(
|
||||||
|
"immediate",
|
||||||
|
StringComparison.InvariantCultureIgnoreCase)
|
||||||
? TimeSpan.Zero
|
? TimeSpan.Zero
|
||||||
: TimeSpanParser.Parse(this.SchedulePeriod);
|
: TimeSpanParser.Parse(this.SchedulePeriod);
|
||||||
set => this.SchedulePeriod = value.ToString();
|
set => this.SchedulePeriod = value.ToString();
|
||||||
|
@ -95,9 +99,24 @@ public partial class NumericalPathSchedule : ISchedule
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match.Groups.Count < 2)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"There must be at least one capture group in '"
|
||||||
|
+ this.PathRegex
|
||||||
|
+ "'.");
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out the index/number of this entry.
|
// Figure out the index/number of this entry.
|
||||||
int number = int.Parse(match.Groups[this.CaptureGroup].Value)
|
string numberValue = match.Groups[this.CaptureGroup].Value;
|
||||||
+ this.CaptureOffset;
|
|
||||||
|
if (!int.TryParse(numberValue, out int number))
|
||||||
|
{
|
||||||
|
throw new FormatException(
|
||||||
|
path + ": Cannot parse '" + numberValue + "' as integer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
number += this.CaptureOffset;
|
||||||
|
|
||||||
// Figure out the time from the start.
|
// Figure out the time from the start.
|
||||||
DateTime start = this.ScheduleStart
|
DateTime start = this.ScheduleStart
|
||||||
|
|
|
@ -103,7 +103,7 @@ chapter will be set to 2023-01-08, and the third at 2023-01-15.
|
||||||
- Defaults to `entity.Get<UPath>().ToString()`
|
- Defaults to `entity.Get<UPath>().ToString()`
|
||||||
- `Regex PathRegex`
|
- `Regex PathRegex`
|
||||||
- The regular expression that retrieves the number.
|
- The regular expression that retrieves the number.
|
||||||
- Defaults to `^.*(\d+)` which grabs the last number found.
|
- Defaults to `^.*?(\d+)[^\d]*$` which grabs the last number found.
|
||||||
- `DateTime ScheduleStart`
|
- `DateTime ScheduleStart`
|
||||||
- The date that the schedule starts.
|
- The date that the schedule starts.
|
||||||
- No default.
|
- No default.
|
||||||
|
|
|
@ -49,6 +49,7 @@ public class NumericalPathScheduleTests : TemporalSchedulesTestBase
|
||||||
"schedules:",
|
"schedules:",
|
||||||
" - pathRegex: chapter-(\\d+)",
|
" - pathRegex: chapter-(\\d+)",
|
||||||
" scheduleStart: 2023-01-01",
|
" scheduleStart: 2023-01-01",
|
||||||
|
" schedulePeriod: 1 week",
|
||||||
" access: public",
|
" access: public",
|
||||||
""));
|
""));
|
||||||
List<TestSchedule>? schedules = model.Schedules!;
|
List<TestSchedule>? schedules = model.Schedules!;
|
||||||
|
@ -141,6 +142,62 @@ public class NumericalPathScheduleTests : TemporalSchedulesTestBase
|
||||||
TestHelper.CompareObjects(expected, actual);
|
TestHelper.CompareObjects(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ScheduleOffsetWorks()
|
||||||
|
{
|
||||||
|
using TemporalSchedulesTestContext context = this.CreateContext();
|
||||||
|
|
||||||
|
// Create a numerical series of entities.
|
||||||
|
var input = new List<Entity>
|
||||||
|
{
|
||||||
|
new Entity().SetAll((UPath)"/chapter-11.md", new TestModel()),
|
||||||
|
new Entity().SetAll((UPath)"/chapter-12.md", new TestModel()),
|
||||||
|
new Entity().SetAll((UPath)"/chapter-13.md", new TestModel()),
|
||||||
|
};
|
||||||
|
|
||||||
|
var schedules = new List<TestSchedule>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
ScheduleStart = DateTime.Parse("2023-01-01"),
|
||||||
|
CaptureOffset = -11,
|
||||||
|
Access = "public",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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>();
|
||||||
|
ApplySchedules op = context.Resolve<ApplySchedules>()
|
||||||
|
.WithGetSchedules(_ => schedules);
|
||||||
|
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
|
||||||
|
|
||||||
|
time.Clock = new FakeClock(now);
|
||||||
|
|
||||||
|
var actual = op
|
||||||
|
.Run(input)
|
||||||
|
.Select(
|
||||||
|
a => string.Format(
|
||||||
|
"{0} -- {1} -- {2}",
|
||||||
|
a.Get<UPath>().ToString(),
|
||||||
|
a.Has<Instant>()
|
||||||
|
? time
|
||||||
|
.ToDateTime(a.Get<Instant>())
|
||||||
|
.ToString("yyyy-MM-dd")
|
||||||
|
: "none",
|
||||||
|
a.Get<TestModel>().Access))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var expected = new List<string>
|
||||||
|
{
|
||||||
|
"/chapter-11.md -- 2023-01-01 -- public",
|
||||||
|
"/chapter-12.md -- 2023-01-08 -- public",
|
||||||
|
"/chapter-13.md -- none -- private",
|
||||||
|
};
|
||||||
|
|
||||||
|
TestHelper.CompareObjects(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SequencedScheduleWorks()
|
public void SequencedScheduleWorks()
|
||||||
{
|
{
|
||||||
|
|
Reference in a new issue