Skip to content
Permalink
Browse files
Fix minor issues related to IEnumerable error messages
  • Loading branch information
dupdob committed Jun 6, 2017
1 parent 60cd571 commit afefc30fbbd1df8e7c83c1f0b1949a2701f6b2c9
@@ -17,7 +17,7 @@
<PackagesPath>$(ArtifactsPath)\Packages</PackagesPath>
<DocPath>$(ArtifactsPath)\Docs</DocPath>
<NuGetToolsPath></NuGetToolsPath>
<AttributeVersionFile>$(SolutionRoot)\Version.cs</AttributeVersionFile>
<AttributeVersionFile>$(SolutionRoot)\Version.cs</AttributeVersionFile>
<NuGetExePath>$(NuGetToolsPath)nuget.exe</NuGetExePath>
<DocuExePath>$(ToolsPath)docu\docu.exe</DocuExePath>
<ZipExe>$(ToolsPath)7za\7za.exe</ZipExe>
@@ -3,7 +3,7 @@
<metadata>
<id>NFluent</id>
<title>NFluent, smooth your .NET TDD experience!</title>
<version>2.0.0-alpha-00</version>
<version>2.0.0-nightly-00</version>
<authors>Thomas PIERRAIN, Cyrille DUPUYDAUBY, Rui CARVALHO, Marc-Antoine LATOUR</authors>
<owners>Thomas PIERRAIN</owners>
<licenseUrl>http://www.apache.org/licenses/LICENSE-2.0</licenseUrl>
@@ -15,6 +15,8 @@
<releaseNotes>New feature(s):
* Support for NetStandard &gt; 1.3
* Support for Net.Core &gt; 1.0
* Compatible for Net &gt; 2.0
* Built for: 2.0, 3.0, 3.5, 4.0, 4.5, NetStandard 1.3
* All: introduce: HasSameValueAs(x) that perform comparison using 'operator==' instead of 'Equals'.
* All: introduce: HasAValueDifferentFrom(x) that perform comparison using 'operator!=' instead of '!Equals'.
* Streams: introduce HasSameSequenceOfBytesAs() check.
@@ -87,6 +87,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFluent.45", "src\NFluent.4
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFluent.45.Tests", "tests\NFluent.45.Tests\NFluent.45.Tests.csproj", "{0014C223-A481-4B87-A480-3D4792A9B276}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFluent.45.Tests.Internals", "tests\NFluent.45.Tests.Internals\NFluent.45.Tests.Internals.csproj", "{95799318-9A09-46C8-AE53-2546F053EF40}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
tests\NFluent.Tests\NFluent.Tests.projitems*{0014c223-a481-4b87-a480-3d4792a9b276}*SharedItemsImports = 4
@@ -98,6 +100,7 @@ Global
src\NFluent\NFluent.projitems*{3a474510-f384-41ce-9270-539b1e51da7e}*SharedItemsImports = 4
src\NFluent\NFluent.projitems*{4797a166-0410-451e-8dab-da7113d77062}*SharedItemsImports = 4
tests\NFluent.Tests\NFluent.Tests.projitems*{6b88c45a-d45e-40fb-8635-d0e0ef0454e9}*SharedItemsImports = 4
tests\NFluent.Tests.Internals\NFluent.Tests.Internals.projitems*{95799318-9a09-46c8-ae53-2546f053ef40}*SharedItemsImports = 4
tests\NFluent.Tests\NFluent.Tests.projitems*{9601b939-8314-4be8-9cde-217e47a7259c}*SharedItemsImports = 4
tests\NFluent.Tests.Internals\NFluent.Tests.Internals.projitems*{9e500148-4f6c-424a-aa09-801db1749677}*SharedItemsImports = 4
tests\NFluent.Tests.Internals\NFluent.Tests.Internals.projitems*{a7c2f427-3d13-4c9b-8663-1ce1e0734608}*SharedItemsImports = 4
@@ -195,6 +198,10 @@ Global
{0014C223-A481-4B87-A480-3D4792A9B276}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0014C223-A481-4B87-A480-3D4792A9B276}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0014C223-A481-4B87-A480-3D4792A9B276}.Release|Any CPU.Build.0 = Release|Any CPU
{95799318-9A09-46C8-AE53-2546F053EF40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95799318-9A09-46C8-AE53-2546F053EF40}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95799318-9A09-46C8-AE53-2546F053EF40}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95799318-9A09-46C8-AE53-2546F053EF40}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -227,6 +234,7 @@ Global
{9601B939-8314-4BE8-9CDE-217E47A7259C} = {261B1CE2-51CF-4F30-B689-3E78C3916F3E}
{CF1D857F-658F-4E1F-8487-CD751F189E6A} = {6A12E9B8-849A-4421-AEB3-B768E78EDC8A}
{0014C223-A481-4B87-A480-3D4792A9B276} = {261B1CE2-51CF-4F30-B689-3E78C3916F3E}
{95799318-9A09-46C8-AE53-2546F053EF40} = {261B1CE2-51CF-4F30-B689-3E78C3916F3E}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = NFluent.40.Tests\NFluent.40.Tests.csproj
@@ -22,6 +22,7 @@ New feature(s):

