Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Build/_build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Nuke.Common" Version="8.1.4" />
<PackageReference Include="Nuke.Common" Version="9.0.4" />
<PackageReference Include="System.Formats.Asn1" Version="8.0.1" />
<PackageDownload Include="GitVersion.Tool" Version="[5.12.0]" />
<PackageDownload Include="ReportGenerator" Version="[5.1.23]" />
Expand Down
5 changes: 4 additions & 1 deletion Build/_build.csproj.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -24,4 +26,5 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
3 changes: 3 additions & 0 deletions FluentAssertions.Json.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FCONSTANT/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCONSTRUCTOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
Expand Down Expand Up @@ -67,6 +69,7 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/Environment/UnitTesting/MsTestProvider/RunConfigurationFilename/@EntryValue">D:\Workspaces\FluentAssertions\Default.testsettings</s:String>
<s:Int64 x:Key="/Default/Environment/UnitTesting/ParallelProcessesCount/@EntryValue">4</s:Int64>
<s:Boolean x:Key="/Default/Environment/UnitTesting/ShadowCopy/@EntryValue">False</s:Boolean>
Expand Down
14 changes: 7 additions & 7 deletions Src/FluentAssertions.Json/FluentAssertions.Json.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageIcon>FluentAssertions.png</PackageIcon>
<PackageReleaseNotes>See https://github.com/fluentassertions/fluentassertions.json/releases/</PackageReleaseNotes>
<Copyright>Copyright Dennis Doomen 2010-2021</Copyright>
<Copyright>Copyright 2024-$([System.DateTime]::Now.ToString(yyyy)) Xceed Software Inc., all rights reserved</Copyright>
<LangVersion>9.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net47|AnyCPU'">
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.0.0" />
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="FluentAssertions" Version="8.0.0" />
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<None Include="..\FluentAssertions.png" Pack="true" Visible="false" PackagePath="" />
</ItemGroup>
Expand All @@ -46,19 +46,19 @@
<AdditionalFiles Include="BannedSymbols.txt" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3">
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.1">
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.406">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="CSharpGuidelinesAnalyzer" Version="3.6.0">
<PackageReference Include="CSharpGuidelinesAnalyzer" Version="3.8.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
29 changes: 16 additions & 13 deletions Src/FluentAssertions.Json/JTokenAssertions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ static JTokenAssertions()
/// Initializes a new instance of the <see cref="JTokenAssertions" /> class.
/// </summary>
/// <param name="subject">The subject</param>
public JTokenAssertions(JToken subject)
: base(subject)
/// <param name="orCreate"></param>
public JTokenAssertions(JToken subject, AssertionChain assertionChain)
: base(subject, assertionChain)
{
EnumerableSubject = new GenericCollectionAssertions<JToken>(subject);
EnumerableSubject = new GenericCollectionAssertions<JToken>(subject, assertionChain);
}

