From 8ae7d39f4bef7d4b6164712a39a3ca3d6ed2b4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Breu=C3=9F=20Valentin?= Date: Fri, 6 Mar 2026 12:26:52 +0100 Subject: [PATCH 1/2] feat: give access to `Timeout` and `CancellationToken` in the `ExpectationBuilder` --- .../aweXpect.Core/Core/ExpectationBuilder.cs | 28 ++++++++++++------- .../Expected/aweXpect.Core_net10.0.txt | 4 +++ .../Expected/aweXpect.Core_net8.0.txt | 4 +++ .../Expected/aweXpect.Core_netstandard2.0.txt | 4 +++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Source/aweXpect.Core/Core/ExpectationBuilder.cs b/Source/aweXpect.Core/Core/ExpectationBuilder.cs index 326811739..21c5d3f8b 100644 --- a/Source/aweXpect.Core/Core/ExpectationBuilder.cs +++ b/Source/aweXpect.Core/Core/ExpectationBuilder.cs @@ -21,8 +21,6 @@ public abstract class ExpectationBuilder { private const string DefaultCurrentSubject = "it"; - private CancellationToken? _cancellationToken; - private ResultContexts? _contexts; /// @@ -31,7 +29,6 @@ public abstract class ExpectationBuilder private string _it = DefaultCurrentSubject; private Node _node = new ExpectationNode(); - private TimeSpan? _timeout; private ITimeSystem? _timeSystem; @@ -59,6 +56,16 @@ private protected ExpectationBuilder() ExpectationGrammars = ExpectationGrammars.None; } + /// + /// The explicit cancellation token to be used for the expectation. + /// + public CancellationToken? CancellationToken { get; private set; } + + /// + /// The timeout to be applied to the expectation. + /// + public TimeSpan? Timeout { get; private set; } + /// /// The expected grammatical form of the expectation text. /// @@ -278,13 +285,13 @@ public MemberExpectationBuilder ForAsyncMember to be used by the constraints. /// public void WithCancellation(CancellationToken cancellationToken) - => _cancellationToken = cancellationToken; + => CancellationToken = cancellationToken; /// /// Adds a to be used by the constraints. /// public void WithTimeout(TimeSpan timeout) - => _timeout = timeout; + => Timeout = timeout; /// /// Adds a to the current expectation constraint. @@ -388,7 +395,7 @@ public virtual ExpectationBuilder UpdateContexts(Action callback } /// - /// Adds the to the context that is included in the failure message. + /// Adds the to the context that is included in the failure message. /// public virtual ExpectationBuilder AddContext(ResultContext resultContext) { @@ -406,7 +413,7 @@ public virtual ExpectationBuilder AddContext(ResultContext resultContext) /// Creates the exception message from the . /// internal Task FromFailure(ConstraintResult failure) - => FromFailure(Subject, failure, _contexts, _cancellationToken ?? CancellationToken.None); + => FromFailure(Subject, failure, _contexts, CancellationToken ?? System.Threading.CancellationToken.None); /// /// Creates the exception message from the . @@ -463,9 +470,10 @@ internal Task IsMet() EvaluationContext.EvaluationContext context = new(); ITimeSystem timeSystem = _timeSystem ?? RealTimeSystem.Instance; TestCancellation? testCancellation = Customize.aweXpect.Settings().TestCancellation.Get(); - _cancellationToken ??= testCancellation?.CancellationTokenFactory?.Invoke() ?? CancellationToken.None; - return IsMet(GetRootNode(), context, timeSystem, _timeout ?? testCancellation?.Timeout, - _cancellationToken.Value); + CancellationToken ??= testCancellation?.CancellationTokenFactory?.Invoke() ?? + System.Threading.CancellationToken.None; + return IsMet(GetRootNode(), context, timeSystem, Timeout ?? testCancellation?.Timeout, + CancellationToken.Value); } internal abstract Task IsMet(Node rootNode, diff --git a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net10.0.txt b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net10.0.txt index 9b8d76871..d3d93a5c8 100644 --- a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net10.0.txt +++ b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net10.0.txt @@ -146,7 +146,9 @@ namespace aweXpect.Core public abstract class ExpectationBuilder { protected ExpectationBuilder(string subjectExpression, aweXpect.Core.ExpectationGrammars grammars = 0) { } + public System.Threading.CancellationToken? CancellationToken { get; } public aweXpect.Core.ExpectationGrammars ExpectationGrammars { get; } + public System.TimeSpan? Timeout { get; } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } @@ -1179,6 +1181,7 @@ namespace aweXpect.Results public class ExpectationResult : aweXpect.Results.Expectation, aweXpect.Core.IOptionsProvider { public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { } + public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task reason) { } public aweXpect.Results.ExpectationResult Because(string reason) { } public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { } public override string? ToString() { } @@ -1194,6 +1197,7 @@ namespace aweXpect.Results where TSelf : aweXpect.Results.ExpectationResult { public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { } + public TSelf Because(System.Threading.Tasks.Task reason) { } public TSelf Because(string reason) { } [System.Diagnostics.StackTraceHidden] public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { } diff --git a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt index 58b2a6a04..ac080cf80 100644 --- a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt +++ b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_net8.0.txt @@ -146,7 +146,9 @@ namespace aweXpect.Core public abstract class ExpectationBuilder { protected ExpectationBuilder(string subjectExpression, aweXpect.Core.ExpectationGrammars grammars = 0) { } + public System.Threading.CancellationToken? CancellationToken { get; } public aweXpect.Core.ExpectationGrammars ExpectationGrammars { get; } + public System.TimeSpan? Timeout { get; } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } @@ -1179,6 +1181,7 @@ namespace aweXpect.Results public class ExpectationResult : aweXpect.Results.Expectation, aweXpect.Core.IOptionsProvider { public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { } + public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task reason) { } public aweXpect.Results.ExpectationResult Because(string reason) { } public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { } public override string? ToString() { } @@ -1194,6 +1197,7 @@ namespace aweXpect.Results where TSelf : aweXpect.Results.ExpectationResult { public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { } + public TSelf Because(System.Threading.Tasks.Task reason) { } public TSelf Because(string reason) { } [System.Diagnostics.StackTraceHidden] public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { } diff --git a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt index 79d2dd06c..b0d684596 100644 --- a/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt +++ b/Tests/aweXpect.Core.Api.Tests/Expected/aweXpect.Core_netstandard2.0.txt @@ -146,7 +146,9 @@ namespace aweXpect.Core public abstract class ExpectationBuilder { protected ExpectationBuilder(string subjectExpression, aweXpect.Core.ExpectationGrammars grammars = 0) { } + public System.Threading.CancellationToken? CancellationToken { get; } public aweXpect.Core.ExpectationGrammars ExpectationGrammars { get; } + public System.TimeSpan? Timeout { get; } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } @@ -1142,6 +1144,7 @@ namespace aweXpect.Results public class ExpectationResult : aweXpect.Results.Expectation, aweXpect.Core.IOptionsProvider { public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { } + public aweXpect.Results.ExpectationResult Because(System.Threading.Tasks.Task reason) { } public aweXpect.Results.ExpectationResult Because(string reason) { } public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { } public override string? ToString() { } @@ -1156,6 +1159,7 @@ namespace aweXpect.Results where TSelf : aweXpect.Results.ExpectationResult { public ExpectationResult(aweXpect.Core.ExpectationBuilder expectationBuilder) { } + public TSelf Because(System.Threading.Tasks.Task reason) { } public TSelf Because(string reason) { } public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { } public override string? ToString() { } From b7084d2888b6c92f091ba52805bfb1d36f92b2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Breu=C3=9F=20Valentin?= Date: Fri, 6 Mar 2026 14:04:13 +0100 Subject: [PATCH 2/2] Fix review issues --- Source/aweXpect.Core/Core/ExpectationBuilder.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Source/aweXpect.Core/Core/ExpectationBuilder.cs b/Source/aweXpect.Core/Core/ExpectationBuilder.cs index 21c5d3f8b..06ebfe457 100644 --- a/Source/aweXpect.Core/Core/ExpectationBuilder.cs +++ b/Source/aweXpect.Core/Core/ExpectationBuilder.cs @@ -59,10 +59,14 @@ private protected ExpectationBuilder() /// /// The explicit cancellation token to be used for the expectation. /// + /// + /// When not set, the expectation will still use the cancellation token from + /// + /// public CancellationToken? CancellationToken { get; private set; } /// - /// The timeout to be applied to the expectation. + /// The explicit timeout to be applied to the expectation. /// public TimeSpan? Timeout { get; private set; } @@ -470,10 +474,11 @@ internal Task IsMet() EvaluationContext.EvaluationContext context = new(); ITimeSystem timeSystem = _timeSystem ?? RealTimeSystem.Instance; TestCancellation? testCancellation = Customize.aweXpect.Settings().TestCancellation.Get(); - CancellationToken ??= testCancellation?.CancellationTokenFactory?.Invoke() ?? - System.Threading.CancellationToken.None; + CancellationToken cancellationToken = CancellationToken ?? + testCancellation?.CancellationTokenFactory?.Invoke() ?? + System.Threading.CancellationToken.None; return IsMet(GetRootNode(), context, timeSystem, Timeout ?? testCancellation?.Timeout, - CancellationToken.Value); + cancellationToken); } internal abstract Task IsMet(Node rootNode,