Skip to content

Commit

Permalink
SAVEPOINT
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisdoomen committed Jan 6, 2024
1 parent 28c4fc2 commit a517fec
Show file tree
Hide file tree
Showing 33 changed files with 1,203 additions and 181 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
8 changes: 4 additions & 4 deletions Src/FluentAssertions/AndConstraint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
namespace FluentAssertions;

[DebuggerNonUserCode]
public class AndConstraint<T>
public class AndConstraint<TParent>
{
public T And { get; }
public TParent And { get; }

/// <summary>
/// Initializes a new instance of the <see cref="AndConstraint{T}"/> class.
/// </summary>
public AndConstraint(T parentConstraint)
public AndConstraint(TParent parent)
{
And = parentConstraint;
And = parent;
}
}
70 changes: 70 additions & 0 deletions Src/FluentAssertions/AndWhich.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions.Common;
using FluentAssertions.Execution;
using FluentAssertions.Formatting;

namespace FluentAssertions;

public class AndWhich<TParent, TSubject> : AndConstraint<TParent>
{
private readonly Assertion assertion;
private readonly string pathPostfix;
private readonly Lazy<TSubject> getSubject;

public AndWhich(TParent parent, TSubject subject, Assertion assertion, string pathPostfix)
: base(parent)
{
getSubject = new Lazy<TSubject>(() => subject);

this.assertion = assertion;
this.pathPostfix = pathPostfix;
}

public AndWhich(TParent parent, IEnumerable<TSubject> subjects)
: base(parent)
{
getSubject = new Lazy<TSubject>(() => SingleOrDefault(subjects));
}

/// <summary>
/// Returns the single result of a prior assertion that is used to select a nested or collection item.
/// </summary>
/// <remarks>
/// Just a convenience property that returns the same value as <see cref="Which"/>.
/// </remarks>
public TSubject Subject => Which;

/// <summary>
/// Returns the single result of a prior assertion that is used to select a nested or collection item.
/// </summary>
public TSubject Which
{
get
{
assertion.AddCallerPostfix(pathPostfix);

Assertion.ReuseOnce(assertion);

return getSubject.Value;
}
}

private static TSubject SingleOrDefault(IEnumerable<TSubject> subjects)
{
TSubject[] matchedElements = subjects.ToArray();
if (matchedElements.Length > 1)
{
string foundObjects = string.Join(Environment.NewLine,
matchedElements.Select(ele => "\t" + Formatter.ToString(ele)));

string message = "More than one object found. FluentAssertions cannot determine which object is meant."
+ $" Found objects:{Environment.NewLine}{foundObjects}";

Services.ThrowException(message);
}

return matchedElements.Single();
}
}
54 changes: 48 additions & 6 deletions Src/FluentAssertions/AssertionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;

Check warning on line 4 in Src/FluentAssertions/AssertionExtensions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Redundant using directive

Using directive is not required by the code and can be safely removed
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
Expand All @@ -11,6 +12,7 @@
using System.Xml.Linq;
using FluentAssertions.Collections;
using FluentAssertions.Common;
using FluentAssertions.Execution;
using FluentAssertions.Numeric;
using FluentAssertions.Primitives;
using FluentAssertions.Specialized;
Expand Down Expand Up @@ -286,6 +288,11 @@ public static ObjectAssertions Should(this object actualValue)
return new ObjectAssertions(actualValue);
}

public static ObjectAssertions Should(this WhichResult<object> tuple)
{
return new ObjectAssertions(tuple.MatchedElement);
}

/// <summary>
/// Returns an <see cref="BooleanAssertions"/> object that can be used to assert the
/// current <see cref="bool"/>.
Expand Down Expand Up @@ -343,7 +350,7 @@ public static NullableGuidAssertions Should(this Guid? actualValue)
[Pure]
public static GenericCollectionAssertions<T> Should<T>(this IEnumerable<T> actualValue)
{
return new GenericCollectionAssertions<T>(actualValue);
return new GenericCollectionAssertions<T>(actualValue, Assertion.GetOrCreate(() => AssertionScope.Current, () => AssertionScope.Current.GetIdentifier()));
}

