diff --git a/Source/aweXpect/Helpers/EqualityHelpers.cs b/Source/aweXpect/Helpers/EqualityHelpers.cs index abb595561..e3efc8bbb 100644 --- a/Source/aweXpect/Helpers/EqualityHelpers.cs +++ b/Source/aweXpect/Helpers/EqualityHelpers.cs @@ -26,14 +26,9 @@ public static bool IsConsideredEqualTo(this double actual, double? expected, dou public static bool IsConsideredEqualTo(this double? actual, double? expected, double tolerance) { - if (actual is null && expected is null) - { - return true; - } - if (actual is null || expected is null) { - return false; + return actual is null && expected is null; } if (double.IsNaN(actual.Value) || double.IsNaN(expected.Value)) diff --git a/Source/aweXpect/Helpers/LinqAsyncHelpers.cs b/Source/aweXpect/Helpers/LinqAsyncHelpers.cs index a1f2107a3..ea39f8e49 100644 --- a/Source/aweXpect/Helpers/LinqAsyncHelpers.cs +++ b/Source/aweXpect/Helpers/LinqAsyncHelpers.cs @@ -7,12 +7,12 @@ namespace aweXpect.Helpers; internal static class LinqAsyncHelpers { #if NET8_0_OR_GREATER - public static async ValueTask AnyButNotAllAsync( + public static async ValueTask AnyButNotInDuplicatesAsync( this IEnumerable source, IEnumerable duplicates, Func> predicate) #else - public static async Task AnyButNotAllAsync( + public static async Task AnyButNotInDuplicatesAsync( this IEnumerable source, IEnumerable duplicates, Func> predicate) diff --git a/Source/aweXpect/Helpers/StringExtensions.cs b/Source/aweXpect/Helpers/StringExtensions.cs index 5522982ca..1b34a2ce5 100644 --- a/Source/aweXpect/Helpers/StringExtensions.cs +++ b/Source/aweXpect/Helpers/StringExtensions.cs @@ -15,13 +15,13 @@ internal static class StringExtensions return null; } - if (string.IsNullOrEmpty(indentation)) + if (!string.IsNullOrEmpty(indentation)) { - return value; + return (indentFirstLine ? indentation : "") + + value.Replace("\n", $"\n{indentation}"); } - return (indentFirstLine ? indentation : "") - + value.Replace("\n", $"\n{indentation}"); + return value; } public static string PrependAOrAn(this string value) @@ -37,40 +37,27 @@ public static string PrependAOrAn(this string value) public static string TrimCommonWhiteSpace(this string value) { - string[] lines = value.Split('\n'); + string[] lines = value.Split(Environment.NewLine); if (lines.Length <= 1) { return value; } StringBuilder sb = new(); - foreach (char c in lines[1]) + foreach (char c in lines[1].TakeWhile(char.IsWhiteSpace)) { - if (char.IsWhiteSpace(c)) - { - sb.Append(c); - } - else - { - break; - } + sb.Append(c); } string commonWhiteSpace = sb.ToString(); - for (int l = 2; l < lines.Length; l++) + foreach (string line in lines.Skip(2).Where(line => !line.StartsWith(commonWhiteSpace))) { - if (lines[l].StartsWith(commonWhiteSpace)) - { - continue; - } - - for (int i = 0; i < Math.Min(lines[l].Length, commonWhiteSpace.Length); i++) + for (int i = 0; i < Math.Min(line.Length, commonWhiteSpace.Length); i++) { - if (lines[l][i] != commonWhiteSpace[i]) + if (line[i] != commonWhiteSpace[i]) { commonWhiteSpace = commonWhiteSpace[..i]; - break; } } } @@ -79,7 +66,7 @@ public static string TrimCommonWhiteSpace(this string value) sb.Append(lines[0]); foreach (string? line in lines.Skip(1)) { - sb.Append('\n').Append(line[commonWhiteSpace.Length..]); + sb.Append(Environment.NewLine).Append(line[commonWhiteSpace.Length..]); } return sb.ToString(); diff --git a/Source/aweXpect/Polyfills/StringExtensions.cs b/Source/aweXpect/Polyfills/StringExtensions.cs index f0ec7f765..432bf37cc 100644 --- a/Source/aweXpect/Polyfills/StringExtensions.cs +++ b/Source/aweXpect/Polyfills/StringExtensions.cs @@ -60,6 +60,18 @@ internal static int IndexOf( StringComparison comparisonType) => @this.IndexOf($"{value}", comparisonType); + /// + /// Splits a string into substrings that are based on the provided string separator. + /// + /// + /// An array whose elements contain the substrings from this instance that are delimited by separator. + /// + internal static string[] Split( + this string @this, + string separator, + StringSplitOptions options = StringSplitOptions.None) + => @this.Split([separator,], options); + /// /// Determines whether this string instance starts with the specified character. /// diff --git a/Source/aweXpect/That/Collections/ThatAsyncEnumerable.AreAllUnique.cs b/Source/aweXpect/That/Collections/ThatAsyncEnumerable.AreAllUnique.cs index 94442621b..19175c2ef 100644 --- a/Source/aweXpect/That/Collections/ThatAsyncEnumerable.AreAllUnique.cs +++ b/Source/aweXpect/That/Collections/ThatAsyncEnumerable.AreAllUnique.cs @@ -124,7 +124,7 @@ public async Task IsMetBy(IAsyncEnumerable? actual, IEv IOptionsEquality o = options; await foreach (TItem item in materialized.WithCancellation(cancellationToken)) { - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(item, compareWith))) { _duplicates.Add(item); @@ -190,7 +190,7 @@ public async Task IsMetBy(IAsyncEnumerable? actual, IEv await foreach (TItem item in materialized.WithCancellation(cancellationToken)) { TMember itemMember = memberAccessor(item); - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(itemMember, compareWith))) { _duplicates.Add(itemMember); diff --git a/Source/aweXpect/That/Collections/ThatDictionary.AreAllUnique.cs b/Source/aweXpect/That/Collections/ThatDictionary.AreAllUnique.cs index b27ec4735..2b4bf2c28 100644 --- a/Source/aweXpect/That/Collections/ThatDictionary.AreAllUnique.cs +++ b/Source/aweXpect/That/Collections/ThatDictionary.AreAllUnique.cs @@ -235,7 +235,7 @@ public async Task IsMetBy(IDictionary? actual, I IOptionsEquality o = options; foreach (TValue item in actual.Values) { - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(item, compareWith))) { _duplicates.Add(item); @@ -298,7 +298,7 @@ public async Task IsMetBy(IDictionary? actual, I { TMember itemMember = memberAccessor(item); - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(itemMember, compareWith))) { _duplicates.Add(itemMember); diff --git a/Source/aweXpect/That/Collections/ThatEnumerable.AreAllUnique.cs b/Source/aweXpect/That/Collections/ThatEnumerable.AreAllUnique.cs index 681e7f170..c5706a95f 100644 --- a/Source/aweXpect/That/Collections/ThatEnumerable.AreAllUnique.cs +++ b/Source/aweXpect/That/Collections/ThatEnumerable.AreAllUnique.cs @@ -257,7 +257,7 @@ public async Task IsMetBy(IEnumerable? actual, IEvaluat IOptionsEquality o = options; foreach (TItem item in materialized) { - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(item, compareWith))) { _duplicates.Add(item); @@ -321,7 +321,7 @@ public async Task IsMetBy(IEnumerable? actual, IEvaluat foreach (TItem item in materialized) { TMember itemMember = memberAccessor(item); - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(itemMember, compareWith))) { _duplicates.Add(itemMember); @@ -382,7 +382,7 @@ public async Task IsMetBy(TEnumerable? actual, IEvaluationCont foreach (object? item in materialized) { if (item is TMatch matchedItem && - await checkedItems.AnyButNotAllAsync(_duplicates, + await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(matchedItem, compareWith))) { _duplicates.Add(item); @@ -446,7 +446,7 @@ public async Task IsMetBy(TEnumerable? actual, IEvaluationCont foreach (object? item in materialized) { TMember itemMember = memberAccessor(item); - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(itemMember, compareWith))) { _duplicates.Add(itemMember); diff --git a/Source/aweXpect/That/Collections/ThatReadOnlyDictionary.AreAllUnique.cs b/Source/aweXpect/That/Collections/ThatReadOnlyDictionary.AreAllUnique.cs index 2c37e9e04..2eb59f7ee 100644 --- a/Source/aweXpect/That/Collections/ThatReadOnlyDictionary.AreAllUnique.cs +++ b/Source/aweXpect/That/Collections/ThatReadOnlyDictionary.AreAllUnique.cs @@ -244,7 +244,7 @@ public async Task IsMetBy(IReadOnlyDictionary? a IOptionsEquality o = options; foreach (TValue item in actual.Values) { - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(item, compareWith))) { _duplicates.Add(item); @@ -306,7 +306,7 @@ public async Task IsMetBy(IReadOnlyDictionary? a foreach (TValue item in actual.Values) { TMember itemMember = memberAccessor(item); - if (await checkedItems.AnyButNotAllAsync(_duplicates, + if (await checkedItems.AnyButNotInDuplicatesAsync(_duplicates, compareWith => o.AreConsideredEqual(itemMember, compareWith))) { _duplicates.Add(itemMember); diff --git a/Tests/aweXpect.Internal.Tests/Helpers/EqualityHelpersTests.cs b/Tests/aweXpect.Internal.Tests/Helpers/EqualityHelpersTests.cs new file mode 100644 index 000000000..cc5baba0c --- /dev/null +++ b/Tests/aweXpect.Internal.Tests/Helpers/EqualityHelpersTests.cs @@ -0,0 +1,405 @@ +using System.Globalization; +using aweXpect.Helpers; + +namespace aweXpect.Internal.Tests.Helpers; + +public sealed class EqualityHelpersTests +{ + public sealed class IsConsideredEqualTo + { + public sealed class DoubleTests + { + [Fact] + public async Task WhenBothAreNaN_ShouldReturnTrue() + { + double value = double.NaN; + double expected = double.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsTrue(); + } + + [Theory] + [InlineData(0.1, 0.0, 0.1)] + [InlineData(0.0, 0.1, 0.1)] + public async Task WhenDifferenceIsTolerance_ShouldReturnTrue( + double value, double expected, double tolerance) + { + bool result = value.IsConsideredEqualTo(expected, tolerance); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenExpectedIsNaN_ShouldReturnFalse() + { + double value = 0.1; + double expected = double.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenExpectedIsNull_ShouldReturnFalse() + { + double value = double.NaN; + double? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenSubjectIsNaN_ShouldReturnFalse() + { + double value = double.NaN; + double expected = 0.1; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsFalse(); + } + } + + public sealed class NullableDoubleTests + { + [Fact] + public async Task WhenBothAreNaN_ShouldReturnTrue() + { + double? value = double.NaN; + double expected = double.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenBothAreNull_ShouldReturnTrue() + { + double? value = null; + double? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsTrue(); + } + + [Theory] + [InlineData(0.1, 0.0, 0.1)] + [InlineData(0.0, 0.1, 0.1)] + public async Task WhenDifferenceIsTolerance_ShouldReturnTrue( + double? value, double expected, double tolerance) + { + bool result = value.IsConsideredEqualTo(expected, tolerance); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenExpectedIsNaN_ShouldReturnFalse() + { + double? value = 0.1; + double expected = double.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenExpectedIsNull_ShouldReturnFalse() + { + double? value = double.NaN; + double? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenSubjectIsNaN_ShouldReturnFalse() + { + double? value = double.NaN; + double expected = 0.1; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenSubjectIsNull_ShouldReturnFalse() + { + double? value = null; + double? expected = double.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1); + + await That(result).IsFalse(); + } + } + + public sealed class FloatTests + { + [Fact] + public async Task WhenBothAreNaN_ShouldReturnTrue() + { + float value = float.NaN; + float expected = float.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsTrue(); + } + + [Theory] + [InlineData(0.1F, 0.0F, 0.1F)] + [InlineData(0.0F, 0.1F, 0.1F)] + public async Task WhenDifferenceIsTolerance_ShouldReturnTrue( + float value, float expected, float tolerance) + { + bool result = value.IsConsideredEqualTo(expected, tolerance); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenExpectedIsNaN_ShouldReturnFalse() + { + float value = 0.1F; + float expected = float.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenExpectedIsNull_ShouldReturnFalse() + { + float value = float.NaN; + float? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenSubjectIsNaN_ShouldReturnFalse() + { + float value = float.NaN; + float expected = 0.1F; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsFalse(); + } + } + + public sealed class NullableFloatTests + { + [Fact] + public async Task WhenBothAreNaN_ShouldReturnTrue() + { + float? value = float.NaN; + float expected = float.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenBothAreNull_ShouldReturnTrue() + { + float? value = null; + float? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsTrue(); + } + + [Theory] + [InlineData(0.1F, 0.0F, 0.1F)] + [InlineData(0.0F, 0.1F, 0.1F)] + public async Task WhenDifferenceIsTolerance_ShouldReturnTrue( + float? value, float expected, float tolerance) + { + bool result = value.IsConsideredEqualTo(expected, tolerance); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenExpectedIsNaN_ShouldReturnFalse() + { + float? value = 0.1F; + float expected = float.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenExpectedIsNull_ShouldReturnFalse() + { + float? value = float.NaN; + float? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenSubjectIsNaN_ShouldReturnFalse() + { + float? value = float.NaN; + float expected = 0.1F; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenSubjectIsNull_ShouldReturnFalse() + { + float? value = null; + float? expected = float.NaN; + + bool result = value.IsConsideredEqualTo(expected, 0.1F); + + await That(result).IsFalse(); + } + } + + public sealed class DecimalTests + { + [Theory] + [InlineData("0.1", "0.0", "0.1")] + [InlineData("0.0", "0.1", "0.1")] + public async Task WhenDifferenceIsTolerance_ShouldReturnTrue( + string valueString, string expectedString, string toleranceString) + { + decimal value = decimal.Parse(valueString, CultureInfo.InvariantCulture); + decimal expected = decimal.Parse(expectedString, CultureInfo.InvariantCulture); + decimal tolerance = decimal.Parse(toleranceString, CultureInfo.InvariantCulture); + + bool result = value.IsConsideredEqualTo(expected, tolerance); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenExpectedIsNull_ShouldReturnFalse() + { + decimal value = decimal.MinValue; + decimal? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1m); + + await That(result).IsFalse(); + } + } + + public sealed class NullableDecimalTests + { + [Fact] + public async Task WhenBothAreNull_ShouldReturnTrue() + { + decimal? value = null; + decimal? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1m); + + await That(result).IsTrue(); + } + + [Theory] + [InlineData("0.1", "0.0", "0.1")] + [InlineData("0.0", "0.1", "0.1")] + public async Task WhenDifferenceIsTolerance_ShouldReturnTrue( + string valueString, string expectedString, string toleranceString) + { + decimal? value = decimal.Parse(valueString, CultureInfo.InvariantCulture); + decimal? expected = decimal.Parse(expectedString, CultureInfo.InvariantCulture); + decimal tolerance = decimal.Parse(toleranceString, CultureInfo.InvariantCulture); + + bool result = value.IsConsideredEqualTo(expected, tolerance); + + await That(result).IsTrue(); + } + + [Fact] + public async Task WhenExpectedIsNull_ShouldReturnFalse() + { + decimal? value = decimal.MinValue; + decimal? expected = null; + + bool result = value.IsConsideredEqualTo(expected, 0.1m); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenSubjectIsNull_ShouldReturnFalse() + { + decimal? value = null; + decimal? expected = decimal.MinValue; + + bool result = value.IsConsideredEqualTo(expected, 0.1m); + + await That(result).IsFalse(); + } + } + + public sealed class NullableDateTimeTests + { + [Fact] + public async Task WhenBothAreNull_ShouldReturnTrue() + { + DateTime? value = null; + DateTime? expected = null; + + bool result = value.IsConsideredEqualTo(expected, TimeSpan.Zero, out bool hasKindDifference); + + await That(result).IsTrue(); + await That(hasKindDifference).IsFalse(); + } + + [Fact] + public async Task WhenExpectedIsNull_ShouldReturnFalse() + { + DateTime? value = DateTime.Now; + DateTime? expected = null; + + bool result = value.IsConsideredEqualTo(expected, TimeSpan.MaxValue, out bool hasKindDifference); + + await That(result).IsFalse(); + await That(hasKindDifference).IsTrue(); + } + + [Fact] + public async Task WhenSubjectIsNull_ShouldReturnFalse() + { + DateTime? value = null; + DateTime? expected = DateTime.Now; + + bool result = value.IsConsideredEqualTo(expected, TimeSpan.MaxValue, out bool hasKindDifference); + + await That(result).IsFalse(); + await That(hasKindDifference).IsTrue(); + } + } + } +} diff --git a/Tests/aweXpect.Internal.Tests/Helpers/LinqAsyncHelpersTests.cs b/Tests/aweXpect.Internal.Tests/Helpers/LinqAsyncHelpersTests.cs new file mode 100644 index 000000000..fd6235bf2 --- /dev/null +++ b/Tests/aweXpect.Internal.Tests/Helpers/LinqAsyncHelpersTests.cs @@ -0,0 +1,48 @@ +using aweXpect.Helpers; + +namespace aweXpect.Internal.Tests.Helpers; + +public sealed class LinqAsyncHelpersTests +{ + public sealed class AnyButNotInDuplicatesAsyncTests + { + [Fact] + public async Task WhenMissingInSource_ShouldBeFalse() + { + int[] source = [1, 2, 3,]; + int[] duplicates = [2, 3, 42,]; + + bool result = await source.AnyButNotInDuplicatesAsync(duplicates, Is42Predicate); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenOccursInSourceAndInDuplicates_ShouldBeFalse() + { + int[] source = [1, 2, 3, 42,]; + int[] duplicates = [2, 3, 42,]; + + bool result = await source.AnyButNotInDuplicatesAsync(duplicates, Is42Predicate); + + await That(result).IsFalse(); + } + + [Fact] + public async Task WhenOccursInSourceButNotInDuplicates_ShouldBeTrue() + { + int[] source = [1, 2, 3, 42,]; + int[] duplicates = [2, 3,]; + + bool result = await source.AnyButNotInDuplicatesAsync(duplicates, Is42Predicate); + + await That(result).IsTrue(); + } + } + +#if NET8_0_OR_GREATER + private static ValueTask Is42Predicate(int value) => ValueTask.FromResult(value == 42); +#else + private static Task Is42Predicate(int value) => Task.FromResult(value == 42); +#endif +} diff --git a/Tests/aweXpect.Internal.Tests/Helpers/QuantifierHelpersTests.cs b/Tests/aweXpect.Internal.Tests/Helpers/QuantifierHelpersTests.cs new file mode 100644 index 000000000..5ba1d5c4f --- /dev/null +++ b/Tests/aweXpect.Internal.Tests/Helpers/QuantifierHelpersTests.cs @@ -0,0 +1,18 @@ +using aweXpect.Helpers; +using aweXpect.Options; + +namespace aweXpect.Internal.Tests.Helpers; + +public sealed class QuantifierHelpersTests +{ + [Fact] + public async Task WhenIndentationIsEmpty_ShouldReturnInput() + { + Quantifier quantifier = Quantifier.Never(); + + string result1 = quantifier.ToNegatedString(); + string result2 = quantifier.ToNegatedString(); + + await That(result1).IsEqualTo(result2); + } +} diff --git a/Tests/aweXpect.Internal.Tests/Helpers/StringExtensionsTests.cs b/Tests/aweXpect.Internal.Tests/Helpers/StringExtensionsTests.cs index a8b2c5987..6fc113857 100644 --- a/Tests/aweXpect.Internal.Tests/Helpers/StringExtensionsTests.cs +++ b/Tests/aweXpect.Internal.Tests/Helpers/StringExtensionsTests.cs @@ -7,24 +7,26 @@ public sealed class StringExtensionsTests public sealed class IndentTests { [Fact] - public async Task WhenIndentationIsEmpty_ShouldReturnInput() + public async Task WhenIndentationIsNotEmpty_ShouldReturnIndentedInput() { string input = "foo\nbar"; + string expected = " foo\n bar"; - string result = input.Indent(""); + string result = input.Indent(" "); - await That(result).IsEqualTo(input); + await That(result).IsEqualTo(expected); } - [Fact] - public async Task WhenIndentationIsNotEmpty_ShouldReturnIndentedInput() + [Theory] + [InlineData("")] + [InlineData(null)] + public async Task WhenIndentationIsNullOrEmpty_ShouldReturnInput(string? indentation) { string input = "foo\nbar"; - string expected = " foo\n bar"; - string result = input.Indent(" "); + string result = input.Indent(indentation); - await That(result).IsEqualTo(expected); + await That(result).IsEqualTo(input); } [Fact] @@ -39,7 +41,7 @@ public async Task WhenIndentFirstLineIsFalse_ShouldOnlyIndentSubsequentLines() } [Fact] - public async Task WhenNull_ShouldReturnNull() + public async Task WhenInputIsNull_ShouldReturnNull() { string? input = null; @@ -111,11 +113,11 @@ await That(result).IsEqualTo(""" } [Fact] - public async Task WhenLinesHaveSomeCommonWhiteSpace_ShouldTrim() + public async Task WhenLinesHaveSomeCommonWhiteSpace1_ShouldTrim() { string input = """ foo - bar + bar baz bay """; @@ -124,12 +126,34 @@ public async Task WhenLinesHaveSomeCommonWhiteSpace_ShouldTrim() await That(result).IsEqualTo(""" foo - bar + bar baz bay """); } + [Fact] + public async Task WhenLinesHaveSomeCommonWhiteSpace2_ShouldTrim() + { + string input = """ + foo + bar + + baz + bay + """; + + string result = input.TrimCommonWhiteSpace(); + + await That(result).IsEqualTo(""" + foo + bar + + baz + bay + """); + } + [Fact] public async Task WhenOnlyHasOneLine_ShouldReturnLine() { diff --git a/Tests/aweXpect.Internal.Tests/Options/RepeatedCheckOptionsTests.cs b/Tests/aweXpect.Internal.Tests/Options/RepeatedCheckOptionsTests.cs index 846a37c66..6e1a5273e 100644 --- a/Tests/aweXpect.Internal.Tests/Options/RepeatedCheckOptionsTests.cs +++ b/Tests/aweXpect.Internal.Tests/Options/RepeatedCheckOptionsTests.cs @@ -1,4 +1,5 @@ -using aweXpect.Options; +using aweXpect.Customization; +using aweXpect.Options; using FluentAssertions.Extensions; namespace aweXpect.Internal.Tests.Options; @@ -12,4 +13,23 @@ public async Task DefaultInterval_ShouldBe100Milliseconds() await That(result).IsEqualTo(100.Milliseconds()); } + + [Fact] + public async Task Interval_ShouldBeReadOnlyOnceFromCustomization() + { + RepeatedCheckOptions sut = new(); + ICheckInterval interval1, interval2; + using (Customize.aweXpect.Settings().DefaultCheckInterval.Set(103.Milliseconds())) + { + interval1 = sut.Interval; + } + + using (Customize.aweXpect.Settings().DefaultCheckInterval.Set(107.Milliseconds())) + { + interval2 = sut.Interval; + } + + await That(interval1.NextCheckInterval()).IsEqualTo(103.Milliseconds()); + await That(interval1.NextCheckInterval()).IsEqualTo(interval2.NextCheckInterval()); + } }