Skip to content

Commit

Permalink
Use string options in StringEqualityEquivalencyStep
Browse files Browse the repository at this point in the history
  • Loading branch information
vbreuss committed Oct 29, 2023
1 parent f5feb3d commit 9f7b5a7
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 1 deletion.
Expand Up @@ -28,12 +28,45 @@ public class StringEqualityEquivalencyStep : IEquivalencyStep
string expectation = (string)comparands.Expectation;

subject.Should()
.Be(expectation, context.Reason.FormattedMessage, context.Reason.Arguments);
.Be(expectation, CreateOptions(context.Options), context.Reason.FormattedMessage, context.Reason.Arguments);
}

return EquivalencyResult.AssertionCompleted;
}

private static Func<EquivalencyAssertionOptions<string>, EquivalencyAssertionOptions<string>> CreateOptions(IEquivalencyAssertionOptions existingOptions)
{
return o =>
{
if (existingOptions is EquivalencyAssertionOptions<string> equivalencyAssertionOptions)
{
return equivalencyAssertionOptions;
}
if (existingOptions.IgnoreLeadingWhitespace)
{
o.IgnoringLeadingWhitespace();
}
if (existingOptions.IgnoreTrailingWhitespace)
{
o.IgnoringTrailingWhitespace();
}
if (existingOptions.IgnoreNewlines)
{
o.IgnoringNewlines();
}
if (existingOptions.IgnoreCase)
{
o.IgnoringCase();
}
return o;
};
}

private static bool ValidateAgainstNulls(Comparands comparands, INode currentNode)
{
object expected = comparands.Expectation;
Expand Down
33 changes: 33 additions & 0 deletions Src/FluentAssertions/Primitives/StringAssertions.cs
Expand Up @@ -63,6 +63,39 @@ public AndConstraint<TAssertions> Be(string expected, string because = "", param
return new AndConstraint<TAssertions>((TAssertions)this);
}

/// <summary>
/// Asserts that a string is exactly the same as another string, using the provided <paramref name="config"/>.
/// </summary>
/// <param name="expected">The expected string.</param>
/// <param name="config">
/// The equivalency options.
/// </param>
/// <param name="because">
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </param>
/// <param name="becauseArgs">
/// Zero or more objects to format using the placeholders in <paramref name="because" />.
/// </param>
public AndConstraint<TAssertions> Be(string expected,
Func<EquivalencyAssertionOptions<string>, EquivalencyAssertionOptions<string>> config,
string because = "", params object[] becauseArgs)
{
Guard.ThrowIfArgumentIsNull(config);

EquivalencyAssertionOptions<string> options = config(AssertionOptions.CloneDefaults<string>());

var expectation = new StringValidator(
new StringEqualityStrategy(options.GetStringComparerOrDefault()),
because, becauseArgs);

var subject = options.ApplyStringSettings(Subject);
expected = options.ApplyStringSettings(expected);

expectation.Validate(subject, expected);
return new AndConstraint<TAssertions>((TAssertions)this);
}

/// <summary>
/// Asserts that the <see cref="string"/> is one of the specified <paramref name="validValues"/>.
/// </summary>
Expand Down
Expand Up @@ -2022,6 +2022,7 @@ namespace FluentAssertions.Primitives
public StringAssertions(string value) { }
protected override string Identifier { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEmpty(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -2106,6 +2106,7 @@ namespace FluentAssertions.Primitives
public StringAssertions(string value) { }
protected override string Identifier { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEmpty(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -1973,6 +1973,7 @@ namespace FluentAssertions.Primitives
public StringAssertions(string value) { }
protected override string Identifier { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEmpty(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -2022,6 +2022,7 @@ namespace FluentAssertions.Primitives
public StringAssertions(string value) { }
protected override string Identifier { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEmpty(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeEquivalentTo(string expected, System.Func<FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>, FluentAssertions.Equivalency.EquivalencyAssertionOptions<string>> config, string because = "", params object[] becauseArgs) { }
Expand Down
Expand Up @@ -158,6 +158,50 @@ public void Default_immutable_lists_should_be_equivalent()
// Act / Assert
collection.Should().BeEquivalentTo(collection1);
}

[Fact]
public void Succeed_for_collection_with_case_different_strings_when_IgnoringCase()
{
// Arrange
var actual = new[] { "first", "test", "last" };
var expect = new[] { "first", "TEST", "last" };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringCase());
}

[Fact]
public void Succeed_for_collection_with_leading_whitespace_different_strings_when_IgnoringLeadingWhitespace()
{
// Arrange
var actual = new[] { "first", "test", "last" };
var expect = new[] { "first", " test", "last" };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringLeadingWhitespace());
}

[Fact]
public void Succeed_for_collection_with_trailing_whitespace_different_strings_when_IgnoringTrailingWhitespace()
{
// Arrange
var actual = new[] { "first", "test", "last" };
var expect = new[] { "first", "test ", "last" };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringTrailingWhitespace());
}

[Fact]
public void Succeed_for_collection_with_newline_different_strings_when_IgnoringNewlines()
{
// Arrange
var actual = new[] { "first", "ABC", "last" };
var expect = new[] { "first", "\rA\nB\r\nC\n", "last" };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringNewlines());
}
}

public class NotBeEquivalentTo
Expand Down
47 changes: 47 additions & 0 deletions Tests/FluentAssertions.Specs/Primitives/ObjectAssertionSpecs.cs
Expand Up @@ -357,6 +357,53 @@ public void Can_chain_multiple_assertions()
}
}

public class BeEquivalentTo
{
[Fact]
public void Succeed_for_object_containing_case_different_strings_when_IgnoringCase()
{
// Arrange
var actual = new { foo = "test" };
var expect = new { foo = "TEST" };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringCase());
}

[Fact]
public void Succeed_for_object_containing_leading_whitespace_different_strings_when_IgnoringLeadingWhitespace()
{
// Arrange
var actual = new { foo = "test" };
var expect = new { foo = " test" };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringLeadingWhitespace());
}

[Fact]
public void Succeed_for_object_containing_trailing_whitespace_different_strings_when_IgnoringTrailingWhitespace()
{
// Arrange
var actual = new { foo = "test" };
var expect = new { foo = "test " };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringTrailingWhitespace());
}

[Fact]
public void Succeed_for_object_containing_newline_different_strings_when_IgnoringNewlines()
{
// Arrange
var actual = new { foo = "ABC" };
var expect = new { foo = "\rA\nB\r\nC\n" };

// Act / Assert
actual.Should().BeEquivalentTo(expect, o => o.IgnoringNewlines());
}
}

public class BeOneOf
{
[Fact]
Expand Down

0 comments on commit 9f7b5a7

Please sign in to comment.