/// <summary>
Expand All @@ -353,7 +360,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, Assertion.GetOrCreate(() => AssertionScope.Current, () => AssertionScope.Current.GetIdentifier()));
}

/// <summary>
Expand All @@ -364,7 +371,8 @@ public static StringCollectionAssertions Should(this IEnumerable<string> @this)
public static GenericDictionaryAssertions<IDictionary<TKey, TValue>, TKey, TValue> Should<TKey, TValue>(
this IDictionary<TKey, TValue> actualValue)
{
return new GenericDictionaryAssertions<IDictionary<TKey, TValue>, TKey, TValue>(actualValue);
return new GenericDictionaryAssertions<IDictionary<TKey, TValue>, TKey, TValue>(actualValue, Assertion.GetOrCreate(() => AssertionScope.Current,
() => AssertionScope.Current.GetIdentifier()));
}

/// <summary>
Expand All @@ -375,7 +383,9 @@ public static StringCollectionAssertions Should(this IEnumerable<string> @this)
public static GenericDictionaryAssertions<IEnumerable<KeyValuePair<TKey, TValue>>, TKey, TValue> Should<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> actualValue)
{
return new GenericDictionaryAssertions<IEnumerable<KeyValuePair<TKey, TValue>>, TKey, TValue>(actualValue);
return new GenericDictionaryAssertions<IEnumerable<KeyValuePair<TKey, TValue>>, TKey, TValue>(actualValue,
Assertion.GetOrCreate(() => AssertionScope.Current,
() => AssertionScope.Current.GetIdentifier()));
}

/// <summary>
Expand All @@ -387,7 +397,8 @@ public static StringCollectionAssertions Should(this IEnumerable<string> @this)
this TCollection actualValue)
where TCollection : IEnumerable<KeyValuePair<TKey, TValue>>
{
return new GenericDictionaryAssertions<TCollection, TKey, TValue>(actualValue);
return new GenericDictionaryAssertions<TCollection, TKey, TValue>(actualValue, Assertion.GetOrCreate(() => AssertionScope.Current,
() => AssertionScope.Current.GetIdentifier()));
}

/// <summary>
Expand Down Expand Up @@ -483,6 +494,16 @@ public static ComparableTypeAssertions<T> Should<T>(this IComparable<T> comparab
return new ComparableTypeAssertions<T>(comparableValue);
}

/// <summary>
/// Returns an <see cref="ComparableTypeAssertions{T}"/> object that can be used to assert the
/// current <see cref="IComparable{T}"/>.
/// </summary>
[Pure]
public static ComparableTypeAssertions<T> Should<T>(this WhichResult<IComparable<T>> tuple)
{
return new ComparableTypeAssertions<T>(tuple.MatchedElement);
}

/// <summary>
/// Returns an <see cref="NumericAssertions{T}"/> object that can be used to assert the
/// current <see cref="int"/>.
Expand All @@ -493,6 +514,16 @@ public static NumericAssertions<int> Should(this int actualValue)
return new Int32Assertions(actualValue);
}

/// <summary>
/// Returns an <see cref="NumericAssertions{T}"/> object that can be used to assert the
/// current <see cref="int"/>.
/// </summary>
[Pure]
public static NumericAssertions<int> Should(this WhichResult<int> actualValue)
{
return new Int32Assertions(actualValue.MatchedElement);
}

/// <summary>
/// Returns an <see cref="NullableNumericAssertions{T}"/> object that can be used to assert the
/// current nullable <see cref="int"/>.
Expand Down Expand Up @@ -710,7 +741,18 @@ public static NullableNumericAssertions<double> Should(this double? actualValue)
[Pure]
public static StringAssertions Should(this string actualValue)
{
return new StringAssertions(actualValue);
return new StringAssertions(actualValue,
Assertion.GetOrCreate(() => AssertionScope.Current, () => AssertionScope.Current.GetIdentifier()));
}

/// <summary>
/// Returns an <see cref="StringAssertions"/> object that can be used to assert the
/// current <see cref="string"/>.
/// </summary>
[Pure]
public static StringAssertions Should(this (string ActualValue, Assertion CurrentAssertion) values)
{
return new StringAssertions(values.ActualValue, values.CurrentAssertion);
}

/// <summary>
Expand Down

0 comments on commit a517fec

Please sign in to comment.