--------------
Change(s):
* IEnumerable: improved description within error messages: partial dump around first difference for large sets
* IDictionnary: no longer supported. Hashtable is supported instead
* Numbers: introduce IsStrictlyPositive() as a substitute for IsPositive() which is now obsolete.
* Numbers: introduce IsStrictlyNegative() as a substitute for IsNegative() which is now obsolete.
@@ -34,6 +35,7 @@ Change(s):
* Strings: generate specific error message using IsEqualTo() when the expected string is empty
* Strings: provides part of string where first difference occurs even when strings have different lenghts
* Objects: IsSameReferenceAs supersede IsSameReferenceThan (now flagged as obsolete)
* Objects: Dump hascodes only when NFluent cannot highligth difference.
* Check.That(Action) can no longer be used (error, obsolete)
* Check.That(Func&lt;T&gt;) can no longer be used (error, obsolete)
* Simplify the way you can extend NFluent by adding your own checks. Now, you can call: var checker = ExtensibilityHelper.ExtractChecker(check);
@@ -30,6 +30,12 @@
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\NFluent.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>..\..\NFluent.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -40,6 +46,11 @@
<Link>Properties\Version.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\NFluent.snk">
<Link>NFluent.snk</Link>
</None>
</ItemGroup>
<Import Project="..\NFluent\NFluent.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -697,8 +697,8 @@ private static bool IsAnEnumerableButNotAnEnumerableOfChars<T>(T element)
message = checker.BuildMessage("The {0} does not contain exactly the expected value(s).");
}

message.For(typeof(IEnumerable)).On(checkedValue).WithEnumerableCount(sutCount).And
.ExpectedValues(enumerable).WithEnumerableCount(expectedCount);
message.For(typeof(IEnumerable)).On(checkedValue, index).WithEnumerableCount(sutCount).And
.ExpectedValues(enumerable, index).WithEnumerableCount(expectedCount);

