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()
|
||||
{
|
||||
this.PathRegex = @"^.*(\d+)";
|
||||
this.PathRegex = @"^.*?(\d+)[^\d]*$";
|
||||
this.GetPath = entity => entity.Get<UPath>().ToString();
|
||||
this.CaptureGroup = 1;
|
||||
this.CaptureOffset = -1;
|
||||
|
@ -61,13 +61,17 @@ public partial class NumericalPathSchedule : ISchedule
|
|||
/// <summary>
|
||||
/// Gets or sets the schedule period as a TimeSpan object. This is converted
|
||||
/// 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>
|
||||
public virtual TimeSpan SchedulePeriodTimeSpan
|
||||
{
|
||||
get => this.SchedulePeriod == null
|
||||
? TimeSpan.Zero
|
||||
: TimeSpanParser.Parse(this.SchedulePeriod);
|
||||
get => string.IsNullOrWhiteSpace(this.SchedulePeriod)
|
||||
|| this.SchedulePeriod.Equals(
|
||||
"immediate",
|
||||
StringComparison.InvariantCultureIgnoreCase)
|
||||
? TimeSpan.Zero
|
||||
: TimeSpanParser.Parse(this.SchedulePeriod);
|
||||
set => this.SchedulePeriod = value.ToString();
|
||||
}
|
||||
|
||||
|
@ -95,9 +99,24 @@ public partial class NumericalPathSchedule : ISchedule
|
|||
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.
|
||||
int number = int.Parse(match.Groups[this.CaptureGroup].Value)
|
||||
+ this.CaptureOffset;
|
||||
string numberValue = match.Groups[this.CaptureGroup].Value;
|
||||
|
||||
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.
|
||||
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()`
|
||||
- `Regex PathRegex`
|
||||
- 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`
|
||||
- The date that the schedule starts.
|
||||
- No default.
|
||||
|
|
|
@ -49,6 +49,7 @@ public class NumericalPathScheduleTests : TemporalSchedulesTestBase
|
|||
"schedules:",
|
||||
" - pathRegex: chapter-(\\d+)",
|
||||
" scheduleStart: 2023-01-01",
|
||||
" schedulePeriod: 1 week",
|
||||
" access: public",
|
||||
""));
|
||||
List<TestSchedule>? schedules = model.Schedules!;
|
||||
|
@ -141,6 +142,62 @@ public class NumericalPathScheduleTests : TemporalSchedulesTestBase
|
|||
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]
|
||||
public void SequencedScheduleWorks()
|
||||
{
|
||||
|
|
Reference in a new issue