/// <summary>
Expand Down Expand Up @@ -126,7 +127,7 @@ private AndConstraint<JTokenAssertions> BeEquivalentTo(JToken expected, bool ign
$"{Format(expected, true).EscapePlaceholders()}{Environment.NewLine}" +
"{reason}.";

Execute.Assertion
CurrentAssertionChain
.ForCondition(difference == null)
.BecauseOf(because, becauseArgs)
.FailWith(message);
Expand Down Expand Up @@ -180,7 +181,7 @@ public AndConstraint<JTokenAssertions> NotBeEquivalentTo(string unexpected, stri
/// </param>
public AndConstraint<JTokenAssertions> NotBeEquivalentTo(JToken unexpected, string because = "", params object[] becauseArgs)
{
Execute.Assertion
CurrentAssertionChain
.ForCondition((Subject is null && unexpected is not null) ||
!JToken.DeepEquals(Subject, unexpected))
.BecauseOf(because, becauseArgs)
Expand Down Expand Up @@ -211,12 +212,12 @@ public AndConstraint<JTokenAssertions> HaveValue(string expected)
/// </param>
public AndConstraint<JTokenAssertions> HaveValue(string expected, string because, params object[] becauseArgs)
{
Execute.Assertion
CurrentAssertionChain
.ForCondition(Subject is not null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected JSON token to have value {0}, but the element was <null>.", expected);

Execute.Assertion
CurrentAssertionChain
.ForCondition(Subject.Value<string>() == expected)
.BecauseOf(because, becauseArgs)
.FailWith("Expected JSON property {0} to have value {1}{reason}, but found {2}.",
Expand All @@ -238,12 +239,12 @@ public AndConstraint<JTokenAssertions> HaveValue(string expected, string because
/// </param>
public AndConstraint<JTokenAssertions> NotHaveValue(string unexpected, string because = "", params object[] becauseArgs)
{
Execute.Assertion
CurrentAssertionChain
.ForCondition(Subject is not null)
.BecauseOf(because, becauseArgs)
.FailWith("Did not expect the JSON property to have value {0}, but the token was <null>.", unexpected);

Execute.Assertion
CurrentAssertionChain
.ForCondition(Subject.Value<string>() != unexpected)
.BecauseOf(because, becauseArgs)
.FailWith("Did not expect JSON property {0} to have value {1}{reason}.",
Expand Down Expand Up @@ -279,7 +280,7 @@ public AndConstraint<JTokenAssertions> MatchRegex(string regularExpression, stri
throw new ArgumentNullException(nameof(regularExpression), "MatchRegex does not support <null> pattern");
}

Execute.Assertion
CurrentAssertionChain
.ForCondition(Regex.IsMatch(Subject.Value<string>(), regularExpression))
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context:JSON property} {0} to match regex pattern {1}{reason}, but found {2}.",
Expand All @@ -306,7 +307,7 @@ public AndConstraint<JTokenAssertions> NotMatchRegex(string regularExpression, s
throw new ArgumentNullException(nameof(regularExpression), "MatchRegex does not support <null> pattern");
}

Execute.Assertion
CurrentAssertionChain
.ForCondition(!Regex.IsMatch(Subject.Value<string>(), regularExpression))
.BecauseOf(because, becauseArgs)
.FailWith("Did not expect {context:JSON property} {0} to match regex pattern {1}{reason}.",
Expand Down Expand Up @@ -341,7 +342,8 @@ public AndWhichConstraint<JTokenAssertions, JToken> HaveElement(string expected,
params object[] becauseArgs)
{
JToken jToken = Subject[expected];
Execute.Assertion

CurrentAssertionChain
.ForCondition(jToken != null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected JSON document {0} to have element \"" + expected.EscapePlaceholders() + "\"{reason}" +
Expand All @@ -366,7 +368,8 @@ public AndWhichConstraint<JTokenAssertions, JToken> NotHaveElement(string unexpe
params object[] becauseArgs)
{
JToken jToken = Subject[unexpected];
Execute.Assertion

CurrentAssertionChain
.ForCondition(jToken == null)
.BecauseOf(because, becauseArgs)
.FailWith("Did not expect JSON document {0} to have element \"" + unexpected.EscapePlaceholders() + "\"{reason}.", Subject);
Expand Down
7 changes: 4 additions & 3 deletions Src/FluentAssertions.Json/JsonAssertionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using FluentAssertions.Execution;
using JetBrains.Annotations;
using Newtonsoft.Json.Linq;

Expand All @@ -16,7 +17,7 @@ public static class JsonAssertionExtensions
[Pure]
public static JTokenAssertions Should(this JToken jToken)
{
return new JTokenAssertions(jToken);
return new JTokenAssertions(jToken, AssertionChain.GetOrCreate());
}

/// <summary>
Expand All @@ -25,7 +26,7 @@ public static JTokenAssertions Should(this JToken jToken)
[Pure]
public static JTokenAssertions Should(this JObject jObject)
{
return new JTokenAssertions(jObject);
return new JTokenAssertions(jObject, AssertionChain.GetOrCreate());
}

/// <summary>
Expand All @@ -34,7 +35,7 @@ public static JTokenAssertions Should(this JObject jObject)
[Pure]
public static JTokenAssertions Should(this JValue jValue)
{
return new JTokenAssertions(jValue);
return new JTokenAssertions(jValue, AssertionChain.GetOrCreate());
}
}
}
4 changes: 2 additions & 2 deletions Src/FluentAssertions.Json/JsonAssertionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace FluentAssertions.Json
/// <summary>
/// Represents the run-time type-specific behavior of a JSON structural equivalency assertion. It is the equivalent of <see cref="FluentAssertions.Equivalency.EquivalencyAssertionOptions{T}"/>
/// </summary>
public sealed class JsonAssertionOptions<T> : EquivalencyAssertionOptions<T>, IJsonAssertionOptions<T>
public sealed class JsonAssertionOptions<T> : EquivalencyOptions<T>, IJsonAssertionOptions<T>
{
public JsonAssertionOptions(EquivalencyAssertionOptions<T> equivalencyAssertionOptions) : base(equivalencyAssertionOptions)
public JsonAssertionOptions(EquivalencyOptions<T> equivalencyAssertionOptions) : base(equivalencyAssertionOptions)
{

}
Expand Down
12 changes: 6 additions & 6 deletions Src/FluentAssertions.Json/ObjectAssertionsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,22 @@ public static AndConstraint<ObjectAssertions> BeJsonSerializable<T>(this ObjectA
/// Zero or more objects to format using the placeholders in <see cref="because" />.
/// </param>
[CustomAssertion]
public static AndConstraint<ObjectAssertions> BeJsonSerializable<T>(this ObjectAssertions assertions, Func<EquivalencyAssertionOptions<T>, EquivalencyAssertionOptions<T>> options, string because = "", params object[] becauseArgs)
public static AndConstraint<ObjectAssertions> BeJsonSerializable<T>(this ObjectAssertions assertions, Func<EquivalencyOptions<T>, EquivalencyOptions<T>> options, string because = "", params object[] becauseArgs)
{
Execute.Assertion.ForCondition(assertions.Subject != null)
assertions.CurrentAssertionChain.ForCondition(assertions.Subject != null)
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context:object} to be JSON serializable{reason}, but the value is null. Please provide a value for the assertion.");

Execute.Assertion.ForCondition(assertions.Subject is T)
assertions.CurrentAssertionChain.ForCondition(assertions.Subject is T)
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context:object} to be JSON serializable{reason}, but {context:object} is not assignable to {0}", typeof(T));

try
{
var deserializedObject = CreateCloneUsingJsonSerializer(assertions.Subject);

var defaultOptions = AssertionOptions.CloneDefaults<T>()
.RespectingRuntimeTypes()
var defaultOptions = AssertionConfiguration.Current.Equivalency.CloneDefaults<T>()
.PreferringRuntimeMemberTypes()
.IncludingFields()
.IncludingProperties();

Expand All @@ -87,7 +87,7 @@ public static AndConstraint<ObjectAssertions> BeJsonSerializable<T>(this ObjectA
catch (Exception exc)
#pragma warning restore CA1031 // Ignore catching general exception
{
Execute.Assertion
assertions.CurrentAssertionChain
.BecauseOf(because, becauseArgs)
.FailWith("Expected {context:object} to be JSON serializable{reason}, but serializing {0} failed with {1}", assertions.Subject, exc);
}
Expand Down
Loading