return message.ToString();
}
@@ -64,7 +64,7 @@ internal MessageBlock(FluentMessage message, object test, GenericLabelBlock bloc
{
if (!(test is string) && (test is IEnumerable))
{
this.value = new EnumerationBlock((IEnumerable) test, index);
this.value = new EnumerationBlock((IEnumerable)test, index);
}
else
{
@@ -87,7 +87,6 @@ internal MessageBlock(FluentMessage message, object test, GenericLabelBlock bloc
internal MessageBlock(FluentMessage message, Type type, GenericLabelBlock label)
{
this.value = new InstanceBlock(type);
if (message == null) throw new ArgumentNullException(nameof(message));
this.message = message;
this.block = label;
}
@@ -102,13 +101,7 @@ internal MessageBlock(FluentMessage message, Type type, GenericLabelBlock label)
/// <value>
/// The <see cref="FluentMessage"/> holding that block.
/// </value>
public FluentMessage And
{
get
{
return this.message;
}
}
public FluentMessage And => this.message;

#endregion

@@ -72,13 +72,13 @@ public static string ToStringProperlyFormatted(this object theObject)

if (theObject is char)
{
return string.Format("'{0}'", theObject);
return $"'{theObject}'";
}

var s = theObject as string;
if (s != null)
{
return string.Format(@"""{0}""", TruncateLongString(s));
return $@"""{TruncateLongString(s)}""";
}

if (theObject is DateTime)
@@ -101,10 +101,10 @@ public static string ToStringProperlyFormatted(this object theObject)
return ToStringProperlyFormatted((float)theObject);
}

var ienum = theObject as IEnumerable;
if (ienum != null)
var enumerable = theObject as IEnumerable;
if (enumerable != null)
{
return ienum.ToEnumeratedString();
return enumerable.ToEnumeratedString();
}

var type = theObject as Type;
@@ -116,7 +116,7 @@ public static string ToStringProperlyFormatted(this object theObject)
var exc = theObject as Exception;
if (exc != null)
{
return string.Format("{{{0}}}: '{1}'", exc.GetType().FullName, exc.Message);
return $"{{{exc.GetType().FullName}}}: '{exc.Message}'";
}

var result = theObject.ToString();
@@ -212,7 +212,7 @@ private static string ToStringProperlyFormatted(this DateTime theDateTime)
private static string ToStringProperlyFormatted(this bool theBoolean)
{
// Ensure that boolean values are not localized
#if !(PORTABLE) && !(NETSTANDARD1_3)
#if !PORTABLE && !NETSTANDARD1_3
return theBoolean.ToString(CultureInfo.InvariantCulture);
#else
return theBoolean.ToString();
@@ -227,7 +227,7 @@ private static string ToStringProperlyFormatted(this bool theBoolean)
private static string ToStringProperlyFormatted(this double value)
{
// Ensure that boolean values are not localized
#if !(PORTABLE)
#if !PORTABLE
return value.ToString(CultureInfo.InvariantCulture);
#else
return value.ToString();
@@ -242,7 +242,7 @@ private static string ToStringProperlyFormatted(this double value)
private static string ToStringProperlyFormatted(this float value)
{
// Ensure that boolean values are not localized
#if !(PORTABLE)
#if !PORTABLE
return value.ToString(CultureInfo.InvariantCulture);
#else
return value.ToString();
@@ -300,11 +300,11 @@ public static bool ImplementsEquals(this Type type)
}

/// <summary>
/// Gets the base type of the given type
/// Gets the base type of the given type.
/// </summary>
/// <param name="type">Type</param>
/// <returns>The Base Type</returns>
/// <remarks>Simplify port to .Net Core</remarks>
/// <param name="type">Type to be analyzed.</param>
/// <returns>The Base Type.</returns>
/// <remarks>Simplify port to .Net Core.</remarks>
public static Type GetBaseType(this Type type)
{
#if NETSTANDARD1_3
@@ -313,6 +313,7 @@ public static Type GetBaseType(this Type type)
return type.BaseType;
#endif
}

/// <summary>
/// Doubles the curly braces in the string.
/// </summary>
@@ -66,7 +66,10 @@ internal static class EqualityHelper
mode = EqualityMode.OperatorEq;
}
if (checker.Negated)
{
negated = !negated;
}

if (negated == FluentEquals(checker.Value, expected, mode))
{
throw new FluentCheckException(BuildErrorMessage(checker, expected, negated, userOperator));
@@ -178,7 +181,7 @@ public static void FillEqualityErrorMessage(FluentMessage msg, object instance,

// shall we display the hash too
var withHash = instance != null && expected != null && instance.GetType() == expected.GetType()
&& instance.ToString() == expected.ToString();
&& instance.ToStringProperlyFormatted() == expected.ToStringProperlyFormatted();

msg.On(instance)
.WithType(withType)
@@ -224,20 +224,20 @@ public void FillMessage(FluentMessage message, DifferenceMode summary)
var mainText = GetMessage(summary);
var actual = this.Actual;
var expected = this.Expected;
if (summary == DifferenceMode.Spaces)
switch (this.Kind)
{
actual = HighlightTabsIfAny(actual);
expected = HighlightTabsIfAny(expected);
}
else if (summary == DifferenceMode.EndOfLine)
{
actual = HighlightFirstCrlfOrLfIfAny(actual);
expected = HighlightFirstCrlfOrLfIfAny(expected);
}
else
{
actual = actual?.TrimEnd('\r');
expected = expected?.TrimEnd('\r');
case DifferenceMode.Spaces:
actual = HighlightTabsIfAny(actual);
expected = HighlightTabsIfAny(expected);
break;
case DifferenceMode.EndOfLine:
actual = HighlightFirstCrlfOrLfIfAny(actual);
expected = HighlightFirstCrlfOrLfIfAny(expected);
break;
default:
actual = actual?.TrimEnd('\r');
expected = expected?.TrimEnd('\r');
break;
}

const int ExtractLength = 20;
@@ -218,12 +218,19 @@ public MessageBlock ExpectedType(Type expectedType)
/// <summary>
/// Adds a message block to describe the expected values.
/// </summary>
/// <param name="expectedValues">The expected values.</param>
/// <returns>The created MessageBlock.</returns>
public MessageBlock ExpectedValues(object expectedValues)
/// <param name="expectedValues">
/// The expected values.
/// </param>
/// <param name="index">
/// The index to highlight.
/// </param>
/// <returns>
/// The created MessageBlock.
/// </returns>
public MessageBlock ExpectedValues(object expectedValues, int index = 0)
{
this.expectedLabel = GenericLabelBlock.BuildExpectedBlock(new EntityNamer { EntityName = "value(s)" });
this.expectedBlock = new MessageBlock(this, expectedValues, this.expectedLabel);
this.expectedBlock = new MessageBlock(this, expectedValues, this.expectedLabel, index);
this.referenceType = this.referenceType ?? expectedValues.GetTypeWithoutThrowingException();
return this.expectedBlock;
}
@@ -25,20 +25,12 @@ internal class GenericLabelBlock
/// </summary>
/// <param name="adjective">The adjective.</param>
/// <param name="namer">The entity naming logic.</param>
private GenericLabelBlock(string adjective, EntityNamer namer)
internal GenericLabelBlock(string adjective, EntityNamer namer)
{
this.adjective = adjective;
this.EntityLogic = namer;
}

/// <summary>
/// Initializes a new instance of the <see cref="GenericLabelBlock"/> class.
/// </summary>
public GenericLabelBlock()
{
this.adjective = string.Empty;
}

/// <summary>
/// Gets or sets the entity logic.
/// </summary>
@@ -47,11 +39,6 @@ public GenericLabelBlock()
/// </value>
private EntityNamer EntityLogic { get; set; }

public static GenericLabelBlock BuildActualBlock(EntityNamer namer)
{
return new GenericLabelBlock("actual", namer);
}

public static GenericLabelBlock BuildCheckedBlock(EntityNamer namer)
{
return new GenericLabelBlock("checked", namer);
@@ -75,7 +62,7 @@ public static GenericLabelBlock BuildGivenBlock(EntityNamer namer)
/// </returns>
public override string ToString()
{
return string.Format("{0} {1}", this.Adjective(), this.EntityName());
return $"{this.Adjective()} {this.EntityName()}";
}

/// <summary>
@@ -3,5 +3,5 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("NFluent.40.Internals.Tests")]
[assembly: AssemblyTitle("NFluent.Internals.Tests")]

0 comments on commit afefc30

Please sign in to comment.