Skip to content

Commit

Permalink
SAVEPOINT
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisdoomen committed Aug 27, 2023
1 parent bc49f11 commit f6a01cd
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 24 deletions.
28 changes: 14 additions & 14 deletions FluentAssertions.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,22 @@
<s:Int64 x:Key="/Default/Environment/UnitTesting/ParallelProcessesCount/@EntryValue">4</s:Int64>
<s:Boolean x:Key="/Default/Environment/UnitTesting/ShadowCopy/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Field/=behavior/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Field/=behavior/Order/@EntryValue">1</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Field/=scenario/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Field/=scenario/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Field/=behavior/@KeyIndexDefined">False</s:Boolean>

<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Field/=scenario/@KeyIndexDefined">False</s:Boolean>

<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Shortcut/@EntryValue">aaa</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Description/@EntryValue">Arrange-Act-Assert</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Text/@EntryValue">[TestMethod]&#xD;
public void When_$scenario$_it_should_$behavior$()&#xD;
{&#xD;
// Arrange&#xD;
$END$&#xD;
&#xD;
// Act&#xD;
&#xD;
&#xD;
// Assert&#xD;
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Text/@EntryValue">[Fact]
public void $END$()
{
// Arrange


// Act


// Assert
}</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=012E3B0572DEF2448B0B5D9AA88E6210/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
Expand Down
3 changes: 2 additions & 1 deletion Src/FluentAssertions/AssertionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using FluentAssertions.Collections;
using FluentAssertions.Common;
using FluentAssertions.Data;
using FluentAssertions.Execution;
using FluentAssertions.Numeric;
using FluentAssertions.Primitives;
using FluentAssertions.Reflection;
Expand Down Expand Up @@ -351,7 +352,7 @@ public static GenericCollectionAssertions<T> Should<T>(this IEnumerable<T> actua
[Pure]
public static StringCollectionAssertions Should(this IEnumerable<string> @this)
{
return new StringCollectionAssertions(@this);
return new StringCollectionAssertions(@this, new Assertion(AssertionScope.Current));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ public class GenericCollectionAssertions<TCollection, T, TAssertions> : Referenc
where TCollection : IEnumerable<T>
where TAssertions : GenericCollectionAssertions<TCollection, T, TAssertions>
{
public GenericCollectionAssertions(TCollection actualValue)
private readonly Assertion assertion;

public GenericCollectionAssertions(TCollection actualValue, Assertion assertion)
: base(actualValue)
{
this.assertion = assertion;
}

/// <summary>
Expand Down Expand Up @@ -1190,7 +1193,7 @@ public AndWhichConstraint<TAssertions, T> ContainSingle(Expression<Func<T, bool>
const string expectationPrefix =
"Expected {context:collection} to contain a single item matching {0}{reason}, ";

bool success = Execute.Assertion
bool success = assertion
.BecauseOf(because, becauseArgs)
.ForCondition(Subject is not null)
.FailWith(expectationPrefix + "but found <null>.", predicate);
Expand Down
12 changes: 6 additions & 6 deletions Src/FluentAssertions/Collections/StringCollectionAssertions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class StringCollectionAssertions : StringCollectionAssertions<IEnumerable
/// <summary>
/// Initializes a new instance of the <see cref="StringCollectionAssertions"/> class.
/// </summary>
public StringCollectionAssertions(IEnumerable<string> actualValue)
: base(actualValue)
public StringCollectionAssertions(IEnumerable<string> actualValue, Assertion assertion)
: base(actualValue, assertion)
{
}
}
Expand All @@ -25,8 +25,8 @@ public class StringCollectionAssertions<TCollection>
/// <summary>
/// Initializes a new instance of the <see cref="StringCollectionAssertions{TCollection}"/> class.
/// </summary>
public StringCollectionAssertions(TCollection actualValue)
: base(actualValue)
public StringCollectionAssertions(TCollection actualValue, Assertion assertion)
: base(actualValue, assertion)
{
}
}
Expand All @@ -38,8 +38,8 @@ public class StringCollectionAssertions<TCollection, TAssertions> : GenericColle
/// <summary>
/// Initializes a new instance of the <see cref="StringCollectionAssertions{TCollection, TAssertions}"/> class.
/// </summary>
public StringCollectionAssertions(TCollection actualValue)
: base(actualValue)
public StringCollectionAssertions(TCollection actualValue, Assertion assertion)
: base(actualValue, assertion)
{
}

Expand Down
56 changes: 56 additions & 0 deletions Src/FluentAssertions/Execution/Assertion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Globalization;

namespace FluentAssertions.Execution;

public class Assertion
{
private readonly IAssertionScope currentScope;
private Func<string> reason;
private bool? succeeded;

public Assertion(IAssertionScope currentScope)
{
this.currentScope = currentScope;
}

/// <summary>
/// Adds an explanation of why the assertion is supposed to succeed to the scope.
/// </summary>
public Assertion BecauseOf(Reason reason)
{
return BecauseOf(reason.FormattedMessage, reason.Arguments);
}

/// <inheritdoc cref="IAssertionScope.BecauseOf(string, object[])"/>
public Assertion BecauseOf(string because, params object[] becauseArgs)
{
reason = () =>
{
try
{
string becauseOrEmpty = because ?? string.Empty;
return becauseArgs?.Length > 0
? string.Format(CultureInfo.InvariantCulture, becauseOrEmpty, becauseArgs)
: becauseOrEmpty;
}
catch (FormatException formatException)
{
return
$"**WARNING** because message '{because}' could not be formatted with string.Format{Environment.NewLine}{formatException.StackTrace}";
}
};

return this;
}

/// <inheritdoc cref="IAssertionScope.ForCondition(bool)"/>
public AssertionScope ForCondition(bool condition)
{
succeeded = condition;

return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,21 @@ namespace FluentAssertions.Specs.Collections;
/// </summary>
public partial class CollectionAssertionSpecs
{
public class Chainings
public class Chaining
{
[Fact]
public void Chaining_something_should_do_something()
{
// Act
var languages = new[] { "C#" };

var act = () => languages.Should().ContainSingle()
.Which.Should().EndWith("script");

// Assert
act.Should().Throw<XunitException>().WithMessage("Expected languages[0]*");
}

[Fact]
public void Should_support_chaining_constraints_with_and()
{
Expand Down

0 comments on commit f6a01cd

Please sign in to comment.