diff --git a/Benchmarks/aweXpect.Benchmarks/HappyCaseBenchmarks.String.cs b/Benchmarks/aweXpect.Benchmarks/HappyCaseBenchmarks.String.cs index b3d2bb578..31747121c 100644 --- a/Benchmarks/aweXpect.Benchmarks/HappyCaseBenchmarks.String.cs +++ b/Benchmarks/aweXpect.Benchmarks/HappyCaseBenchmarks.String.cs @@ -10,17 +10,17 @@ namespace aweXpect.Benchmarks; public partial class HappyCaseBenchmarks { private readonly string _stringExpectation = "foo"; - private readonly string _stringSubject = "foo"; + private readonly string _stringSubject = "FOO"; [Benchmark] public async Task String_aweXpect() - => await Expect.That(_stringSubject).IsEqualTo(_stringExpectation); + => await Expect.That(_stringSubject).IsEqualTo(_stringExpectation).IgnoringCase(); [Benchmark] public AndConstraint String_FluentAssertions() - => _stringSubject.Should().Be(_stringExpectation); + => _stringSubject.Should().BeEquivalentTo(_stringExpectation, o => o.IgnoringCase()); [Benchmark] public async Task String_TUnit() - => await Assert.That(_stringSubject).IsEqualTo(_stringExpectation); + => await Assert.That(_stringSubject).IsEqualTo(_stringExpectation).IgnoringCase(); } diff --git a/Pipeline/Build.cs b/Pipeline/Build.cs index dc06fb472..30c5044b5 100644 --- a/Pipeline/Build.cs +++ b/Pipeline/Build.cs @@ -20,7 +20,7 @@ partial class Build : NukeBuild /// /// Afterward, you can update the package reference in `Directory.Packages.props` and reset this flag. /// - readonly BuildScope BuildScope = BuildScope.Default; + readonly BuildScope BuildScope = BuildScope.CoreOnly; [Parameter("Github Token")] readonly string GithubToken; [GitRepository] readonly GitRepository Repository; diff --git a/Source/aweXpect.Core/Core/Constraints/ConstraintResult.FromException.cs b/Source/aweXpect.Core/Core/Constraints/ConstraintResult.FromException.cs index 055b1a55b..4f3b2f1da 100644 --- a/Source/aweXpect.Core/Core/Constraints/ConstraintResult.FromException.cs +++ b/Source/aweXpect.Core/Core/Constraints/ConstraintResult.FromException.cs @@ -30,7 +30,7 @@ public FromException( _inner = inner; _exception = exception; FurtherProcessingStrategy = inner.FurtherProcessingStrategy; - expectationBuilder.UpdateContexts(c => c.Add(new ResultContext("Exception", exception.ToString()))); + expectationBuilder.AddContext(new ResultContext.Fixed("Exception", exception.ToString())); } public override Outcome Outcome diff --git a/Source/aweXpect.Core/Core/ExpectationBuilder.cs b/Source/aweXpect.Core/Core/ExpectationBuilder.cs index 701876289..9da4460d6 100644 --- a/Source/aweXpect.Core/Core/ExpectationBuilder.cs +++ b/Source/aweXpect.Core/Core/ExpectationBuilder.cs @@ -378,6 +378,16 @@ public virtual ExpectationBuilder UpdateContexts(Action callback return this; } + /// + /// Adds the to the context that is included in the failure message. + /// + public virtual ExpectationBuilder AddContext(ResultContext resultContext) + { + _contexts ??= new ResultContexts(); + _contexts.Add(resultContext); + return this; + } + /// /// Gets the list of . /// diff --git a/Source/aweXpect.Core/Core/IStringMatchType.cs b/Source/aweXpect.Core/Core/IStringMatchType.cs index d17d0ba06..5875a317a 100644 --- a/Source/aweXpect.Core/Core/IStringMatchType.cs +++ b/Source/aweXpect.Core/Core/IStringMatchType.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace aweXpect.Core; @@ -19,7 +20,7 @@ public interface IStringMatchType #endif AreConsideredEqual(string? actual, string? expected, bool ignoreCase, - IEqualityComparer comparer); + IEqualityComparer? comparer); /// /// Get the expectations text. diff --git a/Source/aweXpect.Core/Core/ManualExpectationBuilder.cs b/Source/aweXpect.Core/Core/ManualExpectationBuilder.cs index 91e46a866..55859da7d 100644 --- a/Source/aweXpect.Core/Core/ManualExpectationBuilder.cs +++ b/Source/aweXpect.Core/Core/ManualExpectationBuilder.cs @@ -83,6 +83,14 @@ public override ExpectationBuilder UpdateContexts(Action callbac return this; } + /// + public override ExpectationBuilder AddContext(ResultContext resultContext) + { + inner?.AddContext(resultContext); + base.AddContext(resultContext); + return this; + } + /// public override string ToString() { diff --git a/Source/aweXpect.Core/Core/Polyfills/StringExtensions.cs b/Source/aweXpect.Core/Core/Polyfills/StringExtensions.cs index e552a3975..ba0a1c262 100644 --- a/Source/aweXpect.Core/Core/Polyfills/StringExtensions.cs +++ b/Source/aweXpect.Core/Core/Polyfills/StringExtensions.cs @@ -23,7 +23,7 @@ internal static bool Contains( this string @this, char value, StringComparison comparisonType) - => @this.Contains(value); + => @this.IndexOf(value, comparisonType) >= 0; /// /// Returns a value indicating whether a specified character occurs within this string, using the specified comparison @@ -37,7 +37,7 @@ internal static bool Contains( this string @this, string value, StringComparison comparisonType) - => @this.Contains(value); + => @this.IndexOf(value, comparisonType) >= 0; /// /// Determines whether the end of this string instance matches the specified character. diff --git a/Source/aweXpect.Core/Core/ResultContext.cs b/Source/aweXpect.Core/Core/ResultContext.cs index 9fd100ca0..47e2148b2 100644 --- a/Source/aweXpect.Core/Core/ResultContext.cs +++ b/Source/aweXpect.Core/Core/ResultContext.cs @@ -7,42 +7,17 @@ namespace aweXpect.Core; /// /// A result context that is appended to a result error. /// -public class ResultContext +public abstract class ResultContext { - private readonly Func>? _contentFunc; - - private readonly string? _fixedContent; - - /// - /// A result context that is appended to a result error. - /// - /// The optional determines the displayed order (higher values are displayed first). - public ResultContext(string title, string? content, int priority = 0) - { - Title = title; - _fixedContent = content; - Priority = priority; - } - - /// - /// A result context that is appended to a result error. - /// - /// The optional determines the displayed order (higher values are displayed first). - public ResultContext(string title, Func> asyncContent, int priority = 0) - { - Title = title; - _contentFunc = asyncContent; - Priority = priority; - } + internal ResultContext? _next; /// /// A result context that is appended to a result error. /// /// The optional determines the displayed order (higher values are displayed first). - public ResultContext(string title, Func syncContent, int priority = 0) + protected ResultContext(string title, int priority = 0) { Title = title; - _contentFunc = _ => Task.FromResult(syncContent()); Priority = priority; } @@ -60,18 +35,69 @@ public ResultContext(string title, Func syncContent, int priority = 0) /// /// The content of the context. /// - public async Task GetContent(CancellationToken cancellationToken = default) + public abstract Task GetContent(CancellationToken cancellationToken = default); + + /// + /// A from a fixed content. + /// + public class Fixed : ResultContext { - if (_fixedContent is not null) + private readonly string? _content; + + /// + /// A from a fixed . + /// + /// The optional determines the displayed order (higher values are displayed first). + public Fixed(string title, string? content, int priority = 0) : base(title, priority) { - return _fixedContent; + _content = content; } - if (_contentFunc is not null) + /// + public override Task GetContent(CancellationToken cancellationToken = default) + => Task.FromResult(_content); + } + + /// + /// A from an async callback. + /// + public class AsyncCallback : ResultContext + { + private readonly Func> _callback; + + /// + /// A from an async . + /// + /// The optional determines the displayed order (higher values are displayed first). + public AsyncCallback(string title, Func> callback, int priority = 0) : base( + title, priority) + { + _callback = callback; + } + + /// + public override Task GetContent(CancellationToken cancellationToken = default) + => _callback(cancellationToken); + } + + /// + /// A from a sync callback. + /// + public class SyncCallback : ResultContext + { + private readonly Func _callback; + + /// + /// A from a sync . + /// + /// The optional determines the displayed order (higher values are displayed first). + public SyncCallback(string title, Func callback, int priority = 0) : base(title, priority) { - return await _contentFunc(cancellationToken); + _callback = callback; } - return null; + /// + public override Task GetContent(CancellationToken cancellationToken = default) + => Task.FromResult(_callback()); } } diff --git a/Source/aweXpect.Core/Core/ResultContexts.cs b/Source/aweXpect.Core/Core/ResultContexts.cs index 0830b1a3e..9d05615fe 100644 --- a/Source/aweXpect.Core/Core/ResultContexts.cs +++ b/Source/aweXpect.Core/Core/ResultContexts.cs @@ -9,11 +9,19 @@ namespace aweXpect.Core; /// public class ResultContexts : IEnumerable { - private readonly List _results = new(); + private ResultContext? _first; private bool _isOpen = true; /// - public IEnumerator GetEnumerator() => _results.GetEnumerator(); + public IEnumerator GetEnumerator() + { + ResultContext? current = _first; + while (current != null) + { + yield return current; + current = current._next; + } + } /// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); @@ -43,7 +51,15 @@ public ResultContexts Add(ResultContext context) { if (_isOpen) { - _results.Add(context); + if (_first is null) + { + _first = context; + } + else + { + context._next = _first._next; + _first._next = context; + } } return this; @@ -56,7 +72,7 @@ public ResultContexts Clear() { if (_isOpen) { - _results.Clear(); + _first = null; } return this; @@ -66,14 +82,7 @@ public ResultContexts Clear() /// Removes all contexts with the given . /// public ResultContexts Remove(string title, StringComparison stringComparison = StringComparison.OrdinalIgnoreCase) - { - if (_isOpen) - { - _results.RemoveAll(x => x.Title.Equals(title, stringComparison)); - } - - return this; - } + => Remove(c => string.Equals(c.Title, title, stringComparison)); /// /// Removes all contexts that match the . @@ -82,7 +91,28 @@ public ResultContexts Remove(Predicate predicate) { if (_isOpen) { - _results.RemoveAll(predicate); + ResultContext? previous = null; + ResultContext? current = _first; + while (current != null) + { + if (predicate(current)) + { + if (previous == null) + { + _first = current._next; + } + else + { + previous._next = current._next; + } + } + else + { + previous = current; + } + + current = current._next; + } } return this; diff --git a/Source/aweXpect.Core/Core/ThatBool.cs b/Source/aweXpect.Core/Core/ThatBool.cs index 59a34f274..499c8435b 100644 --- a/Source/aweXpect.Core/Core/ThatBool.cs +++ b/Source/aweXpect.Core/Core/ThatBool.cs @@ -36,6 +36,9 @@ private sealed class WithDefaultExpectationBuilderProxy(ExpectationBuilder inner public override ExpectationBuilder UpdateContexts(Action callback) => inner.UpdateContexts(callback); + public override ExpectationBuilder AddContext(ResultContext resultContext) + => inner.AddContext(resultContext); + internal override Task IsMet(Node rootNode, EvaluationContext.EvaluationContext context, ITimeSystem timeSystem, TimeSpan? timeout, CancellationToken cancellationToken) diff --git a/Source/aweXpect.Core/Equivalency/EquivalencyExpectationBuilder.cs b/Source/aweXpect.Core/Equivalency/EquivalencyExpectationBuilder.cs index 085cbacca..01bbb7107 100644 --- a/Source/aweXpect.Core/Equivalency/EquivalencyExpectationBuilder.cs +++ b/Source/aweXpect.Core/Equivalency/EquivalencyExpectationBuilder.cs @@ -134,4 +134,7 @@ internal override Task IsMet(Node rootNode, /// public override ExpectationBuilder UpdateContexts(Action callback) => this; + + /// + public override ExpectationBuilder AddContext(ResultContext resultContext) => this; } diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.ContainingMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.ContainingMatchType.cs index ea5300e70..bda1faffb 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.ContainingMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.ContainingMatchType.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using aweXpect.Core; using aweXpect.Core.Helpers; @@ -70,7 +71,7 @@ public ValueTask public Task #endif AreConsideredEqual(string? actual, string? expected, bool ignoreCase, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (actual is null && expected is null) { @@ -90,10 +91,19 @@ public Task #endif } + if (comparer is not null) + { +#if NET8_0_OR_GREATER + return ValueTask.FromResult(Contains(actual, expected, comparer)); +#else + return Task.FromResult(Contains(actual, expected, comparer)); +#endif + } + #if NET8_0_OR_GREATER - return ValueTask.FromResult(Contains(actual, expected, comparer)); + return ValueTask.FromResult(actual.Contains(expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); #else - return Task.FromResult(Contains(actual, expected, comparer)); + return Task.FromResult(actual.Contains(expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); #endif } diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs index 1af81a3c0..33e9787d3 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.ExactMatchType.cs @@ -110,7 +110,7 @@ public ValueTask public Task #endif AreConsideredEqual(string? actual, string? expected, bool ignoreCase, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (actual is null && expected is null) { @@ -130,10 +130,19 @@ public Task #endif } + if (comparer is not null) + { +#if NET8_0_OR_GREATER + return ValueTask.FromResult(comparer.Equals(actual, expected)); +#else + return Task.FromResult(comparer.Equals(actual, expected)); +#endif + } + #if NET8_0_OR_GREATER - return ValueTask.FromResult(comparer.Equals(actual, expected)); + return ValueTask.FromResult(string.Equals(actual, expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); #else - return Task.FromResult(comparer.Equals(actual, expected)); + return Task.FromResult(string.Equals(actual, expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); #endif } diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs index 4dfffa3a8..cb887f160 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.PrefixMatchType.cs @@ -94,7 +94,7 @@ public ValueTask public Task #endif AreConsideredEqual(string? actual, string? expected, bool ignoreCase, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (actual is null && expected is null) { @@ -114,11 +114,20 @@ public Task #endif } + if (comparer is not null) + { +#if NET8_0_OR_GREATER + return ValueTask.FromResult(actual.Length >= expected.Length && comparer.Equals(actual[..expected.Length], expected)); +#else + return Task.FromResult(actual.Length >= expected.Length && + comparer.Equals(actual[..expected.Length], expected)); +#endif + } + #if NET8_0_OR_GREATER - return ValueTask.FromResult(actual.Length >= expected.Length && comparer.Equals(actual[..expected.Length], expected)); + return ValueTask.FromResult(actual.StartsWith(expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); #else - return Task.FromResult(actual.Length >= expected.Length && - comparer.Equals(actual[..expected.Length], expected)); + return Task.FromResult(actual.StartsWith(expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); #endif } diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.RegexMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.RegexMatchType.cs index 9aefa41f6..d144e17f5 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.RegexMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.RegexMatchType.cs @@ -47,7 +47,7 @@ public ValueTask public Task #endif AreConsideredEqual(string? actual, string? expected, bool ignoreCase, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (actual is null || expected is null) { diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs index ded5b36ea..18ff4be54 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.SuffixMatchType.cs @@ -102,7 +102,7 @@ public ValueTask public Task #endif AreConsideredEqual(string? actual, string? expected, bool ignoreCase, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (actual is null && expected is null) { @@ -122,11 +122,20 @@ public Task #endif } + if (comparer is not null) + { #if NET8_0_OR_GREATER return ValueTask.FromResult(actual.Length >= expected.Length && comparer.Equals(actual[^expected.Length..], expected)); #else - return Task.FromResult(actual.Length >= expected.Length && - comparer.Equals(actual[^expected.Length..], expected)); + return Task.FromResult(actual.Length >= expected.Length && + comparer.Equals(actual[^expected.Length..], expected)); +#endif + } + +#if NET8_0_OR_GREATER + return ValueTask.FromResult(actual.EndsWith(expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); +#else + return Task.FromResult(actual.EndsWith(expected, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); #endif } diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.WildcardMatchType.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.WildcardMatchType.cs index 3240338ea..ca4d63fd6 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.WildcardMatchType.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.WildcardMatchType.cs @@ -56,7 +56,7 @@ public ValueTask public Task #endif AreConsideredEqual(string? actual, string? expected, bool ignoreCase, - IEqualityComparer comparer) + IEqualityComparer? comparer) { if (actual is null || expected is null) { diff --git a/Source/aweXpect.Core/Options/StringEqualityOptions.cs b/Source/aweXpect.Core/Options/StringEqualityOptions.cs index dcfdd3afe..b9edb1f2c 100644 --- a/Source/aweXpect.Core/Options/StringEqualityOptions.cs +++ b/Source/aweXpect.Core/Options/StringEqualityOptions.cs @@ -33,7 +33,7 @@ public async Task AreConsideredEqual(string? actual, TExpected if (expected is not string expectedString) { result = await _matchType.AreConsideredEqual(actual, null, _ignoreCase, - _comparer ?? UseDefaultComparer(_ignoreCase)); + _comparer); return result; } @@ -55,8 +55,7 @@ public async Task AreConsideredEqual(string? actual, TExpected expectedString = expectedString.TrimEnd(); } - result = await _matchType.AreConsideredEqual(actual, expectedString, _ignoreCase, - _comparer ?? UseDefaultComparer(_ignoreCase)); + result = await _matchType.AreConsideredEqual(actual, expectedString, _ignoreCase, _comparer); return result; } diff --git a/Source/aweXpect/Equivalency/EquivalencyExtensions.cs b/Source/aweXpect/Equivalency/EquivalencyExtensions.cs index 1373fb53a..cddfbd469 100644 --- a/Source/aweXpect/Equivalency/EquivalencyExtensions.cs +++ b/Source/aweXpect/Equivalency/EquivalencyExtensions.cs @@ -49,8 +49,8 @@ internal static ObjectEqualityOptions Equivalent(this Object internal static void AddEquivalencyContext(this ExpectationBuilder expectationBuilder, EquivalencyOptions equivalencyOptions) - => expectationBuilder.UpdateContexts(contexts => contexts.Add( - new ResultContext("Equivalency options", - _ => Task.FromResult(equivalencyOptions.ToString()), - int.MinValue))); + => expectationBuilder.AddContext( + new ResultContext.SyncCallback("Equivalency options", + equivalencyOptions.ToString, + int.MinValue)); } diff --git a/Source/aweXpect/That/Collections/CollectionHelpers.cs b/Source/aweXpect/That/Collections/CollectionHelpers.cs index abea6c6d2..93a60be80 100644 --- a/Source/aweXpect/That/Collections/CollectionHelpers.cs +++ b/Source/aweXpect/That/Collections/CollectionHelpers.cs @@ -54,7 +54,7 @@ internal static ExpectationBuilder AddCollectionContext(this ExpectationB if (contexts.All(c => c.Title != "Collection")) { contexts - .Add(new ResultContext("Collection", + .Add(new ResultContext.SyncCallback("Collection", () => Formatter.Format(value, typeof(TItem).GetFormattingOption(value switch { ICollection coll => coll.Count, @@ -90,7 +90,7 @@ internal static ExpectationBuilder AddCollectionContext(this ExpectationBuilder if (contexts.All(c => c.Title != "Collection")) { contexts - .Add(new ResultContext("Collection", + .Add(new ResultContext.SyncCallback("Collection", () => Formatter.Format(value, type.GetFormattingOption(value switch { ICollection coll => coll.Count, @@ -120,7 +120,7 @@ internal static async Task AddCollectionContext( if (contexts.All(c => c.Title != "Collection")) { contexts - .Add(new ResultContext("Collection", + .Add(new ResultContext.SyncCallback("Collection", () => Formatter.Format(value.MaterializedItems, typeof(TItem).GetFormattingOption(value.Count)) .AppendIsIncomplete(isIncomplete), @@ -144,7 +144,7 @@ internal static ExpectationBuilder AddCollectionContext(this Expec if (contexts.All(c => c.Title != "Dictionary")) { contexts - .Add(new ResultContext("Dictionary", + .Add(new ResultContext.SyncCallback("Dictionary", () => Formatter.Format(value, typeof(TValue).GetFormattingOption(value.Count)) .AppendIsIncomplete(isIncomplete), -2)); @@ -166,7 +166,7 @@ internal static ExpectationBuilder AddCollectionContext(this Expec if (contexts.All(c => c.Title != "Dictionary")) { contexts - .Add(new ResultContext("Dictionary", + .Add(new ResultContext.SyncCallback("Dictionary", () => Formatter.Format(value, typeof(TValue).GetFormattingOption(value.Count)) .AppendIsIncomplete(isIncomplete), -2)); diff --git a/Source/aweXpect/That/Collections/ThatAsyncEnumerable.cs b/Source/aweXpect/That/Collections/ThatAsyncEnumerable.cs index 5a3b3ecf6..4fe1e9618 100644 --- a/Source/aweXpect/That/Collections/ThatAsyncEnumerable.cs +++ b/Source/aweXpect/That/Collections/ThatAsyncEnumerable.cs @@ -160,22 +160,20 @@ private void AppendContexts(bool isIncomplete) EnumerableQuantifier.QuantifierContexts quantifierContexts = _quantifier.GetQuantifierContext(); if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.MatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Matching items", - Formatter.Format(_matchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Matching items", + () => Formatter.Format(_matchingItems, typeof(TItem).GetFormattingOption(_matchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.NotMatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Not matching items", - Formatter.Format(_notMatchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Not matching items", + () => Formatter.Format(_notMatchingItems, typeof(TItem).GetFormattingOption(_notMatchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } } } @@ -351,22 +349,20 @@ private void AppendContexts(bool isIncomplete) EnumerableQuantifier.QuantifierContexts quantifierContexts = _quantifier.GetQuantifierContext(); if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.MatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Matching items", - Formatter.Format(_matchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Matching items", + () => Formatter.Format(_matchingItems, typeof(TItem).GetFormattingOption(_matchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.NotMatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Not matching items", - Formatter.Format(_notMatchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Not matching items", + () => Formatter.Format(_notMatchingItems, typeof(TItem).GetFormattingOption(_notMatchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } } } @@ -512,15 +508,14 @@ public async Task IsMetBy(IAsyncEnumerable? actual, IEv _items = []; } - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Expected", + expectationBuilder.AddContext(new ResultContext.SyncCallback("Expected", () => Formatter.Format(expected, typeof(TItem).GetFormattingOption(expected switch { ICollection coll => coll.Count, ICountable countable => countable.Count, _ => null, })), - -2))); + -2)); await foreach (TItem item in materializedEnumerable.WithCancellation(cancellationToken)) { if (_items?.Count < maximumNumber + 1) @@ -639,10 +634,9 @@ public async Task IsMetBy(IAsyncEnumerable? actual, IEv _items = []; } - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Expected", + expectationBuilder.AddContext(new ResultContext.SyncCallback("Expected", () => Formatter.Format(_expectations, typeof(TItem).GetFormattingOption(_expectations.Length)), - -2))); + -2)); NoOptions noOptions = new(); await foreach (TItem item in materializedEnumerable.WithCancellation(cancellationToken)) { @@ -762,15 +756,14 @@ public async Task IsMetBy(IAsyncEnumerable? actual, IEv _items = []; } - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Expected", + expectationBuilder.AddContext(new ResultContext.SyncCallback("Expected", () => Formatter.Format(expected, typeof(TItem).GetFormattingOption(expected switch { ICollection coll => coll.Count, ICountable countable => countable.Count, _ => null, })), - -2))); + -2)); NoOptions noOptions = new(); await foreach (TItem item in materializedEnumerable.WithCancellation(cancellationToken)) { diff --git a/Source/aweXpect/That/Collections/ThatEnumerable.cs b/Source/aweXpect/That/Collections/ThatEnumerable.cs index e34ee8326..6e0acd094 100644 --- a/Source/aweXpect/That/Collections/ThatEnumerable.cs +++ b/Source/aweXpect/That/Collections/ThatEnumerable.cs @@ -50,15 +50,14 @@ public async Task IsMetBy(IEnumerable? actual, IEvaluat return this; } - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Expected", + expectationBuilder.AddContext(new ResultContext.SyncCallback("Expected", () => Formatter.Format(expected, typeof(TItem).GetFormattingOption(expected switch { ICollection coll => coll.Count, ICountable countable => countable.Count, _ => null, })), - -2))); + -2)); IEnumerable materializedEnumerable = context.UseMaterializedEnumerable>(actual); ICollectionMatcher matcher = matchOptions.GetCollectionMatcher(expected); @@ -161,10 +160,9 @@ public async Task IsMetBy(IEnumerable? actual, IEvaluat context, CancellationToken.None)) .ToArray(); - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Expected", + expectationBuilder.AddContext(new ResultContext.SyncCallback("Expected", () => Formatter.Format(_expectations, typeof(TItem).GetFormattingOption(_expectations.Length)), - -2))); + -2)); ICollectionMatcher matcher = matchOptions.GetCollectionMatcher(_expectations); int maximumNumber = Customize.aweXpect.Formatting().MaximumNumberOfCollectionItems.Get(); @@ -264,15 +262,14 @@ public async Task IsMetBy(IEnumerable? actual, IEvaluat return this; } - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Expected", + expectationBuilder.AddContext(new ResultContext.SyncCallback("Expected", () => Formatter.Format(expected, typeof(TItem).GetFormattingOption(expected switch { ICollection coll => coll.Count, ICountable countable => countable.Count, _ => null, })), - -2))); + -2)); IEnumerable materializedEnumerable = context.UseMaterializedEnumerable>(actual); ICollectionMatcher matcher = matchOptions.GetCollectionMatcher(expected); @@ -376,15 +373,14 @@ public async Task IsMetBy(TEnumerable? actual, IEvaluationCont return this; } - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Expected", + expectationBuilder.AddContext(new ResultContext.SyncCallback("Expected", () => Formatter.Format(expected, typeof(TItem).GetFormattingOption(expected switch { ICollection coll => coll.Count, ICountable countable => countable.Count, _ => null, })), - -2))); + -2)); IEnumerable materializedEnumerable = context.UseMaterializedEnumerable(actual); ICollectionMatcher matcher = matchOptions.GetCollectionMatcher(expected); int maximumNumber = Customize.aweXpect.Formatting().MaximumNumberOfCollectionItems.Get(); @@ -589,20 +585,18 @@ private void AppendContexts(bool isIncomplete) EnumerableQuantifier.QuantifierContexts quantifierContexts = _quantifier.GetQuantifierContext(); if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.MatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Matching items", - Formatter.Format(_matchingItems, typeof(TItem).GetFormattingOption(_matchingItems?.Count)) + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Matching items", + () => Formatter.Format(_matchingItems, typeof(TItem).GetFormattingOption(_matchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.NotMatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Not matching items", - Formatter.Format(_notMatchingItems, typeof(TItem).GetFormattingOption(_notMatchingItems?.Count)) + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Not matching items", + () => Formatter.Format(_notMatchingItems, typeof(TItem).GetFormattingOption(_notMatchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } } } @@ -752,20 +746,18 @@ private void AppendContexts(bool isIncomplete) EnumerableQuantifier.QuantifierContexts quantifierContexts = _quantifier.GetQuantifierContext(); if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.MatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Matching items", - Formatter.Format(_matchingItems, typeof(TItem).GetFormattingOption(_matchingItems?.Count)) + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Matching items", + () => Formatter.Format(_matchingItems, typeof(TItem).GetFormattingOption(_matchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.NotMatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Not matching items", - Formatter.Format(_notMatchingItems, typeof(TItem).GetFormattingOption(_notMatchingItems?.Count)) + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Not matching items", + () => Formatter.Format(_notMatchingItems, typeof(TItem).GetFormattingOption(_notMatchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } } } @@ -913,22 +905,20 @@ private void AppendContexts(bool isIncomplete) EnumerableQuantifier.QuantifierContexts quantifierContexts = _quantifier.GetQuantifierContext(); if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.MatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Matching items", - Formatter.Format(_matchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Matching items", + () => Formatter.Format(_matchingItems, (_itemType ?? typeof(object)).GetFormattingOption(_matchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.NotMatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Not matching items", - Formatter.Format(_notMatchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Not matching items", + () => Formatter.Format(_notMatchingItems, (_itemType ?? typeof(object)).GetFormattingOption(_notMatchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } } } @@ -1084,22 +1074,20 @@ private void AppendContexts(bool isIncomplete) EnumerableQuantifier.QuantifierContexts quantifierContexts = _quantifier.GetQuantifierContext(); if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.MatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Matching items", - Formatter.Format(_matchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Matching items", + () => Formatter.Format(_matchingItems, (_itemType ?? typeof(object)).GetFormattingOption(_matchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } if (quantifierContexts.HasFlag(EnumerableQuantifier.QuantifierContexts.NotMatchingItems)) { - _expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Not matching items", - Formatter.Format(_notMatchingItems, + _expectationBuilder.AddContext(new ResultContext.SyncCallback("Not matching items", + () => Formatter.Format(_notMatchingItems, (_itemType ?? typeof(object)).GetFormattingOption(_notMatchingItems?.Count)) .AppendIsIncomplete(isIncomplete), - int.MaxValue))); + int.MaxValue)); } } } diff --git a/Source/aweXpect/That/Exceptions/ThatException.HasMessage.cs b/Source/aweXpect/That/Exceptions/ThatException.HasMessage.cs index dd435e0af..8bd68eeef 100644 --- a/Source/aweXpect/That/Exceptions/ThatException.HasMessage.cs +++ b/Source/aweXpect/That/Exceptions/ThatException.HasMessage.cs @@ -58,8 +58,7 @@ public async Task IsMetBy(Exception? actual, CancellationToken Outcome = await options.AreConsideredEqual(actual?.Message, expected) ? Outcome.Success : Outcome.Failure; if (!string.IsNullOrEmpty(actual?.Message)) { - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Message", actual.Message))); + expectationBuilder.AddContext(new ResultContext.Fixed("Message", actual.Message)); } return this; diff --git a/Source/aweXpect/That/Exceptions/ThatException.HasMessageContaining.cs b/Source/aweXpect/That/Exceptions/ThatException.HasMessageContaining.cs index c4cc091e2..89fcf7e13 100644 --- a/Source/aweXpect/That/Exceptions/ThatException.HasMessageContaining.cs +++ b/Source/aweXpect/That/Exceptions/ThatException.HasMessageContaining.cs @@ -61,8 +61,7 @@ public async Task IsMetBy(Exception? actual, CancellationToken : Outcome.Failure; if (!string.IsNullOrEmpty(actual?.Message)) { - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Message", actual.Message))); + expectationBuilder.AddContext(new ResultContext.Fixed("Message", actual.Message)); } return this; diff --git a/Source/aweXpect/That/Strings/ThatString.IsEqualTo.cs b/Source/aweXpect/That/Strings/ThatString.IsEqualTo.cs index 094b934b9..0c6f70e89 100644 --- a/Source/aweXpect/That/Strings/ThatString.IsEqualTo.cs +++ b/Source/aweXpect/That/Strings/ThatString.IsEqualTo.cs @@ -55,8 +55,7 @@ public async Task IsMetBy(string? actual, CancellationToken ca Outcome = await options.AreConsideredEqual(actual, expected) ? Outcome.Success : Outcome.Failure; if (!string.IsNullOrEmpty(actual)) { - expectationBuilder.UpdateContexts(contexts => contexts - .Add(new ResultContext("Actual", actual))); + expectationBuilder.AddContext(new ResultContext.Fixed("Actual", actual)); } return this; } diff --git a/Tests/Frameworks/aweXpect.Frameworks.MsTest4.Tests/MsTest4FrameworkTests.cs b/Tests/Frameworks/aweXpect.Frameworks.MsTest4.Tests/MsTest4FrameworkTests.cs index d93ecf96b..2974ad55a 100644 --- a/Tests/Frameworks/aweXpect.Frameworks.MsTest4.Tests/MsTest4FrameworkTests.cs +++ b/Tests/Frameworks/aweXpect.Frameworks.MsTest4.Tests/MsTest4FrameworkTests.cs @@ -1,6 +1,8 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; +[assembly: Parallelize] + namespace aweXpect.Frameworks.MsTest4.Tests; [TestClass] 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 a18e8c9e5..6fd7fddb0 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 @@ -155,6 +155,7 @@ namespace aweXpect.Core public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } + public virtual aweXpect.Core.ExpectationBuilder AddContext(aweXpect.Core.ResultContext resultContext) { } public aweXpect.Core.ExpectationBuilder And(string textSeparator = " and ") { } public aweXpect.Core.ExpectationBuilder.MemberExpectationBuilder ForAsyncMember(aweXpect.Core.MemberAccessor> memberAccessor, System.Action? expectationTextGenerator = null, bool replaceIt = true) { } public aweXpect.Core.ExpectationBuilder.MemberExpectationBuilder ForMember(aweXpect.Core.MemberAccessor memberAccessor, System.Action? expectationTextGenerator = null, bool replaceIt = true) { } @@ -220,7 +221,7 @@ namespace aweXpect.Core } public interface IStringMatchType { - System.Threading.Tasks.ValueTask AreConsideredEqual(string? actual, string? expected, bool ignoreCase, System.Collections.Generic.IEqualityComparer comparer); + System.Threading.Tasks.ValueTask AreConsideredEqual(string? actual, string? expected, bool ignoreCase, System.Collections.Generic.IEqualityComparer? comparer); string GetExpectation(string? expected, aweXpect.Core.ExpectationGrammars grammars); string GetExtendedFailure(string it, string? actual, string? expected, bool ignoreCase, System.Collections.Generic.IEqualityComparer comparer, aweXpect.Core.StringDifferenceSettings? settings); string GetOptionString(bool ignoreCase, System.Collections.Generic.IEqualityComparer? comparer); @@ -237,6 +238,7 @@ namespace aweXpect.Core public class ManualExpectationBuilder : aweXpect.Core.ExpectationBuilder, System.Collections.Generic.IEqualityComparer> { public ManualExpectationBuilder(aweXpect.Core.ExpectationBuilder? inner, aweXpect.Core.ExpectationGrammars grammars = 0) { } + public override aweXpect.Core.ExpectationBuilder AddContext(aweXpect.Core.ResultContext resultContext) { } public void AppendExpectation(System.Text.StringBuilder stringBuilder, string? indentation = null) { } protected virtual bool Equals(aweXpect.Core.ManualExpectationBuilder other) { } public override bool Equals(object? obj) { } @@ -260,14 +262,27 @@ namespace aweXpect.Core public static aweXpect.Core.MemberAccessor FromFunc(System.Func func, string name) { } public static aweXpect.Core.MemberAccessor FromFuncAsMemberAccessor(System.Func func, string name) { } } - public class ResultContext + public abstract class ResultContext { - public ResultContext(string title, System.Func syncContent, int priority = 0) { } - public ResultContext(string title, System.Func> asyncContent, int priority = 0) { } - public ResultContext(string title, string? content, int priority = 0) { } + protected ResultContext(string title, int priority = 0) { } public int Priority { get; } public string Title { get; set; } - public System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + public abstract System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default); + public class AsyncCallback : aweXpect.Core.ResultContext + { + public AsyncCallback(string title, System.Func> callback, int priority = 0) { } + public override System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + } + public class Fixed : aweXpect.Core.ResultContext + { + public Fixed(string title, string? content, int priority = 0) { } + public override System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + } + public class SyncCallback : aweXpect.Core.ResultContext + { + public SyncCallback(string title, System.Func callback, int priority = 0) { } + public override System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + } } public class ResultContexts : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { @@ -561,6 +576,7 @@ namespace aweXpect.Equivalency public abstract class EquivalencyExpectationBuilder : aweXpect.Core.ExpectationBuilder { protected EquivalencyExpectationBuilder() { } + public override aweXpect.Core.ExpectationBuilder AddContext(aweXpect.Core.ResultContext resultContext) { } public void AppendExpectation(System.Text.StringBuilder stringBuilder, string? indentation = null) { } public abstract System.Threading.Tasks.Task IsMetBy(TValue value, aweXpect.Core.EvaluationContext.IEvaluationContext context, System.Threading.CancellationToken cancellationToken); public override aweXpect.Core.ExpectationBuilder UpdateContexts(System.Action callback) { } 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 6e6c85bc8..2ad9d3678 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 @@ -155,6 +155,7 @@ namespace aweXpect.Core public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } public aweXpect.Core.ExpectationBuilder AddConstraint(System.Func> constraintBuilder) { } + public virtual aweXpect.Core.ExpectationBuilder AddContext(aweXpect.Core.ResultContext resultContext) { } public aweXpect.Core.ExpectationBuilder And(string textSeparator = " and ") { } public aweXpect.Core.ExpectationBuilder.MemberExpectationBuilder ForAsyncMember(aweXpect.Core.MemberAccessor> memberAccessor, System.Action? expectationTextGenerator = null, bool replaceIt = true) { } public aweXpect.Core.ExpectationBuilder.MemberExpectationBuilder ForMember(aweXpect.Core.MemberAccessor memberAccessor, System.Action? expectationTextGenerator = null, bool replaceIt = true) { } @@ -220,7 +221,7 @@ namespace aweXpect.Core } public interface IStringMatchType { - System.Threading.Tasks.Task AreConsideredEqual(string? actual, string? expected, bool ignoreCase, System.Collections.Generic.IEqualityComparer comparer); + System.Threading.Tasks.Task AreConsideredEqual(string? actual, string? expected, bool ignoreCase, System.Collections.Generic.IEqualityComparer? comparer); string GetExpectation(string? expected, aweXpect.Core.ExpectationGrammars grammars); string GetExtendedFailure(string it, string? actual, string? expected, bool ignoreCase, System.Collections.Generic.IEqualityComparer comparer, aweXpect.Core.StringDifferenceSettings? settings); string GetOptionString(bool ignoreCase, System.Collections.Generic.IEqualityComparer? comparer); @@ -237,6 +238,7 @@ namespace aweXpect.Core public class ManualExpectationBuilder : aweXpect.Core.ExpectationBuilder, System.Collections.Generic.IEqualityComparer> { public ManualExpectationBuilder(aweXpect.Core.ExpectationBuilder? inner, aweXpect.Core.ExpectationGrammars grammars = 0) { } + public override aweXpect.Core.ExpectationBuilder AddContext(aweXpect.Core.ResultContext resultContext) { } public void AppendExpectation(System.Text.StringBuilder stringBuilder, string? indentation = null) { } protected virtual bool Equals(aweXpect.Core.ManualExpectationBuilder other) { } public override bool Equals(object? obj) { } @@ -260,14 +262,27 @@ namespace aweXpect.Core public static aweXpect.Core.MemberAccessor FromFunc(System.Func func, string name) { } public static aweXpect.Core.MemberAccessor FromFuncAsMemberAccessor(System.Func func, string name) { } } - public class ResultContext + public abstract class ResultContext { - public ResultContext(string title, System.Func syncContent, int priority = 0) { } - public ResultContext(string title, System.Func> asyncContent, int priority = 0) { } - public ResultContext(string title, string? content, int priority = 0) { } + protected ResultContext(string title, int priority = 0) { } public int Priority { get; } public string Title { get; set; } - public System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + public abstract System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default); + public class AsyncCallback : aweXpect.Core.ResultContext + { + public AsyncCallback(string title, System.Func> callback, int priority = 0) { } + public override System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + } + public class Fixed : aweXpect.Core.ResultContext + { + public Fixed(string title, string? content, int priority = 0) { } + public override System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + } + public class SyncCallback : aweXpect.Core.ResultContext + { + public SyncCallback(string title, System.Func callback, int priority = 0) { } + public override System.Threading.Tasks.Task GetContent(System.Threading.CancellationToken cancellationToken = default) { } + } } public class ResultContexts : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { @@ -547,6 +562,7 @@ namespace aweXpect.Equivalency public abstract class EquivalencyExpectationBuilder : aweXpect.Core.ExpectationBuilder { protected EquivalencyExpectationBuilder() { } + public override aweXpect.Core.ExpectationBuilder AddContext(aweXpect.Core.ResultContext resultContext) { } public void AppendExpectation(System.Text.StringBuilder stringBuilder, string? indentation = null) { } public abstract System.Threading.Tasks.Task IsMetBy(TValue value, aweXpect.Core.EvaluationContext.IEvaluationContext context, System.Threading.CancellationToken cancellationToken); public override aweXpect.Core.ExpectationBuilder UpdateContexts(System.Action callback) { } diff --git a/Tests/aweXpect.Core.Tests/Core/ResultContextsTests.cs b/Tests/aweXpect.Core.Tests/Core/ResultContextsTests.cs index 60ec7120b..5ccf10879 100644 --- a/Tests/aweXpect.Core.Tests/Core/ResultContextsTests.cs +++ b/Tests/aweXpect.Core.Tests/Core/ResultContextsTests.cs @@ -7,7 +7,7 @@ public async Task Add_ShouldAddContext() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "bar")); + sut.Add(new ResultContext.Fixed("foo", "bar")); await That(sut).HasSingle().Which.IsEquivalentTo(new { @@ -20,11 +20,11 @@ public async Task AddMultiple_ShouldAddContext() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); - sut.Add(new ResultContext("foo", "2")); - sut.Add(new ResultContext("foo", "2")); - sut.Add(new ResultContext("bar", "3")); - sut.Add(new ResultContext("foo", "4")); + sut.Add(new ResultContext.Fixed("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "2")); + sut.Add(new ResultContext.Fixed("foo", "2")); + sut.Add(new ResultContext.Fixed("bar", "3")); + sut.Add(new ResultContext.Fixed("foo", "4")); await That(sut).HasCount().EqualTo(5); } @@ -34,8 +34,8 @@ public async Task Clear_ShouldRemoveAllContexts() { ResultContexts sut = [ - new ResultContext("foo", "bar"), - new ResultContext("foo", "bar"), + new ResultContext.Fixed("foo", "bar"), + new ResultContext.Fixed("foo", "bar"), ]; sut.Clear(); @@ -47,11 +47,11 @@ public async Task Clear_ShouldRemoveAllContexts() public async Task Close_ShouldRestrictAdd() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); - sut.Add(new ResultContext("bar", "2")); + sut.Add(new ResultContext.Fixed("bar", "2")); await That(sut).HasSingle().Which.IsEquivalentTo(new { Title = "foo", @@ -62,7 +62,7 @@ await That(sut).HasSingle().Which.IsEquivalentTo(new public async Task Close_ShouldRestrictClear() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); @@ -77,7 +77,7 @@ await That(sut).HasSingle().Which.IsEquivalentTo(new public async Task Close_ShouldRestrictRemoveWithPredicate() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); @@ -92,7 +92,7 @@ await That(sut).HasSingle().Which.IsEquivalentTo(new public async Task Close_ShouldRestrictRemoveWithTitle() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); @@ -107,12 +107,12 @@ await That(sut).HasSingle().Which.IsEquivalentTo(new public async Task Open_ShouldRestrictAdd() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); sut.Open(); - sut.Add(new ResultContext("bar", "2")); + sut.Add(new ResultContext.Fixed("bar", "2")); await That(sut).HasCount().EqualTo(2); } @@ -120,7 +120,7 @@ public async Task Open_ShouldRestrictAdd() public async Task Open_ShouldRestrictClear() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); sut.Open(); @@ -133,7 +133,7 @@ public async Task Open_ShouldRestrictClear() public async Task Open_ShouldRestrictRemoveWithPredicate() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); sut.Open(); @@ -146,7 +146,7 @@ public async Task Open_ShouldRestrictRemoveWithPredicate() public async Task Open_ShouldRestrictRemoveWithTitle() { ResultContexts sut = new(); - sut.Add(new ResultContext("foo", "1")); + sut.Add(new ResultContext.Fixed("foo", "1")); sut.Close(); sut.Open(); @@ -160,9 +160,9 @@ public async Task Remove_WithPredicate_ShouldRemoveAllMatchingContexts() { ResultContexts sut = [ - new ResultContext("foo", "bar"), - new ResultContext("bar", "baz"), - new ResultContext("foo", "bar"), + new ResultContext.Fixed("foo", "bar"), + new ResultContext.Fixed("bar", "baz"), + new ResultContext.Fixed("foo", "bar"), ]; sut.Remove(c => c.Title == "foo"); @@ -178,9 +178,9 @@ public async Task Remove_WithTitle_ShouldRemoveAllMatchingContexts() { ResultContexts sut = [ - new ResultContext("foo", "bar"), - new ResultContext("bar", "baz"), - new ResultContext("foo", "bar"), + new ResultContext.Fixed("foo", "bar"), + new ResultContext.Fixed("bar", "baz"), + new ResultContext.Fixed("foo", "bar"), ]; sut.Remove("foo"); diff --git a/Tests/aweXpect.Core.Tests/ExpectTests.cs b/Tests/aweXpect.Core.Tests/ExpectTests.cs index 2b97fcf11..5ee907609 100644 --- a/Tests/aweXpect.Core.Tests/ExpectTests.cs +++ b/Tests/aweXpect.Core.Tests/ExpectTests.cs @@ -16,8 +16,8 @@ public async Task Context_FromSuccess_ShouldNotBeIncludedInMessage() async Task Act() => await ThatAll( - new MyExpectation(result1, new ResultContext("context-title1", "contest-content1")), - new MyExpectation(result2, new ResultContext("context-title2", "contest-content2"))); + new MyExpectation(result1, new ResultContext.Fixed("context-title1", "contest-content1")), + new MyExpectation(result2, new ResultContext.Fixed("context-title2", "contest-content2"))); await That(Act).Throws() .WithMessage(""" @@ -38,8 +38,8 @@ public async Task Context_Multiple_ShouldBeIncludedInMessage() Expectation.Result result = new(1, "foo", new DummyConstraintResult(Outcome.Failure, "expectation", "result")); async Task Act() - => await ThatAll(new MyExpectation(result, new ResultContext("t1", "c1"), new ResultContext("t2", "c2"), - new ResultContext("t3", "c3"))); + => await ThatAll(new MyExpectation(result, new ResultContext.Fixed("t1", "c1"), new ResultContext.Fixed("t2", "c2"), + new ResultContext.Fixed("t3", "c3"))); await That(Act).Throws() .WithMessage(""" @@ -65,7 +65,7 @@ public async Task Context_ShouldBeIncludedInMessage() Expectation.Result result = new(1, "foo", new DummyConstraintResult(Outcome.Failure, "expectation", "result")); async Task Act() - => await ThatAll(new MyExpectation(result, new ResultContext("context-title", "contest-content"))); + => await ThatAll(new MyExpectation(result, new ResultContext.Fixed("context-title", "contest-content"))); await That(Act).Throws() .WithMessage("""