Skip to content

Commit a991eb1

Browse files
authored
Merge pull request #244 from NCronJob-Dev/em/namedcron
Teach JobOptionBuilder to add a cron expression to a named job
2 parents 9fbc921 + d2aa667 commit a991eb1

File tree

4 files changed

+179
-4
lines changed

4 files changed

+179
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ All notable changes to **NCronJob** will be documented in this file. The project
1212
- Expose whether a scheduled job is enabled or not. By [@nulltoken](https://github.com/nulltoken) in [#231](https://github.com/NCronJob-Dev/NCronJob/pull/231).
1313
- Make `IRuntimeJobRegistry.GetAllRecurringJobs()` return the job type. By [@nulltoken](https://github.com/nulltoken) in [#232](https://github.com/NCronJob-Dev/NCronJob/pull/232).
1414
- Surface job name and type through `ExecutionProgress`. By [@nulltoken](https://github.com/nulltoken) in [#234](https://github.com/NCronJob-Dev/NCronJob/pull/234).
15+
- Teach `JobOptionBuilder` to add a cron expression to a named job. By [@nulltoken](https://github.com/nulltoken) in [#244](https://github.com/NCronJob-Dev/NCronJob/pull/244).
1516

1617
### Fixed
1718

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
namespace NCronJob;
2+
3+
/// <summary>
4+
/// Represents a builder to refine a job with a cron expression or a parameter.
5+
/// </summary>
6+
public sealed class CronAndParameterBuilder : IOptionChainerBuilder
7+
{
8+
private readonly JobOptionBuilder optionBuilder;
9+
private readonly JobOption jobOption;
10+
11+
internal CronAndParameterBuilder(JobOptionBuilder optionBuilder, JobOption jobOption)
12+
{
13+
this.optionBuilder = optionBuilder;
14+
this.jobOption = jobOption;
15+
}
16+
17+
/// <summary>
18+
/// Chains another option to the job.
19+
/// </summary>
20+
public JobOptionBuilder And => optionBuilder;
21+
22+
/// <summary>
23+
/// The parameter that can be passed down to the job.<br/>
24+
/// When an instant job is triggered a parameter can be passed down via the <see cref="IInstantJobRegistry"/> interface.
25+
/// </summary>
26+
/// <param name="parameter">The parameter to add that will be passed to the cron job.</param>
27+
/// <returns>Returns a <see cref="IOptionChainerBuilder"/> that allows chaining new options.</returns>
28+
public IOptionChainerBuilder WithParameter(object? parameter)
29+
{
30+
jobOption.Parameter = parameter;
31+
return this;
32+
}
33+
34+
/// <summary>
35+
/// Adds a cron expression for the given job.
36+
/// </summary>
37+
/// <param name="cronExpression">The cron expression that defines when the job should be executed.</param>
38+
/// <param name="timeZoneInfo">Optional, provides the timezone that is used to evaluate the cron expression. Defaults to UTC.</param>
39+
/// <returns>Returns a <see cref="ParameterOnlyBuilder"/> that allows naming the job or adding a parameter to it.</returns>
40+
public ParameterOnlyBuilder WithCronExpression(string cronExpression, TimeZoneInfo? timeZoneInfo = null)
41+
{
42+
ArgumentNullException.ThrowIfNull(cronExpression);
43+
44+
cronExpression = cronExpression.Trim();
45+
46+
jobOption.CronExpression = cronExpression;
47+
jobOption.TimeZoneInfo = timeZoneInfo ?? TimeZoneInfo.Utc;
48+
49+
return new ParameterOnlyBuilder(optionBuilder, jobOption);
50+
}
51+
}

src/NCronJob/Configuration/Builder/JobOptionBuilder.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public ParameterBuilder WithCronExpression(string cronExpression, TimeZoneInfo?
3434
/// Sets the job name. This can be used to identify the job.
3535
/// </summary>
3636
/// <param name="jobName">The job name associated with this job.</param>
37-
/// <returns>Returns a <see cref="ParameterBuilder"/> that allows further configuration.</returns>
37+
/// <returns>Returns a <see cref="CronAndParameterBuilder"/> that allows further configuration.</returns>
3838
/// <remarks>The job name should be unique over all job instances.</remarks>
39-
public ParameterOnlyBuilder WithName(string jobName)
39+
public CronAndParameterBuilder WithName(string jobName)
4040
{
4141
var jobOption = new JobOption
4242
{
@@ -45,7 +45,7 @@ public ParameterOnlyBuilder WithName(string jobName)
4545

4646
jobOptions.Add(jobOption);
4747

48-
return new ParameterOnlyBuilder(this, jobOption);
48+
return new CronAndParameterBuilder(this, jobOption);
4949
}
5050

5151
internal List<JobOption> GetJobOptions()

tests/NCronJob.Tests/JobOptionBuilderTests.cs

+124-1
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,145 @@ public void ShouldCreateMultipleNamedJobsWithAnd()
7979
var builder = new JobOptionBuilder();
8080
builder
8181
.WithName("name1")
82+
.And
83+
.WithName("name2");
84+
85+
var options = builder.GetJobOptions();
86+
87+
options.Count.ShouldBe(2);
88+
options[0].Name.ShouldBe("name1");
89+
options[1].Name.ShouldBe("name2");
90+
}
91+
92+
[Fact]
93+
public void ShouldCreateMultipleNamedJobsWithoutAnd()
94+
{
95+
var builder = new JobOptionBuilder();
96+
builder
97+
.WithName("name1");
98+
99+
builder
100+
.WithName("name2");
101+
102+
var options = builder.GetJobOptions();
103+
104+
options.Count.ShouldBe(2);
105+
options[0].Name.ShouldBe("name1");
106+
options[1].Name.ShouldBe("name2");
107+
}
108+
109+
[Fact]
110+
public void ShouldCreateMultipleNamedAndScheduledJobsWithAnd()
111+
{
112+
var builder = new JobOptionBuilder();
113+
builder
114+
.WithName("name1")
115+
.WithCronExpression(Cron.AtEveryMinute)
116+
.And
117+
.WithName("name2")
118+
.WithCronExpression(Cron.AtEveryMinute);
119+
120+
var options = builder.GetJobOptions();
121+
122+
options.Count.ShouldBe(2);
123+
options[0].Name.ShouldBe("name1");
124+
options[0].CronExpression.ShouldBe(Cron.AtEveryMinute);
125+
options[1].Name.ShouldBe("name2");
126+
options[1].CronExpression.ShouldBe(Cron.AtEveryMinute);
127+
}
128+
129+
[Fact]
130+
public void ShouldCreateMultipleNamedAndScheduledJobsWithoutAnd()
131+
{
132+
var builder = new JobOptionBuilder();
133+
builder
134+
.WithName("name1")
135+
.WithCronExpression(Cron.AtEveryMinute);
136+
137+
builder
138+
.WithName("name2")
139+
.WithCronExpression(Cron.AtEveryMinute);
140+
141+
var options = builder.GetJobOptions();
142+
143+
options.Count.ShouldBe(2);
144+
options[0].Name.ShouldBe("name1");
145+
options[0].CronExpression.ShouldBe(Cron.AtEveryMinute);
146+
options[1].Name.ShouldBe("name2");
147+
options[1].CronExpression.ShouldBe(Cron.AtEveryMinute);
148+
}
149+
150+
[Fact]
151+
public void ShouldCreateMultipleNamedScheduledAndParameterizedJobsWithAnd()
152+
{
153+
var builder = new JobOptionBuilder();
154+
builder
155+
.WithName("name1")
156+
.WithCronExpression(Cron.AtEveryMinute)
82157
.WithParameter("foo")
83158
.And
84159
.WithName("name2")
160+
.WithCronExpression(Cron.AtEveryMinute)
85161
.WithParameter("bar");
86162

87163
var options = builder.GetJobOptions();
88164

89165
options.Count.ShouldBe(2);
90166
options[0].Name.ShouldBe("name1");
167+
options[0].CronExpression.ShouldBe(Cron.AtEveryMinute);
91168
options[0].Parameter.ShouldBe("foo");
92169
options[1].Name.ShouldBe("name2");
170+
options[1].CronExpression.ShouldBe(Cron.AtEveryMinute);
93171
options[1].Parameter.ShouldBe("bar");
94172
}
95173

96174
[Fact]
97-
public void ShouldCreateMultipleNamedJobsWithoutAnd()
175+
public void ShouldCreateMultipleNamedScheduledAndParameterizedJobsWithoutAnd()
176+
{
177+
var builder = new JobOptionBuilder();
178+
builder
179+
.WithName("name1")
180+
.WithCronExpression(Cron.AtEveryMinute)
181+
.WithParameter("foo");
182+
183+
builder
184+
.WithName("name2")
185+
.WithCronExpression(Cron.AtEveryMinute)
186+
.WithParameter("bar");
187+
188+
var options = builder.GetJobOptions();
189+
190+
options.Count.ShouldBe(2);
191+
options[0].Name.ShouldBe("name1");
192+
options[0].CronExpression.ShouldBe(Cron.AtEveryMinute);
193+
options[0].Parameter.ShouldBe("foo");
194+
options[1].Name.ShouldBe("name2");
195+
options[1].CronExpression.ShouldBe(Cron.AtEveryMinute);
196+
options[1].Parameter.ShouldBe("bar");
197+
}
198+
199+
[Fact]
200+
public void ShouldCreateMultipleNamedAndParameterizedJobsWithAnd()
201+
{
202+
var builder = new JobOptionBuilder();
203+
builder
204+
.WithName("name1")
205+
.WithParameter("foo")
206+
.And
207+
.WithName("name2")
208+
.WithParameter("bar");
209+
210+
var options = builder.GetJobOptions();
211+
212+
options.Count.ShouldBe(2);
213+
options[0].Name.ShouldBe("name1");
214+
options[0].Parameter.ShouldBe("foo");
215+
options[1].Name.ShouldBe("name2");
216+
options[1].Parameter.ShouldBe("bar");
217+
}
218+
219+
[Fact]
220+
public void ShouldCreateMultipleNamedAndParameterizedJobsWithoutAnd()
98221
{
99222
var builder = new JobOptionBuilder();
100223
builder

0 commit comments

Comments
 (0)